Selenium Grid Tutorial – Set Up, Architecture and Parallel Execution

selenium grid tutorial

In today’s fast-paced development landscape, it is very crucial to test applications across multiple browsers, devices, and platforms in a limited time frame. Selenium Grid provides a robust solution to this challenge by enabling parallel test execution across distributed environments with speed and accuracy. In this article, we will understand what Selenium Grid is, its architecture, how to set it up, and real-world examples of parallel test execution.

What is Selenium Grid?

Selenium Grid is a powerful tool in the Selenium suite that allows parallel test execution on multiple machines, browsers, and platforms. It helps distribute the test load, thereby reducing execution time and improving test efficiency.

It uses the hub-node architecture, where the hub is the control room that controls the test execution, and the nodes are the remote machines that execute the tests on different browser instances.

Why use Selenium Grid?

Selenium Grid offers multiple benefits for testers and QA teams.

  1. Parallel Test Execution – A lot of execution time is saved by running tests on multiple machines concurrently.
  2. Cross-Browser Testing – Scale your test coverage by running tests against different browsers and OS configurations.
  3. Remote Execution – Tests can be executed on remote machines without depending on your local systems.
  4. Scalable Infrastructure – You can add more nodes as and when your testing needs grow.

With such advantages, agile teams can prioritize distributed and parallel testing, hence reducing the feedback loops in CI/CD workflows.

Selenium Grid Architecture

Selenium Grid uses the distributed architecture consisting of the following components-

1. Hub

This is the central point that receives the test requests. It acts as the central coordinator, distributing test scripts to appropriate nodes based on specified capabilities.

2. Node

A node is a remote machine that registers with the hub. Nodes are configured to run specific browser types and OS configurations. They take commands from the Hub and execute the requested test script.

Selenium Grid 4 is a complete redesign of its predecessor, introducing a microservice-based architecture. It comes with some new components which are discussed below.

3. Router

A router is added to Grid 4, and it acts as the entry point that handles incoming requests and forwards them to the proper service internally.

4. Distributor

The distributor allocates test sessions to available nodes based on their registered capabilities. It is primarily responsible for registering and keeping track of all the nodes and their capabilities. Additionally, it keeps track of new session requests that come through the new session queue.

5. Session Map

The Session map acts as a tracker and tracks where each test session is running. It stores the relationship between the session ID and the node where the session is running.

6. New Session Queue

The new session queue holds all the incoming session requests in FIFO order and checks if any requests in the queue have timed out so that they can be removed.

7. Event Bus

It is an asynchronous message layer that facilitates communication between Grid components in distributed mode. 

The below diagram is an overview of how communication happens in Selenium Grid 4.

Selenium Grid architecture diagram showing Router, Session Queue, Distributor, Session Map, Event Bus, Nodes, and Client components with their connections.

Selenium Grid 4 – What’s New?

The latest version of Selenium Grid comes with several enhancements-

  • It supports both standalone and distributed mode.
  • It offers built-in support for Docker.
  • It comes with an enhanced dashboard UI.
  • Its integrated Selenium manager can auto-detect browser drivers. 
  • The enhanced event logs and metrics provide improved observability.

The latest version of the Selenium grid can be downloaded from the official Selenium downloads page.

How to Set Up Selenium Grid?

To get started, you need to ensure the following prerequisites are in place-

  1. Java 11 or later must be installed on your system.
  2. Latest selenium server JAR file
  3. Web browser drivers such as Chrome Driver, Gecko Driver, etc. (these are optional with Selenium Manager)
  4. A good understanding of command-line operations

Modes of Operation in Selenium Grid 4

The latest version of Selenium Grid supports multiple modes to run the Grid-

  • Standalone Mode – For local development and quick execution
  • Hub and Node Mode – For distributed architecture in a classic style
  • Distributed Mode – A microservice-based architecture where each component (Event Bus, Router, Distributor, etc.) runs independently, ideally on separate machines.
  • Docker/Grid execution with Kubernetes – For highly scalable cloud-based execution

In this guide, we will focus on Standalone, and, Hub and Node Mode for simplicity and clarity.

Setting Up Selenium Grid in Standalone Mode

Standalone mode is the simplest setup to run the Selenium grid locally. 

Step 1: Download the Selenium Server

Visit the official Selenium downloads page and download the latest version of the Selenium Server JAR file. As of now, the latest version is 4.30.0. Place the downloaded JAR in a dedicated folder in your system.

