Selenium grid - Run tests across platforms/browsers

Selenium Grid is used to run the selenium tests parallely accross different platforms(Nodes) and browsers from one system (Hub)....

Steps for setting up the selenium grid:
1st thing 1st:


Download the selenium standalone jar file from here,
[see below screenshot] version may be different


Place the jar file in your lcoal drive, let's say under C:\Grid

For ease of access, place the below bat files under C:\Grid

HUB configuration:


Paste the below commands in a note pad and save it as (say hub.bat)

title hub
cd c:\Grid
java -jar selenium-server-standalone-2.45.0.jar -port 4444 -role hub 
-nodeTimeout 600 

Run the hub.bat file to start the hub, keep it up and running on cmd,
to check if it's up, open any browser and type:
http://localhost:4444/grid/console or http://:4444/grid/console

NODE configuration:

Paste the below commands in a note pad and save it as (say node1.bat)

title node1
cd C:\Grid
java -jar selenium-server-standalone-2.45.0.jar -role webdriver/node -hub 
http://<hubipadd>:4444/grid/register -port 5566/anyfreeport 
-Dwebdriver.chrome.driver="./chromedriver.exe"
-browser browserName="chrome",version=any, platform=WINDOWS,maxinstances=2 
-hubhost <hubipadd>-host <nodeipadd> -maxSession 5

After running the above node1.bat file, refresh the opened url (http://localhost:4444/grid/console), and see it displays the node configuration.
--------------------------------------------------------------------------------------------------
Let's understand the above command:
every word starts with "-" is a key, and value follows after
so,
-jar is  selenium-server-standalone-2.45.0.jar
-role as node
-hub as http:\\&lthubIPAdd&gt:4444/grid/register   we are registering node with the hub
-port any available free port of node
-Dwebdriver.chrome.driver = "c:\Grid\chromedriver.exe" if want to run on chrome browser
same way, we can have  -Dwebdriver.ie.driver "c:\Grid\IEDriverServer.exe"
-browser as browserName= any or browsername like chrome / firefox
                    version = proper browser version
platform = what kind of operating system

There are 2 more keys we can use: 

maxinstances and maxSession

Maxinstances determines how many instances of browser(of same version) can be run on the node machines.
e.g - 
-browser browserName=firefox,version=34,maxInstances=3,platform=WINDOWS
-browser browserName=iexplorer,version=9.0,maxInstances=2,platform=LINUX
 in above, we can run 3 instances of FF34 and 2 instances of IE9 on node machines.
MaxSession determines how many browsers(irespective of type and version) can run on node machines.
e.g: in the above example if I mention, maxSession=2, this will override the maxinstances as we can only run 2 browsers(either 2FF / 2IE / 1FF and 1IE) parallely on node machines.
if nothing specified for maxinstances and maxSession, it defaults to 1.
-------------------------------------------------------------------------------------------------------

We have to create and run the bat files (node1, node2..etc) and place in each node machine where we want to run our selenium tests.

Either we can write the details of browser, platform of the respective node in the bat file.
or
we can specify the details in a file (format:*.json)

Let's have a look at some practical implementation of the selenium grid:

Scenario-1: 

Run tests on multiple browsers parallel in one machine using grid.
                                    (Single machine as both hub and node)
                   So we need to run 1st hub.bat and then node.bat file in the same machine
                                    (copy bat file contents as mentioned in above sections)

then, the code would be something like below - here we are only looking for the ways to run tests in different platform and browser, doesn't matter what the test does

package hubnode;

import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class Grid {
 static WebDriver driver = null;
 
 @Parameters({"browser"})
 @Test
 public static void openGoogle(String browser) throws MalformedURLException, InterruptedException
 {
  DesiredCapabilities cap = new DesiredCapabilities();
  switch (browser)
  {
   case "firefox":
        cap = DesiredCapabilities.firefox();
        break;
   case "ie":
        cap = DesiredCapabilities.internetExplorer();
        break;
   case "chrome":
        cap = DesiredCapabilities.chrome();
        break;
   default:
        cap = DesiredCapabilities.firefox();
        break;
  }
  cap.setPlatform(Platform.WINDOWS);
  driver = new RemoteWebDriver(new URL("http://10.112.76.224:4444/wd/hub"), cap);
  //if want to run tests on same machine, which is HUB
  driver.get("http://qavalidation.com");
  Thread.sleep(2000);
  driver.close();
 }
}

and the customized testng.xml would be like below: [run the testng.xml]

xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests">
<test name="Test">
      <parameter name="browser" value="firefox" />
      <classes>
          <class name="hubnode.Grid" />
      </classes>
</test>
<test name="Test1">
      <parameter name="browser" value="chrome" />
      <classes>
          <class name="hubnode.Grid" />
      </classes>
</test>
<test name="TestIE">
      <parameter name="browser" value="ie" />
      <classes>
          <class name="hubnode.Grid" />
      </classes>
</test>
</suite>

You will observe, the test will run in all the 3 browsers(FF, IE and Chrome) on same machine.

Scenario-2: 

Run tests in 2 or more different node machines and run from hub machine.
hub and node bat file content will be same, this time run the node.bat file from each                             machine where we want to run our tests.

Let's say machine A is hub, then run the hub.bat file
title hub
cd c:\Grid
java -jar selenium-server-standalone-2.45.0.jar -port 4444 -role hub 
-nodeTimeout 600

machine B is node1, then run the node1.bat (browser=chrome)
title node1
cd C:\Grid
java -jar selenium-server-standalone-2.45.0.jar -role node -hub htt
p://:4444/grid/register -port 5551 -Dwebdriver.chrome.
driver="c:\Grid\chromedriver.exe" -browser browserName="chrome", version=any, platform=
WINDOWS,maxinstances=2 -maxSession 5

machine C is node2, then run the node2.bat (browser=firefox)
title node2
cd C:\Grid
java -jar selenium-server-standalone-2.45.0.jar -role node -hub 
http://<HubIPAdd>:4444/grid/register -port 5552 -browser browserName="firefox", 
version=any, platform=WINDOWS -maxinstances=2 -maxSession 5

machine D is node3, then run the node3.bat (browser=ie)
title node3
cd C:\Grid
java -jar selenium-server-standalone-2.45.0.jar -role webdriver -hub htt
p://<HubIPAdd>:4444/grid/register -port 5553 -Dwebdriver.ie.driver=
"c:\Grid\IEDriverServer.exe" -browser browserName="iexplorer", 
version=any, platform=WINDOWS,maxinstances=2 -maxSession 5

and here we need to change a bit of our code implementation and testng.xml file as well
package hubnode;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class Grid {
 static WebDriver driver = null;
 static String br = null;
 @Parameters({"browser", "remoteurl"})
 @Test
 public static void openGoogle(String browser, String remoteurl) throws InterruptedException, IOException
 {
  br=browser.toString();
  DesiredCapabilities cap = new DesiredCapabilities();
  switch (browser)
  {
   case "firefox":
        cap = DesiredCapabilities.firefox();
        break;
   case "ie":
    File file = new File("c:\\Grid\\IEDriverServer.exe");
    System.setProperty("webdriver.ie.driver", file.getAbsolutePath());
        cap = DesiredCapabilities.internetExplorer(); 
        break;
   case "chrome":
     System.setProperty("webdriver.chrome.driver","c:\\Grid\\chromedriver.exe");
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--start-maximized");
    options.addArguments("test-type");
       cap.setCapability(ChromeOptions.CAPABILITY, options);
       cap = DesiredCapabilities.chrome();
        break;
   default:
        cap = DesiredCapabilities.firefox();
        break;
  }
  cap.setPlatform(Platform.WINDOWS);
  
  //Node Machine IP address
  driver = new RemoteWebDriver(new URL(remoteurl+"/wd/hub"), cap);
  
  driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS);
  //driver.manage().window().maximize();
  Thread.sleep(2000);
  driver.navigate().to("http://www.gmail.com");
 }
}
And the testng.xml should be:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Grid" parallel="tests" thread-count="3">
<test name="Test1">
      <parameter name="browser" value="firefox" />
      <parameter name="remoteurl" value="http://10.110.70.32:5551" />
      <classes>
          <class name="hubnode.Grid" />
      </classes>
