How To Use Selenium Grid To Run Selenium Tests In Multiple Nodes

In this article, we will show you a selenium grid multiple nodes example. It will run the Selenium WebDriver Tests using 2 different Nodes in a Selenium Grid. One node runs the test using Google Chrome and the other node runs the test using Firefox.

1.Setup Selenium Grid with one Hub and two Nodes.

  1. Download the Selenium Server (Grid) ( a jar file like selenium-server-standalone-3.141.59.jar ) from the link https://www.selenium.dev/downloads/.
  2. Save the downloaded jar file to a local folder such as /Users/songzhao/Documents/WorkSpace/Tools/selenium-server-standalone-3.141.59.jar.
  3. Open a terminal and run the command $ java -jar /.../selenium-server-standalone-3.141.59.jar -role hub -port 8888 to set up the Selenium Grid Hub like below. The Selenium Grid hub listens on port 8888.
    $ java -jar /Users/songzhao/Documents/WorkSpace/Tools/selenium-server-standalone-3.141.59.jar -role hub -port 8888
    21:13:28.823 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
    21:13:28.999 INFO [GridLauncherV3.lambda$buildLaunchers$5] - Launching Selenium Grid hub on port 8888
    2021-05-10 21:13:29.615:INFO::main: Logging initialized @1438ms to org.seleniumhq.jetty9.util.log.StdErrLog
    21:13:29.977 INFO [Hub.start] - Selenium Grid hub is up and running
    21:13:29.981 INFO [Hub.start] - Nodes should register to http://192.168.31.31:8888/grid/register/
    21:13:29.981 INFO [Hub.start] - Clients should connect to http://192.168.31.31:8888/wd/hub
    
  4. Open another terminal and run the command $ java -jar /.../selenium-server-standalone-2.53.0.jar -role node -hub http://localhost:8888/grid/register to set up the first Node ( N1 ) and register it to the Hub just created.  The first Selenium Grid node is located on localhost also.

    $ java -jar /Users/songzhao/Documents/WorkSpace/Tools/selenium-server-standalone-3.141.59.jar -role node -hub http://localhost:8888/grid/register
    
    07:16:15.101 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
    07:16:15.300 INFO [GridLauncherV3.lambda$buildLaunchers$7] - Launching a Selenium Grid node on port 36824
    2021-05-11 07:16:15.478:INFO::main: Logging initialized @685ms to org.seleniumhq.jetty9.util.log.StdErrLog
    07:16:15.934 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
    07:16:16.097 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 36824
    07:16:16.097 INFO [GridLauncherV3.lambda$buildLaunchers$7] - Selenium Grid node is up and ready to register to the hub
    07:16:16.188 INFO [SelfRegisteringRemote$1.run] - Starting auto registration thread. Will try to register every 5000 ms.
    07:16:16.846 INFO [SelfRegisteringRemote.registerToHub] - Registering the node to the hub: http://localhost:8888/grid/register
    07:16:16.924 INFO [SelfRegisteringRemote.registerToHub] - The node is registered to the hub and ready to use
    
  5. Setup the second Selenium Grid Node ( N2 ) and register it to the Hub just created also. The second node is located in localhost also. N2 will listen on port 6666, and can execute google chrome for selenium  testing only.
  6. But when you run below command to set up the Node 2, it will throws an error.

    java -jar /Users/songzhao/Documents/WorkSpace/Tools/selenium-server-standalone-3.141.59.jar -role node -hub http://localhost:8888/grid/register -port 6666 -Dwebdriver.chrome.driver=/Users/songzhao/Documents/WorkSpace/Tools/chromedriver -browser browserName=chrome, maxInstances=5, platform=VISTA
  7. The error message is  Exception in thread “main” com.beust.jcommander.ParameterException: Was passed main parameter ‘-Dwebdriver.chrome.driver=/…/chromedriver -browser’ but no main parameter was defined in your arg class.

    $ java -jar /Users/songzhao/Documents/WorkSpace/Tools/selenium-server-standalone-3.141.59.jar -role node -hub http://localhost:8888/grid/register -port 6666 -Dwebdriver.chrome.driver= /Users/songzhao/Documents/WorkSpace/Tools/chromedriver -browser browserName=chrome, maxInstances=5, platform=VISTA
    Exception in thread "main" com.beust.jcommander.ParameterException: Was passed main parameter '-Dwebdriver.chrome.driver=' but no main parameter was defined in your arg class
        at com.beust.jcommander.JCommander.initMainParameterValue(JCommander.java:936)
        at com.beust.jcommander.JCommander.parseValues(JCommander.java:752)
        at com.beust.jcommander.JCommander.parse(JCommander.java:340)
        at com.beust.jcommander.JCommander.parse(JCommander.java:319)
        at org.openqa.grid.selenium.GridLauncherV3.parse(GridLauncherV3.java:218)
        at org.openqa.grid.selenium.GridLauncherV3.lambda$buildLaunchers$7(GridLauncherV3.java:271)
        at org.openqa.grid.selenium.GridLauncherV3.lambda$launch$0(GridLauncherV3.java:86)
        at java.base/java.util.Optional.map(Optional.java:260)
        at org.openqa.grid.selenium.GridLauncherV3.launch(GridLauncherV3.java:86)
        at org.openqa.grid.selenium.GridLauncherV3.main(GridLauncherV3.java:70)
  8. To solve the above error, you should create a JSON file node2Config.json, and add the below configuration JSON content in it. From the JSON configuration data, we can see it only supports google chrome for selenium testing.
    {
      "capabilities":
      [
        {
          "browserName": "firefox",
          "marionette": true,
          "maxInstances": 5,
          "seleniumProtocol": "WebDriver",
          "webdriver.gecko.driver": "/Users/songzhao/Documents/WorkSpace/Tools/geckodriver"
        },
        {
          "browserName": "chrome",
          "maxInstances": 5,
          "seleniumProtocol": "WebDriver",
          "webdriver.chrome.driver": "/Users/songzhao/Documents/WorkSpace/Tools/chromedriver"
        },
        {
          "browserName": "internet explorer",
          "platform": "WINDOWS",
          "maxInstances": 1,
          "seleniumProtocol": "WebDriver"
        },
        {
          "browserName": "safari",
          "technologyPreview": false,
          "platform": "MAC",
          "maxInstances": 1,
          "seleniumProtocol": "WebDriver"
        }
      ],
      "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
      "maxSession": 5,
      "port": -1,
      "register": true,
      "registerCycle": 5000,
      "hub": "http://localhost:8888",
      "nodeStatusCheckTimeout": 5000,
      "nodePolling": 5000,
      "role": "node",
      "unregisterIfStillDownAfter": 60000,
      "downPollingLimit": 2,
      "debug": false,
      "servlets" : [],
      "withoutServlets": [],
      "custom": {}
    }
    
  9. Now run the command java -Dwebdriver.chrome.driver=/.../chromedriver.exe -jar /.../selenium-server-standalone.jar -role node -nodeConfig /.../node1Config.json in another terminal to start up the Selenium Grid Node 2 and register it to the Selenium Grid Hub like below.
  10. Please be careful with the path or name of the node configuration JSON file, otherwise, you may encounter the below error.
    $ java -Dwebdriver.chrome.driver=/Users/songzhao/Documents/WorkSpace/Tools/chromedriver -jar /Users/songzhao/Documents/WorkSpace/Tools/selenium-server-standalone-3.141.59.jar -role node -nodeConfig /Users/songzhao/Documents/WorkSpace/Tools/node1Config.json
    Exception in thread "main" com.beust.jcommander.ParameterException: /Users/songzhao/Documents/WorkSpace/Tools/node1Config.json is not a valid file.
        at org.openqa.grid.internal.cli.FileExistsValueValidator.validate(FileExistsValueValidator.java:30)
        at com.beust.jcommander.ParameterDescription.validateValueParameter(ParameterDescription.java:353)
        at com.beust.jcommander.ParameterDescription.validateValueParameter(ParameterDescription.java:342)
        at com.beust.jcommander.ParameterDescription.addValue(ParameterDescription.java:240)
        at com.beust.jcommander.JCommander.processFixedArity(JCommander.java:895)
        at com.beust.jcommander.JCommander.processFixedArity(JCommander.java:870)
        at com.beust.jcommander.JCommander.parseValues(JCommander.java:721)
        at com.beust.jcommander.JCommander.parse(JCommander.java:340)
        at com.beust.jcommander.JCommander.parse(JCommander.java:319)
        at org.openqa.grid.selenium.GridLauncherV3.parse(GridLauncherV3.java:218)
        at org.openqa.grid.selenium.GridLauncherV3.lambda$buildLaunchers$7(GridLauncherV3.java:271)
        at org.openqa.grid.selenium.GridLauncherV3.lambda$launch$0(GridLauncherV3.java:86)
        at java.base/java.util.Optional.map(Optional.java:260)
        at org.openqa.grid.selenium.GridLauncherV3.launch(GridLauncherV3.java:86)
        at org.openqa.grid.selenium.GridLauncherV3.main(GridLauncherV3.java:70)
    
  11. Now you can start the second Selenium Grid Node successfully with the below command.
    $ java -Dwebdriver.chrome.driver=/Users/songzhao/Documents/WorkSpace/Tools/chromedriver -jar /Users/songzhao/Documents/WorkSpace/Tools/selenium-server-standalone-3.141.59.jar -role node -nodeConfig /Users/songzhao/Documents/WorkSpace/Tools/node2Config.json
    08:45:42.108 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
    08:45:42.326 INFO [GridLauncherV3.lambda$buildLaunchers$7] - Launching a Selenium Grid node on port 17649
    2021-05-11 08:45:42.478:INFO::main: Logging initialized @636ms to org.seleniumhq.jetty9.util.log.StdErrLog
    08:45:42.792 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
    08:45:42.902 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 17649
    08:45:42.903 INFO [GridLauncherV3.lambda$buildLaunchers$7] - Selenium Grid node is up and ready to register to the hub
    08:45:42.961 INFO [SelfRegisteringRemote$1.run] - Starting auto registration thread. Will try to register every 5000 ms.
    08:45:43.345 INFO [SelfRegisteringRemote.registerToHub] - Registering the node to the hub: http://localhost:8888/grid/register
    08:45:43.363 INFO [SelfRegisteringRemote.registerToHub] - The node is registered to the hub and ready to use
    
    
  12. After running the above command line, you can see the following log info in Selenium Grid Hub Console output. That means the 2 nodes’ registration is completed successfully.

    09:01:13.644 INFO [DefaultGridRegistry.add] - Registered a node http://192.168.31.31:19326
    09:01:20.551 INFO [DefaultGridRegistry.add] - Registered a node http://192.168.31.31:26317
  13. Open a web browser and browse the URL http://localhost:8888/grid/console, you can see the two Nodes in the Selenium Grid web console.