Step 2: Launch Selenium Grid in Standalone Mode

Open your terminal or command prompt, and navigate to the folder where the JAR file is stored by using the following command:

java -jar selenium-server-4.30.0.jar standalone

Once done, you will see that the Selenium Server starts up, and the corresponding URI is displayed.

AD 4nXcofs54eqFoc 7VKgrcHacC5Qp7WdtgEwVZjunVbu1fOnH ZCKXVGOJSsoKnwe0bPvRxbbb989SOjYNcd5vqh4UsXCaLeToQQh8PAZ0AJcU4i04pXs207Ed9hEVdHbI4pvhkqc8lw?key=FMZSBXICZY0V EWLr2XFM1MO

Step 3: Verify the Grid UI

Once the server is up and running, open your browser and navigate to http://localhost:4444. You will see that the grid is running and the available Nodes and information on sessions, configurations, and logs.

AD 4nXf1qOhH0uK1 CTWizl2XnOhMxfDke CvPfyaUfOXUFp6x3McXjdSp6J4jfRQEXHMvMEP0qXQgomkon53CnFIEy8l2PYoXH496f3Hsv C1XIPKUux2jdLmdual2TYFrMztVwWx8ZjA?key=FMZSBXICZY0V EWLr2XFM1MO

Now that your Selenium Grid is set up in standalone mode you can run your tests on the Grid. We will be using a very basic Selenium test and run it on the Selenium Grid. We will use the ChromeOptions class and RemoteWebDriver to invoke the Chrome browser. The below code can be referred to for your execution:

import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
public class GridTest {
	@Test
	public void verifyPageTitle() throws MalformedURLException {
       // Create ChromeOptions object to set browser-specific capabilities
       ChromeOptions options = new ChromeOptions();
    // (Optional) You can add arguments or capabilities if needed
      // options.addArguments("--headless"); // Example: run Chrome in headless mode
       // Initialize the RemoteWebDriver with Grid URL and Chrome options
       WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
		driver.get("https://www.google.com/");
		
		//Get page title
		String actual= driver.getTitle();
		String expected = "Google";
		
		//Assert that the page title matches with the expected title
		Assert.assertEquals(actual, expected,"Page title does not match!");
		
		//Clean up
		driver.quit();
	}
}

Upon running the test, you will notice that the execution starts and the corresponding logs are printed in the terminal or command line showing the instance invoked.

AD 4nXfERNBUQkbvwkyR24kr92D X4934Cmm5FfXNPmJS4YPk krtUWI 4h43J0AYoy38huLDZpeIXOru0mx TussRwOoCPLtRRBNkxWGAUdpBLkkJWtkJR17m4l8N2EDdoQ6tvd7aw?key=FMZSBXICZY0V EWLr2XFM1MO
AD 4nXdE8C67V6 3Fju0dLK5pSp nZTU2i8GXbGQqP RLZWy7g1RORjncJIQe sKUh7SvyTu4Kp5Dsmi 6wDXVcmilFt ixBfcJ8wqYi7obqHndBeHY1PcCMnPzhTM4 GbpWau2Y3t36Q?key=FMZSBXICZY0V EWLr2XFM1MO

We will now see setting up and using Selenium grid in Hub and Node mode.

Setting Up Selenium Grid in Hub and Node Mode

This method of using Selenium Grid separates the Hub from the Nodes, hence making it more flexible for larger and distributed teams.

Step 1: Start the Hub

You can start the Hub by navigating to the location of the downloaded Selenium server in terminal or command line in your system and enter the following command-

java -jar selenium-server-4.30.0.jar hub

This will start the hub on port 4444 and act as the central point for managing all the incoming requests.

AD 4nXcAJHJnTmRdwG fzOcxnsdWpVG4lneLgwawwzpSedtU3dPd7cKAHcsrsU4uKqovKW5w1 gn RRxui1xWCRUaiwAlduLnZmfSVhZxe5ECTWedA 8PjWmEtZwjF8rb4XeP8siHF51Cw?key=FMZSBXICZY0V EWLr2XFM1MO

The UI will look like below-