</test>
<test name="Test2">
      <parameter name="browser" value="chrome" />
      <parameter name="remoteurl" value="http://10.112.40.12:5552" />
      <classes>
          <class name="hubnode.Grid" />
      </classes>
</test>
<test name="Test3">
      <parameter name="browser" value="ie" />
      <parameter name="remoteurl" value="http://10.220.204.105:5553" />
      <classes>
          <class name="hubnode.Grid" />
      </classes>
</test>
</suite>
run the hub.bat file from pc A, then run node1.bat from pc B, node2.bat from pc C, node3.bat from pc D
Run the testng.xml to see tests running.            
capabilities set in code tries to match with the key value pair (from the bat file) and if matches, then corresponding browser opens to run the tests. 

--------------------------------------------------------------------------------------------------------------
We can even pass the browser parameters in a file (as *.json format) instead of writing in the command line Example: node1.json file content would be:
{
  "capabilities":
      [
        {
          "browserName": "chrome",
          "version": "32",
          "platform": "WINDOWS",
          "maxInstances": 2
        },
        {
          "browserName": "iexplorer",
          "version": "8",
          "platform": "WINDOWS",
          "maxInstances": 3
        }
      ],
    "configuration":
        {
        "nodeTimeout":120,
        "port":5555,

        "hubPort":4444,
        "hubHost":"localhost",

        "nodePolling":2000,

        "registerCycle":10000,
        "register":true,
        "cleanUpCycle":2000,
        "timeout":30000,
        "maxSession":5,
        }
}
and the command line statement would be:
title node1
cd c:\grid
java -jar selenium-server-standalone-.jar -role node -hub http://localhost:4444/grid/register 
-nodeConfig node1.json

7 comments: