Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Selenium Grid Setup Tutorial for Cross-Browser Testing

DZone 's Guide to

Selenium Grid Setup Tutorial for Cross-Browser Testing

Learn more about how to implement automated, cross-browser testing with Selenium Grid Setup.

· Performance Zone ·
Free Resource

When performing cross-browser testing manually, one roadblock that you might have hit during the verification phase is testing the functionalities of your web application across different operating systems, devices, and/or browsers with respect to time. With thousands of browsers available in the market, automation testing for validating cross-browser compatibility has become a necessity.

Referring to automation and considering our love for open-source software, it is inevitable to turn a blind eye from one of the most renowned test automation frameworks, Selenium. We have covered automation testing with Selenium WebDriver for cross-browser testing previously on our blog where we discussed different variants of Selenium, i.e IDE, RC, WebDriver, etc. and ran our first automation script.

In that article, we emphasized the limitation of working with Local Selenium WebDriver. With Local Selenium WebDriver, you can perform browser-compatibility testing ‘only’ on the browsers that are installed on the machine (where testing is performed), i.e. your testing effort is limited to only a certain combination (device + operating system + browser).

Verification of your web-application with the ‘local’ version of the Selenium WebDriver is not a scalable approach. Some of the problems that you encounter with this kind of setup are:

  • How to verify functionalities on platforms and operating systems that are not installed on the machine, i.e. even if it is a dual-boot machine, you will still have problems.
  • How do you perform automated cross-browser testing on browsers with different versions? Essentially, your machine can have Firefox version 64.0, but you want to perform the testing on Firefox version 36.0. What do you do?
  • How do you perform cross-browser testing on a website with multiple numbers of browsers? Your machine may not have Opera installed, but for the purpose of testing, you would need to install these browsers, resulting in unnecessary disk space consumption.
  • How to attain the best performance, i.e. parallelization while performing the tests on a local machine?

Though Local Selenium WebDriver is ideal for testing on a smaller scale, the necessary amount of scalability and performance can be achieved after you set up a ‘Selenium Grid.’

This article provides a closer look at Selenium Grid and how web developers and software testers leverage the power of the Selenium Grid setup to perform automated cross-browser testing.

We will be making use of the following languages, frameworks, and tools (IDE) to write better automation code.

  • Programming language – Python (Download Link)
  • Test framework – Pytest
  • Web application framework – Selenium
  • Integrated Development Environment – Eclipse version 4.90 (Download Link), PyCharm – Community Edition (Download Link)

What Is Selenium Grid?

Selenium Grid is a testing tool (which is a part of the Selenium Suite) that is based on the ‘client-server’ architecture. In Selenium Grid terminology, the Client machine is termed as a ‘Hub,’ and server(s) are termed as ‘Nodes.’

Selenium Grid setup allows you to execute cross-browser testing through a variety of different machines across different browsers (as well as different versions of browsers) and different operating systems. Hence, it brings the required amount of parallelism and distribution to your test execution environment.

A Selenium Grid setup can have only one Hub and ‘n’ number of nodes. The primary job of the ‘hub machine’ is to distribute the test case supplied to the ‘node machine,’ which matches the capabilities required for executing cross-browser testing. We will discuss Hub and Node in greate detail (which are the core components for the setup of Selenium Grid infrastructure) in further sections.

There are two versions of Selenium Grid available, namely Selenium Grid 2.0 and Selenium Grid 1.0. Selenium Grid 2.0 is most popular amongst automation testers since it supports Selenium RC (Remote Control) and Selenium WebDriver scripts.

Why Selenium Grid Setup Is a Wise Choice