AD 4nXdg9yDtN5MtEaQthTQAk3f39yVYQf 8iAkNOgiG6PFF3eNsbrwQdM AcPTDqSsJ2r8 lC2W AoSn0iifNP nM4kXEgIeZDS4j1kFXxKZEbRL9IeII59gsOXTF3gzlurcXc8xoAw?key=FMZSBXICZY0V EWLr2XFM1MO

Step 2: Register a Node

To register a node, open another terminal window and enter the following command:

java -jar selenium-server-4.30.0.jar node --detect-drivers true --hub http://localhost:4444

This command will detect the browser drivers automatically and connect it to the node.

AD 4nXdQN0wgNFE5nVqo9rDm6r5FYFzLPw 77Ih 8mVGhoFRTDQfzKbc5qe2slSCfywJlQnUHuUTte Tws0Sucyu5JUQiRRdNMdsJA8Iw8h8vrLUb31NsW Z8auzo6jH98DZ7Pvhy1Ar g?key=FMZSBXICZY0V EWLr2XFM1MO

Also, you will note that on the Hub UI, the node is registered.

AD 4nXeQXNgL6Sy6FYU8hQ4kE4bDypJulq6nbrHltfulr2vkuPU09lKq6YAsEGmWeNIfsbsi7E 3VWUtpMlbnw5aPI1K3ysNI3iAn8Yhi cSXnhtIDB86gEeTZ74Nba3E5NXQKQrdQFY?key=FMZSBXICZY0V EWLr2XFM1MO

Note that you can use the same machine or a different machine to register nodes with a Hub. Now that our hub and nodes are set up, we can run the same test that we ran on the standalone server and see the execution logs on the terminal.

Execution Logs on Hub:

AD 4nXfHRVk PamtTW1YQMv0ACJGz0ya6x dPVk6rE j5 OuWoouMaeZNrHzIPJBHMjrMq3B9zF4LGO0gOya6ipi0UFniy0ZV95J nyEHwCO6uqxPMYZv64K1xHl73hz f5SqhnNE92sw?key=FMZSBXICZY0V EWLr2XFM1MO

Execution Logs on Node:

AD 4nXcPMd3GDzeOqGuGTKBUzTBC Wk3Q28ErlmRgUK 8TIzjhY81sb3 APocwGZdJNLQHrcpSib ov1vdXwGAi EIbfqJWvb2 MZ8GFF4TcW9edBlbuLGHcYj499YwUD8Tyju3IrEdDqg?key=FMZSBXICZY0V EWLr2XFM1MO

Running Tests in Parallel with Selenium Grid

Selenium Grid enables parallel execution of tests across multiple machines, browsers, and operating systems, reducing execution time and improving test efficiency. This helps teams ensure that the application works consistently across multiple environments and browsers in reduced execution time. 

To begin with, you need to create different test classes for the different browsers that you need to check.

Chrome Test Class

package crossBrowser;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
public class ChromeTest {
	@Test
	public void verifyPageTitle() throws MalformedURLException {
       // Create ChromeOptions object to set browser-specific capabilities
       ChromeOptions options = new ChromeOptions();
       // Initialize the RemoteWebDriver with Grid URL and Chrome options
       WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
		driver.get("https://www.google.com/");
		
		//Get page title
		String actual= driver.getTitle();
		String expected = "Google";
		
		//Assert that the page title matches with the expected title
		Assert.assertEquals(actual, expected,"Page title does not match!");
		
		//Clean up
		driver.quit();
	}
}

Firefox Test Class

package crossBrowser;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
public class FirefoxTest {
	
	@Test
	public void verifyPageTitle() throws MalformedURLException {
       // Create FirefoxOptions object to set browser-specific capabilities
       FirefoxOptions options = new FirefoxOptions();
       // Initialize the RemoteWebDriver with Grid URL and Firefox options
       WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
		driver.get("https://www.google.com/");
		
		//Get page title
		String actual= driver.getTitle();
		String expected = "Google";
		
		//Assert that the page title matches with the expected title
		Assert.assertEquals(actual, expected,"Page title does not match!");
		
		//Clean up
		driver.quit();
	}
}

Safari Test Class

package crossBrowser;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariOptions;
import org.testng.Assert;
import org.testng.annotations.Test;
public class SafariTest {
	@Test
	public void verifyPageTitle() throws MalformedURLException {
       // Create SafariOptions object to set browser-specific capabilities
       SafariOptions options = new SafariOptions();
       // Initialize the RemoteWebDriver with Grid URL and Safari options
       WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
		driver.get("https://www.google.com/");
		
		//Get page title
		String actual= driver.getTitle();
		String expected = "Google";
		
		//Assert that the page title matches with the expected title
		Assert.assertEquals(actual, expected,"Page title does not match!");
		
		//Clean up
		driver.quit();
	}
}