2. Write Java Code to Execute Selenium Testing Scripts On Selenium Grid Multiple Nodes

  1. To connect to the Selenium Grid Hub you should create a RemoteWebDriver object with the Hub URL.
    private static String hubUrl = "http://localhost:8888/wd/hub";
    
    RemoteWebDriver remoteWebDriver = new RemoteWebDriver(new URL(hubUrl), dc);
    
  2. Create a java class TestRuneTestingOnMultipleNodes in your maven project.
  3. The class contains two methods testFirefoxWithNode1() and testChromeWithNode2().
  4. Below is the detailed source code. When you run the example code, you can see the log data in the Selenium Grid Hub console.
    package com.dev2qa.webdriver.grid;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.openqa.selenium.remote.RemoteWebDriver;
    
    public class TestRuneTestingOnMultipleNodes {
        
        /* This is the Hub server connect url in the selenium grid. */
        private static String hubUrl = "http://localhost:8888/wd/hub";
        
    
        /* This method is used to test Firefox on Node1. */
        public void testFirefoxWithNode1()
        {
            System.out.println("Start Testing Firefox on Node1. ");
            this.testUtil(hubUrl, "http://yahoo.com", "Firefox");
            System.out.println("Stop Testing Firefox on Node1. ");
        }
        
    
        /* This method is used to test Google Chrome on Node2. */
        public void testChromeWithNode2()
        {
            System.out.println("Start Testing Google Chrome on Node2. ");
            this.testUtil(hubUrl, "http://bing.com", "Chrome");
            System.out.println("Stop Testing Google Chrome on Node2. ");
    
        }
        
        
        private void testUtil(String hubUrl, String testUrl, String testBrowser)
        {
            /* This is the remote webdriver object used to interact with remote web browser.*/
            RemoteWebDriver remoteWebDriver = null;
            
            /* dc include desired test web browser's information.*/
            DesiredCapabilities dc = null;
            try {
                
                if("Firefox".equalsIgnoreCase(testBrowser))
                {
                    System.out.println("Create Firefox DesiredCapabilities object.");
                    /* If user want to test Firefox. */
                    dc = DesiredCapabilities.firefox();
                }else if("Chrome".equalsIgnoreCase(testBrowser))
                {
                    System.out.println("Create Google Chrome DesiredCapabilities object.");
                    /* If user want to test google Chrome. */
                    dc = DesiredCapabilities.chrome();
                }else
                {
                    System.out.println("Create InternetExplorer DesiredCapabilities object by default.");
                    /* We default test Internet Explorer web browser. */
                    dc = DesiredCapabilities.internetExplorer();
                }
                
                System.out.println("Create remote webdriver object to connect to grid Hub server : " + hubUrl);
                /* Create the remote webdriver object to send command to selenium grid Hub server. 
                 * And transfer user desired test web browser to Hub server, then Hub will choose 
                 * one related Node which can run the web browser desired to run the test.
                 * */
                remoteWebDriver = new RemoteWebDriver(new URL(hubUrl), dc);
                
                System.out.println("Maxmize the web browser window");
                /* Maximize the web browser window on the selected Node. */
                remoteWebDriver.manage().window().maximize();
                
                System.out.println("Browse web page " + testUrl);
                /* Browse the test Url in related Node. */
                remoteWebDriver.navigate().to(testUrl);
                
                System.out.println("Wait 10 seconds.");
                Thread.sleep(10000);
            } catch (MalformedURLException ex) {
                /* If Hub url is not formated correctly. */
                ex.printStackTrace();
            } catch (InterruptedException ex) {
                /* If current thread interrupted. */
                ex.printStackTrace();
            }finally
            {
                if(remoteWebDriver!=null)
                {
                    /* Quit and close the web browser on the related Node. */
                    remoteWebDriver.quit();
                }
            }
        }
    
        public static void main(String[] args) {
            
            TestRuneTestingOnMultipleNodes obj = new TestRuneTestingOnMultipleNodes();
            
            obj.testFirefoxWithNode1();
            
            obj.testChromeWithNode2();
    
        }
    
    }
    

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.