There are a number of benefits in adopting the Selenium Grid setup. Here, we have a look at some of the top advantages of Selenium Grid setup as a part of your test execution strategy for performing cross-browser testing.

  • Reduced Execution Time – Selenium Grid setup can be used to execute multiple test cases on different browsers (and browser versions) and operating systems. You can also run multiple instances of Selenium RC along with the test configuring combinations. As the tests are executed in ‘parallel’ (scattered across different machines), the overall time consumed for cross-browser testing trims down significantly.
  • Scalable and Maintainable – as we know, Selenium Grid setup reduces the amount of time required for parallel testing — by a huge margin, the entire solution is highly scalable. If you want to perform testing on a new node (which could be the operating system/browser), all it needs are a few minor tweaks in the code with respect to the addition of capabilities, and your solution for the new node is ready.
  • Perform Multi-Combination Testing – Using the Hub and Node feature of Selenium Grid setup, you can perform multi-OS, multi-browser, and multi-device verification of your source code.

By default, the execution after the setup of the Selenium Grid is not parallel in nature. In order to take advantage of parallelism, the Selenium tests should be written in a manner that takes parallel execution for cross-browser testing into account.

Primary Components of the Selenium Grid Setup and Brief Look at RemoteWebDriver Workflow

In our previous articles on Selenium WebDriver for cross-browser testing, the core focus was on ‘Selenium for local testing;’ you would have observed that a local WebDriver API/interface has to be used in order to complete testing. In case you want to use the Selenium WebDriver to execute tests on a separate machine, you have to use Remote WebDriver interface. Since the tests (in normal scenarios) have to be executed on a different machine, RemoteWebDriver is based on the traditional ‘Client-Server’ model. The RemoteWebDriver consists of two main parts – Hub (Server) and Node(Client). Let’s have a detailed look at the same in this section.

Hub/Server – The Hub is the central component of the ‘Selenium Grid architecture.’ It loads the tests that have to be executed. There can only be one ‘Hub,’ which acts as the ‘Master’ in the setup of the Selenium Grid infrastructure. Once the Hub receives an input/test case that needs to be executed, it searches for a Node (client) that matches the desired capabilities and diverts the ‘test execution request’ to the matching node.

For example, if you have set up a Selenium Grid with (hub + two nodes) where the node configuration is as below:

  • Node 1 – Windows 10, Chrome 73.0
  • Node 2 – Windows 10, Firefox 64.0

If there is a test case that has the ‘Desired Capabilities requirement’ (Windows 10 + Chrome), the hub first receives the request for this requirement. By looking at the requirement, it diverts the execution request to Node 1.

Node – a Node is a machine on which the tests are executed. The node can have a different configuration from the hub. There is no limit on the number of nodes that can be connected to the hub. Since the test code execution will occur on the node(s), it is recommended that you choose machines with the best possible configuration so that you can get the best performance out of your Selenium Grid setup.

Simple Representation of the Selenium Grid SetupSelenium-Grid-Representation

Installation and Configuration to Setup a Selenium Grid

Our development environment is installed on Windows 10 machine. For demonstration, Hub and Node are installed on the same machine.

Step 1: In order to set up the Selenium Grid infrastructure, you first need to download the Selenium Server jar from the official website of Selenium. It was formerly called the ‘Selenium RC server.’ The download link can be found here.

Once the selenium server jar file is downloaded, you should configure the hub using the following command (java -jar selenium-server-standalone-x.x.x.jar -role hub):

java -jar selenium-server-standalone-3.9.1.jar -role hub


Step 2: By default, the hub would use the port 4444. The port can be changed by using the configuration option  –port. Below is the screenshot of the logs observed once the above command is executed.
Selenium-Grid-Hub-Screenshot

In order to verify whether the hub is configured correctly, open the browser window and type the following in the address bar:

 http://107.108.86.20:4444/wd/hub 

Below is the output snapshot when the above URL is opened in the Firefox browser:


Step 3: Now that the ‘Hub’ is up and running, you now have to configure the nodes for the purpose of cross-browser testing. Execute the following command on the terminal:

java -jar selenium-server-standalone-3.9.1.jar -role node -hub http://<IP-Address>/grid/register/ -browser "browserName=firefox,maxinstance=1,platform=WINDOWS" –port <port-number>


In our case, the Hub is configured on port number 4444, and the node is configured on port numbers 5555 and 5556. One node is configured for a platform, such as Windows, and a browser, like Firefox. Second, the node is configured for a platform, like Windows, and a browser, such as Chrome.