Now, create a TestNG XML configuration for parallel test execution.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite thread-count="3" parallel="tests" name="Suite">
 <test name="ChromeTest">
   <classes>
     <class name="crossBrowser.ChromeTest"/>
   </classes>
 </test> <!-- Test -->
 <test name="FirefoxTest">
   <classes>
     <class name="crossBrowser.FirefoxTest"/>
   </classes>
 </test> <!-- Test -->
 <test name="SafariTest">
   <classes>
     <class name="crossBrowser.SafariTest"/>
   </classes>
 </test> <!-- Test -->
</suite> <!-- Suite -->

Now, execute the TestNG XML and see that the tests are executed in parallel across the different browsers.

AD 4nXdlfVhS 4F1lv41fxmqOhZ0 Tj4hnNqcw4 UphS NITRzl6cVjvvZFV TkilRc9MtFqJ 8o5yupdBfc8eo8Xb3ZD05Jxx1AIDvg7y3r 9b8S8jgSvCZ2zgXC AY4gX7My7c4Obu?key=FMZSBXICZY0V EWLr2XFM1MO

Hub logs

AD 4nXdDwe UgfSjnJWA82Ax2L 0gWDVfdHePZU2 hHqDKt8wUtly438SE 6dv 5H3lfdMu8L4vGqk9bKGwmM5BpRyUIiuxqaD280uiNQmTcHINVuZqs2IhHYyLdwZvGcNzGfodX 3J7iw?key=FMZSBXICZY0V EWLr2XFM1MO

Node logs

AD 4nXegArIez MV2uM8mxJ7SH7uO c0PaxhjDX3VquKGzK BcFgGvso8qYnVzs 2IqfHHIfzW tyWv kCmJRNSoFCoPAXbzAT5gGWQ7tW1ST1vqSgRnB0GyP OczJ9 9yKJE5HLD rbQ?key=FMZSBXICZY0V EWLr2XFM1MO

And with this, you can easily perform and scale your test coverage to include the different browsers in your test strategy without compromising with the execution time.

Common Selenium Grid Commands

PurposeCommand
Start Standalone Gridjava -jar selenium-server.jar standalone
Start Hub Onlyjava -jar selenium-server.jar hub
Start Nodejava -jar selenium-server.jar node –detect-drivers true –hub http://localhost:4444
View Grid ConsoleOpen http://localhost:4444 in your browser
View Running SessionsOpen Grid UI or use API endpoint http://localhost:4444/status

Best Practices For Selenium Grid

To ensure stable, scalable and efficient test execution across all supported browsers and platforms using Selenium Grid, it is essential to follow certain best practices.

  1. Use Selenium-4 compatible Options classes in place of DesiredCapabilities for better driver customization and future-proofing against ongoing Selenium updates.
  2. Leverage parallel test execution using frameworks like TestNG or JUnit to maximize the benefits of distributed testing using Selenium Grid. Ensure that your tests are stateless and thread-safe to avoid flaky test behavior.
  3. Avoid hardcoding Grid URLs and browser names; instead, use configuration files or environment variables.
  4. Implement a WebDriver Factory pattern to improve code reuse by taking parameters for browser names and environments.
  5. Always monitor node health and load, as overloading of grid nodes can lead to session failures. You can integrate monitoring tools like Grafana for an overview of the overall health.
  6. Use tags and capabilities based on your specific requirements to route tests to appropriate nodes.
  7. Clean up sessions and drivers after execution to avoid clogging of the grid.
  8. Keep browser drivers updated and use the latest Selenium Grid version. Use Selenium Manager to automatically fetch the correct driver version, reducing configuration overhead.

Conclusion

Selenium Grid is one of the best options for any scalable test automation strategy. It not only empowers teams to run tests in parallel or perform cross-browser testing but also reduces test cycle durations. Whether you are testing locally, in a standalone or distributed environment, or through containers with Docker, Selenium Grid gives you the flexibility and control needed in agile development setups. With the latest version, the architecture is revamped to accommodate and power up the modern day practices in automation testing using Selenium Grid.