java -jar selenium-server-standalone-3.9.1.jar -role node  
-hub http://107.108.86.20:4444/grid/register/ 
-browser "browserName=firefox,maxinstance=1,platform=WINDOWS" -port 5555


The output for the command is shown below:

Selenium-Node-Output

For verifying whether the Node has been configured correctly, please enter the following in the address bar.

http://localhost:4444/grid/console?config=true&configDebug=true#

Selenium-Grid-Hub-Output-Screenshot

For configuring the node on port number 5556 (with the Operating System as Windows and the browser as Chrome), please execute the following command on the terminal:

java -jar selenium-server-standalone-3.9.1.jar -role node  
-hub http://107.108.86.20:4444/grid/register/ 
-port 5556 -browser "browserName=chrome,maxinstance=1,platform=WINDOWS"


Now, when you visit http://localhost:4444/grid/console?config=true&configDebug=true# on the address bar, you will also see details about ports 5556 as well.
Selenium-Node-Browser-Output

In case you are planning to use Internet Explorer as the browser, you just need to pass the correct browser name as an input argument to the jar file. Below is the command that you can use for the Internet Explorer browser:

java -jar selenium-server-standalone-3.9.1.jar -role node -hub http://107.108.86.20:4444/grid/register/ -port 5556 -browser "browserName=internet explorer,maxinstance=1,platform=WINDOWS"


There are other parameters apart from the browserName that you might require, if needed:

CONFIGURATION OPTION EXPLANATION
port Configure the port number to which the node will be connected. Configured using –port option.
maxinstance Used to put a restriction on the maximum number of browser initializations in the code. In case you want maximum 3 Firefox instances on the node 5555, you can configure using the option -browser “browserName=firefox,maxinstance=3,platform=WINDOWS” -port 5555
maxSession Configure the number of browser instances that can run in parallel on the node. Requests are automatically queued once the maxSession limit is reached. In order to limit the number of Firefox sessions on port 5555, you can use the following option
-browser “browserName=firefox,maxinstance=1,platform=WINDOWS” -maxSession 3 -port 5555


Using Pytest With Your Selenium Grid Setup

Now that you have knowledge about Selenium Grid, let’s have a look at an example where we use Pytest with our Selenium Grid setup (or the Remote WebDriver interface). We have a detailed article about test automation using Pytest and the Selenium WebDriver interface where we explained more about the installation of Pytest, using Selenium with Pytest, fixtures in Pytest, and more.

For the purpose of this demonstration, Hub (Server) and Nodes (Clients) are configured on the same machine. We will be using the machine IP address when configuring the Remote WebDriver. Let’s configure the Hub and Nodes using the respective commands for automated, cross-browser testing.

Setting Up the Hub for Your Selenium Grid

Please go to the directory where you have the Selenium Server jar file. In our case, we are using the version 3.9.1 and the jar file name is selenium-server-standalone-3.9.1.jar by using the ‘cd’ command. Start the Hub by executing the following command on the terminal:

java -jar selenium-server-standalone-3.9.1.jar -role hub

As discussed before, by default, the Hub would start on port 4444. ‘Nodes’ can connect to the ‘Hub’ using the link http://:/wd/hub. In our case, the Hub/Server is configured on a machine that has IP address ‘107.108.86.20’ and the port on which it is configured is 4444. Hence, nodes need to use the link http://107.108.86.20:4444/wd/hub in order to divert their request to the configured Hub.

Setting Up the Nodes for Your Selenium Grid

Now that the Hub is configured, the next step to set up the Selenium Grid is the Nodes. We will configure two nodes that have the following requirements.

  • Node 1 – Port 5555, Firefox, maxinstance = 1, platform = Windows
  • Node 2 – Port 5556, Chrome, maxinstance = 1, platform = Windows

On the terminal, execute the following commands to configure the two nodes:

Configuration of Node 1

java -jar selenium-server-standalone-3.9.1.jar -role node -hub http://107.108.86.20:4444/grid/register/ -browser "browserName=firefox,maxinstance=1,platform=WINDOWS" -port 5555


Configuration of Node 2

java -jar selenium-server-standalone-3.9.1.jar -role node -hub http://107.108.86.20:4444/grid/register/ -browser "browserName=chrome,maxinstance=1,platform=WINDOWS" -port 5556


You can visit this page to verify whether the nodes have been configured properly. Below is the screenshot that shows the status of the nodes.

Selenium-Hub-Node-Setup

The end goal that we plan to achieve is to divert the request from the nodes to the hub, invoke the ‘required browser instance,’ open the webpage inputted to the browser, and terminate the browser session, i.e. perform and clean up the allocated resources.

Since we are using Pytest for development, we recommend that you download PyCharm (Community Edition) from here.

command_executor – if the hub is configured incorrectly or if the wrong IP address or port is used, you may get an error ‘Couldn’t register the node’ while conducting the node registration.

Pytest-Selenium-Grid-Error-Hub-Node

desired_capabilities – the required capabilities are passed through the Remote WebDriver. Based on the details inputted as a part of desired_capabilities, the ‘best matching’ node is selected for execution.

Selenium-Browser-Invocation

The first test case has to be executed on a node that has the Chrome browser, and the second test case required has to be executed on a node that has the Firefox browser. You can have a look at how we modified the ‘Local WebDriver’ implementation to ‘Remote WebDriver’ implementation by configuring the WebDriver to execute requests on a remote machine, i.e. matching node. The complete implementation is demonstrated below:

#FileName - test_selenium_grid_firefox_chrome.py

# Import the 'modules' that are required for execution

import pytest
#import pytest_html
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from time import sleep

#Fixture for Firefox
@pytest.fixture(params=["chrome", "firefox"],scope="class")
def driver_init(request):
    if request.param == "chrome":
    #Local webdriver implementation
    #web_driver = webdriver.Chrome()
    #Remote WebDriver implementation
    web_driver = webdriver.Remote(
            command_executor='http://107.108.86.20:4444/wd/hub',
            desired_capabilities={'browserName': 'chrome', 'javascriptEnabled': True})
    if request.param == "firefox":
 #Local webdriver implementation
    #web_driver = webdriver.Firefox()

    #Remote WebDriver implementation
    web_driver = webdriver.Remote(
           command_executor='http://107.108.86.20:4444/wd/hub',
           desired_capabilities={'browserName': 'firefox'})
    request.cls.driver = web_driver
    yield
    web_driver.close()

@pytest.mark.usefixtures("driver_init")
class BasicTest:
    pass
class Test_URL(BasicTest):
        def test_open_url(self):
            self.driver.get("https://www.lambdatest.com/")
            print(self.driver.title)

            sleep(5)


The implementation remains the same since the only thing that changes is using the Remote WebDriver interface. For more information about the above implementation (including fixtures, classes, etc. in Pytest), please refer our earlier article here.

To execute the code, please use the command on the local terminal (or terminal on PyCharm).

py.test --verbose --capture=no test_selenium_grid_firefox_chrome.py


Once the Hub receives a request for the execution of ‘testcase 1,’ the request would be diverted to Node 2 (where Chrome browser is configured) and request the execution of ‘testcase 2.’ The request would then be diverted to Node 1 (where Firefox browser is configured). The output is shown below.

Pytest-Selenium-Grid

LambdaTest: a Cross-Browser Testing Cloud

Selenium Grid setup is very useful when you have to execute a large number of test cases on different machines. In order to get the best out of Selenium Grid setup and automation testing, you may require to have machines with different Operating Systems and different types (and versions) of browsers installed on the same. Setting up such an infrastructure would involve a huge cost and a significant amount of effort to maintain.

In such a scenario, the team can make use of LambdaTest, a scalable cloud-based, cross-browser testing platform where you can perform testing on 2000+ browsers (of different versions) installed on different machines and devices (mobiles, tablets, etc.). The upside of using Selenium Grid setup offered by LambdaTest is that you can cut down heavily on your build and execution times.

Porting Existing RemoteWebDriver Interface for Selenium Grid Setup on LambdaTest

To get started, you need to create an account on LambdaTest. Once you have logged into your account, please head over to the ‘Automation’ tab by visiting https://automation.lambdatest.com/

LambdaTest-Automation-Tab

Before you start the automation test, you might need to set the capabilities required for execution. In the example that we used earlier, the tests had to be executed on Windows 10 machines with the browser being Firefox and Chrome. We generate the required capabilities using the ‘Capabilities Generator’ on LambdaTest. Shown below is a capability created using the generator where platform = Windows 10, BrowserName = Firefox.

LambdaTest-Capabilities-Generator

Capabilities Generated Using Capability Generator

capabilities = {
"build" : "your build name",
"name" : "your test name",
"platform" : "Windows 10",
"browserName" : "Firefox",
"version" : "64.0",
"selenium_version" : "3.13.0",
       "firefox.driver" : v0.23.0
}


Let’s have a close look at the various parameters that are supplied for setting the desired capabilities:

PARAMETER DESCRIPTION EXAMPLE
Build Build name that you can identify the build sel-grid-firefox-on-windows
Name Test name to identify the test being performed selenium-grid-test-using-firefox
Platform Platform/Operating System on which you intend the test to be performed Windows 10, Windows 8.1, MacOS, etc.
BrowserName A browser on which the automation test would be performed Firefox, Chrome, Microsoft Edge, etc.
version Particular browser version on which the test would be performed Firefox version 64.0, Chrome version 70.0, etc.
selenium_version Which version of Selenium that would be used for the testing 3.13.0
firefox.driver Remote WebDriver version for Firefox 2.42

It is important to note that some of the capability parameters mentioned above are optional, e.g. if you just specify platform, like Windows 10, and BrowserName, such as Firefox, the test would be performed on a node that has ‘Firefox on Windows 10’ (irrespective of the version of Firefox on that machine).

In our example, we declare the capabilities obtained from LambdaTest Capabilities generator, as shown below:

#Set capabilities for testing on Chrome
ch_caps = {
    "build" : "Sel-Grid-Chrome",
    "name" : "Testing on Chrome using Selenium Grid",
    "platform" : "Windows 10",
    "browserName" : "Chrome",
    "version" : "71.0",
    "selenium_version" : "3.13.0",
    "chrome.driver" : 2.42
}

#Set capabilities for testing on Firefox
ff_caps = {
    "build" : "Sel-Grid-Firefox",
    "name" : "Testing on Firefox using Selenium Grid",
    "platform" : "Windows 10",
    "browserName" : "Firefox",
    "version" : "64.0",
}


In order to perform testing, you have to enter your credentials – ‘username’ and ‘application key,’ which are supplied to the Remote WebDriver. The credentials (that have to be kept confidential) can be obtained by visiting your LambdaTest profile section. Here, ‘username’ is the email address with which you log in on LambdaTest, and ‘application key’ is the Access Token for authenticating to your LambdaTest account from external systems.

If the credentials are correct, the test would be executed on the remote URL

/* user_name – userid for login on Lambdatest */
/* app_key – Access token obtained from Lambdatest */

remote_url = "https://" + user_name + ":" + app_key + "@hub.lambdatest.com/wd/hub"


The ‘Remote URL’ also consists of @hub.lambdatest.com/wd/hub, which is the LambdaTest grid URL for your account. The remote WebDriver API now takes input as ‘remote_url’ and capabilities (ch_caps/ff_caps), which are generated using the LambdaTest Capabilities generator. Apart from these changes, the entire implementation is kept the same (like implementation using ‘Remote WebDriver interface without using LambdaTest’).

LT-RemoteWebDriver-SeleniumGrid

The complete implementation is below (Note: Global variables are stored in another Python file, which is imported at the beginning of the implementation).

# Obtain the credentials by visiting https://accounts.lambdatest.com/profile
UserName = "user-name"
AppKey = "access-token"


# Import the 'modules' that are required for execution   
import pytest #import pytest_html from selenium 
import webdriver from selenium.webdriver.chrome.options 
import Options from selenium.webdriver.common.keys 
import Keys from time import sleep import urllib3 
import warnings   #FileName – test_lam_selenium_grid_firefox_chrome.py 
#Global variables are declared in a seperate file import test_lam_var   
#Set capabilities for testing on Chrome ch_caps = {     
"build" : "Sel-Grid-Chrome",     
"name" : "Testing on Chrome using Selenium Grid",     
"platform" : "Windows 10",     
"browserName" : "Chrome",     
"version" : "71.0",     
"selenium_version" : "3.13.0",     
"chrome.driver" : 2.42 }   
#Set capabilities for testing on Firefox ff_caps = {    
 "build" : "Sel-Grid-Firefox",     
"name" : "Testing on Firefox using Selenium Grid",     
"platform" : "Windows 10",     
"browserName" : "Firefox",     
"version" : "64.0", }   
user_name = test_lam_var.UserName app_key = test_lam_var.AppKey   
#Fixture for Firefox @pytest.fixture(params=["chrome", "firefox"],scope="class") def driver_init(request):     urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)     
remote_url = "https://" + user_name + ":" + app_key + "@hub.lambdatest.com/wd/hub"     
if request.param == "chrome":     #Remote WebDriver implementation        
 #web_driver = webdriver.Remote(             
#command_executor='http://107.108.86.20:4444/wd/hub',             
#desired_capabilities={'browserName': 'chrome', 'javascriptEnabled': True})         
web_driver = webdriver.Remote(command_executor=remote_url, desired_capabilities=ch_caps)     
if request.param == "firefox":     
#Remote WebDriver implementation         
#web_driver = webdriver.Remote(         
#    command_executor='http://107.108.86.20:4444/wd/hub',         
#    desired_capabilities={'browserName': 'firefox'})         web_driver = webdriver.Remote(command_executor=remote_url, desired_capabilities=ff_caps)     request.cls.driver = web_driver     yield       web_driver.close()   @pytest.mark.usefixtures("driver_init") class BasicTest:     pass class Test_URL(BasicTest):         def test_open_url(self):             self.driver.get("https://www.lambdatest.com/")             print(self.driver.title)               sleep(5)


Below is the output when the Python code is executed using py.test command:

LambdaTest-Selenium-Grid

Though the command has been triggered on your machine, the execution happens on the ‘Node on the LambdaTest cloud infrastructure,’ which matches the capabilities supplied to the Remote WebDriver API. In order to check the execution status on the server, you have to navigate to the Automation tab where you can identify the tests executed using ‘build’ and ‘test-name,’ which were entered while creating the capabilities. Below is the snapshot of the sample code when executed on the LambdaTest server.

LambdaTest-Selenium-Grid

For the purpose of analysis and debugging, you can have a look at the different tabs, namely Exception, Command, Network, Logs, MetaData, etc., in the location where details about Automation tests are mentioned.

LambdaTest-Sample

Conclusion

Testing using Selenium Grid setup can be instrumental in speeding up your entire test execution process since you can take advantage of parallelism while implementing your tests. Though Selenium Grid setup (without a cloud infrastructure) can be a ‘scalable approach,’ its scalability can become limited if an in-house infrastructure is set up. Along with the initial setup, there would be repeated expenses for maintaining the infrastructure, too.

By leveraging setup of Selenium Grid infrastructure through LambdaTest, you can speed up your entire testing process since all the tests executed on the LambdaTest cloud. You can make use of test automation frameworks with respect to various programming languages, such as Python, C#, Ruby, Java, PHP, JavaScript, and more for implementation, which makes it more developer friendly. As far as implementation is concerned, porting an existing code (using an in-house Selenium Grid setup) to Selenium Grid setup offered by LambdaTest is easy and considerably time-saving.

Happy Testing!

Topics:
selenium testing ,cross browser testing ,selenium ,browser testing ,website testing ,Selenium GRid ,Performance ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}