Setting Up Selenium Grid 4: A Step-by-Step Tutorial for Scalable Test Automation

July 28, 2025

As web applications grow in complexity, the demand for rapid, reliable, and scalable testing has never been more critical. A single, sequential test suite that once took minutes can quickly balloon into hours, creating a significant bottleneck in the CI/CD pipeline. This is the challenge where a selenium grid transforms from a 'nice-to-have' into an absolute necessity. Selenium Grid 4 represents a monumental leap forward from its predecessors, rebuilt from the ground up with modern architecture, enhanced stability, and first-class Docker support. It empowers QA teams and developers to run tests in parallel across multiple machines, browsers, and operating systems, drastically reducing execution time and accelerating feedback loops. This comprehensive guide will walk you through every step of setting up and mastering Selenium Grid 4, from the simplest Standalone configuration to a fully scalable, distributed grid using Docker. Whether you are new to parallel testing or migrating from an older version, this tutorial provides the authoritative knowledge you need to harness the full power of the modern selenium grid.

The Evolution: Why Selenium Grid 4 is a Game-Changer

To fully appreciate the power of Selenium Grid 4, it's essential to understand the limitations of its predecessors. Earlier versions, while revolutionary for their time, often involved a cumbersome setup process. Users had to manage separate Hub and Node JARs, wrestle with JSON configuration files, and frequently deal with stability issues like stale sessions or 'ghost' nodes. The architecture was less resilient, making it a challenge to maintain a robust testing infrastructure, a pain point echoed in many discussions on CI/CD pipeline optimization.

Selenium Grid 4 fundamentally re-architects the entire system to address these issues head-on. It's not merely an update; it's a complete rewrite guided by modern software development principles. The core philosophy shifted towards stability, observability, and adherence to web standards.

Key Architectural Improvements

The most significant change is the adoption of the W3C WebDriver Protocol as the native communication language between clients and the server. This eliminates the need for the complex JSON Wire Protocol translation layer, resulting in faster, more reliable, and more consistent test execution across all browser drivers. According to a Forrester report on DevOps trends, standardization is a key driver for reducing flakiness in automated processes, and Selenium Grid 4's W3C compliance is a direct reflection of this industry-wide movement.

Internally, the monolithic Hub has been deconstructed into several distinct components, each with a specific responsibility:

  • Router: The entry point for all incoming new session requests. It directs them to the New Session Queue.
  • Distributor: The brain of the grid. It pulls requests from the queue and finds a suitable Node with the requested capabilities (e.g., Chrome on Linux).
  • Session Map: Tracks the mapping between session IDs and the Node where the session is running.
  • Node: The worker machine that executes the browser automation commands.
  • Event Bus: A messaging system that facilitates communication between all the other components, allowing for a more decoupled and scalable architecture.

This new, distributed architecture not only enhances stability but also provides unprecedented observability. The revamped Grid UI offers a real-time view of the grid's capacity, current sessions, and the queue of pending tests. This level of insight was previously difficult to achieve without third-party tools. Furthermore, the integration of a GraphQL API allows for programmatic querying of the grid's state, opening up new possibilities for custom dashboards and monitoring solutions. The rise of containerization, as highlighted by Docker's own market trend reports, is also a central theme in Grid 4's design, with official, easy-to-use Docker images being a primary method of deployment.

Prerequisites: Gathering Your Tools for Grid Setup

Before diving into the setup process, it's crucial to ensure your environment is properly prepared. A successful selenium grid installation depends on having the right components in place. This preparation step will save you significant time and prevent common configuration errors down the line.

Here is a checklist of the essential software you will need:

  • Java Development Kit (JDK) 11 or higher: The Selenium Server is a Java application, and Grid 4 requires at least JDK 11 to run. You can verify your installed version by running java -version in your terminal. If you don't have it, you can download it from the official Oracle Java Downloads page or use an open-source alternative like OpenJDK.

  • Selenium Server JAR File: This is the core executable for the entire grid. You will need the single selenium-server-<version>.jar file. Always download the latest stable version directly from the official Selenium website to benefit from the latest features and bug fixes. Avoid using older, separate selenium-server-standalone files, as they are from previous Grid versions.

  • Web Browsers: You must have the actual web browsers you intend to test against (e.g., Google Chrome, Mozilla Firefox, Microsoft Edge) installed on the machines that will serve as Nodes.

  • WebDriver Executables: Each browser requires a corresponding WebDriver executable to allow Selenium to automate it. These drivers act as the bridge between your test scripts and the browser. You must download the correct driver version that matches your installed browser version.

    Pro Tip: Place these WebDriver executables in a directory that is included in your system's PATH environment variable. This allows the Selenium Server to find and launch them automatically without needing to specify their location with command-line flags.

  • (Optional but Highly Recommended) Docker: While not strictly required for a basic setup, Docker is the recommended way to run a scalable and maintainable selenium grid. It simplifies dependency management and allows for effortless scaling. We will cover the Docker setup in detail later. You can install Docker Desktop for your operating system.

Method 1: The Simplest Setup with Standalone Mode

For developers and QA engineers who need a quick, no-fuss way to run tests in parallel on a single machine, the Standalone mode is the perfect starting point. In this mode, a single command launches a fully functional selenium grid on your local machine, complete with a Hub and a Node. The Node is automatically configured to detect all available browser drivers in your system's PATH.

This mode is ideal for:

  • Learning the basics of selenium grid without the complexity of a distributed setup.
  • Running a small-scale parallel test suite on a local development machine.
  • CI environments where the agent is a single, powerful machine.

Starting the Grid in Standalone Mode

Open your terminal or command prompt, navigate to the directory where you downloaded the selenium-server-<version>.jar file, and execute the following command:

java -jar selenium-server-4.15.0.jar standalone

(Replace 4.15.0 with the version you downloaded.)

Upon execution, you will see a series of log messages indicating that the server components are starting. A key message to look for is:

INFO [SeleniumServer.boot] - Started Selenium Standalone 4.15.0 (revision 1d678a381b...): http://192.168.1.10:4444

This confirms that your selenium grid is up and running. You can now access the Grid Console UI by opening a web browser and navigating to the URL provided in the log, which is typically http://localhost:4444.

Exploring the Grid Console

The UI provides a wealth of information at a glance. You'll see the available browser slots (e.g., Chrome, Firefox) that the grid detected, the maximum number of concurrent sessions, and a real-time view of any running or queued tests. This immediate visual feedback is a significant improvement and helps in debugging test distribution issues. Research from MIT's HCI lab often emphasizes the importance of intuitive UIs in complex systems, and the Selenium 4 UI is a testament to this principle.

Running a Test on Your Standalone Grid

To run a test, you need to configure your Selenium client (your test script) to use RemoteWebDriver instead of a local driver (like ChromeDriver or FirefoxDriver). You must point it to the URL of your running grid.

Here is a simple example using Python:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options as ChromeOptions

# Define the grid URL
grid_url = "http://localhost:4444/wd/hub"

# Set desired capabilities for the test
options = ChromeOptions()
options.browser_version = 'latest'
options.platform_name = 'linux' # Or 'windows', 'mac'

# Create a RemoteWebDriver instance
driver = webdriver.Remote(
    command_executor=grid_url,
    options=options
)

try:
    print("Session started. Session ID:", driver.session_id)
    driver.get("https://www.google.com")
    print("Page title:", driver.title)
    search_box = driver.find_element(By.NAME, "q")
    search_box.send_keys("Selenium Grid 4")
    search_box.submit()
    print("Search performed.")
finally:
    # Always quit the driver to release the session on the grid
    driver.quit()
    print("Session closed.")

When you run this script, you will see the test being assigned to one of the available Chrome slots in the Grid Console. The driver.quit() command is absolutely critical; it terminates the session and releases the browser slot, making it available for the next test. Failing to call quit() will lead to orphaned sessions that consume grid resources.

Method 2: Building a Distributed Hub and Node Grid

While Standalone mode is excellent for local testing, the true power of a selenium grid is realized in a distributed environment. The Hub and Node model allows you to distribute your test load across multiple machines, each potentially having different operating systems and browser configurations. This is the classic setup for dedicated QA labs and robust CI/CD pipelines where scalability is paramount.

In this architecture:

  • The Hub acts as the central coordinator. It receives all test requests and distributes them to registered Nodes that match the requested capabilities.
  • Nodes are the worker machines. They register themselves with the Hub and wait for commands to execute tests in their configured browsers.

Step 1: Start the Hub

Choose one machine to act as your Hub. This machine doesn't need to be exceptionally powerful, as it's primarily responsible for coordination, not test execution. From the terminal on this machine, run:

java -jar selenium-server-4.15.0.jar hub

The Hub will start on the default port 4444. You'll see log output confirming its startup, including the crucial URLs for the Event Bus and session registration.

INFO [Hub.start] - Selenium Grid Hub 4.15.0 is up and running on http://192.168.1.10:4444

Make a note of the Hub's IP address (192.168.1.10 in this example), as you will need it to connect your Nodes.

Step 2: Registering a Node

Now, on a separate machine (or in a separate terminal on the same machine for demonstration), you will start a Node and register it with the Hub. Ensure this machine has browsers and their corresponding WebDrivers installed.

The simplest command to start a Node is:

java -jar selenium-server-4.15.0.jar node --hub http://<HUB_IP_ADDRESS>:4444

Replace <HUB_IP_ADDRESS> with the actual IP address of your Hub machine. The Node will start, detect the browsers on its system, and attempt to register with the Hub. If successful, you'll see a log message like:

INFO [NodeServer.execute] - Registered with hub at http://192.168.1.10:4444

Now, if you refresh the Grid Console UI at http://<HUB_IP_ADDRESS>:4444, you will see the newly registered Node and its available browser slots.

Step 3: Advanced Node Configuration with TOML

For more granular control, relying on auto-detection isn't always ideal. You might want to specify exactly which browsers a Node offers, how many concurrent sessions it can run, or define custom capabilities. This is where configuration files become essential. Selenium Grid 4 uses the human-readable TOML (Tom's Obvious, Minimal Language) format.

Create a file named node-config.toml with the following content:

# Example TOML configuration for a Selenium Grid Node
[events]
publish = "tcp://<HUB_IP_ADDRESS>:4442"
subscribe = "tcp://<HUB_IP_ADDRESS>:4443"

[server]
port = 5555

[node]
# Max number of concurrent sessions on this node
max-sessions = 5
# Automatically register this node with the hub
register = true
register-cycle = 5000

# Define the drivers and their capabilities
[[node.driver-configuration]]
max-sessions = 3
display-name = "Chrome"
stereotype = '{"browserName": "chrome", "platformName": "WINDOWS"}'

[[node.driver-configuration]]
max-sessions = 2
display-name = "Firefox"
stereotype = '{"browserName": "firefox", "platformName": "WINDOWS"}'

This configuration file defines two browser types, Chrome and Firefox, and allocates a maximum of 3 and 2 concurrent sessions to them, respectively. Remember to replace <HUB_IP_ADDRESS> with your Hub's IP. To start a Node with this configuration, use the --config flag:

java -jar selenium-server-4.15.0.jar node --config node-config.toml

This approach is highly recommended for production-like environments, as it makes your selenium grid setup declarative and version-controllable. Infrastructure as Code (IaC) principles, which advocate for managing infrastructure via configuration files, are directly supported by this method, leading to more predictable and reproducible test environments.

Step 4: Running Tests on the Distributed Grid

The test script for a distributed grid is identical to the one for Standalone mode. The only change is the grid_url, which must point to the Hub's address:

grid_url = "http://<HUB_IP_ADDRESS>:4444/wd/hub"

When you run your test, the RemoteWebDriver will send the new session request (including the desired capabilities) to the Hub. The Hub's Distributor component will then find a registered Node that matches the request (e.g., a Node with an available Chrome slot on Windows) and forward the session to it. All subsequent test commands will be proxied through the Hub to the correct Node until driver.quit() is called.

Method 3: The Ultimate Scalability with Docker and Docker Compose

For the ultimate in scalability, reproducibility, and ease of management, running your selenium grid with Docker is the industry-standard approach. Containerization solves many common infrastructure problems: it isolates dependencies, ensures a consistent environment for every test run, and allows you to scale your grid up or down with a single command. The adoption of container technology in QA has skyrocketed, with a 2024 Gartner report indicating that over 70% of enterprise CI/CD pipelines now leverage containers for testing and deployment.

Selenium provides official Docker images for all grid components, making the setup process incredibly streamlined.

Using Docker Compose for a One-Command Grid

While you can run individual Docker containers for the Hub and Nodes, the most efficient method is to use Docker Compose. It allows you to define and manage your multi-container application in a single docker-compose.yml file.

Create a file named docker-compose.yml and add the following configuration:

version: "3"
services:
  selenium-hub:
    image: selenium/hub:latest
    container_name: selenium-hub
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"

  chrome:
    image: selenium/node-chrome:latest
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443

  firefox:
    image: selenium/node-firefox:latest
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443

Let's break down this file:

  • services: Defines the different containers that make up our application.
  • selenium-hub: This service uses the official selenium/hub image. It exposes the necessary ports for the Grid UI (4444), event publishing (4442), and subscribing (4443).
  • chrome & firefox: These are our Node services. They use the selenium/node-chrome and selenium/node-firefox images respectively.
  • depends_on: This ensures that the Nodes will only start after the Hub is running.
  • environment: This is the crucial part for Node configuration. We set environment variables to tell the Nodes where to find the Hub's Event Bus. Docker Compose creates a private network where services can reach each other by their service name (e.g., selenium-hub).

Launching and Scaling Your Dockerized Grid

With the docker-compose.yml file in your directory, starting the entire selenium grid is as simple as running one command:

docker-compose up -d

The -d flag runs the containers in detached mode (in the background). Docker will pull the necessary images and start the Hub, one Chrome Node, and one Firefox Node. You can check the status with docker-compose ps.

The real magic comes with scaling. Need more Chrome browsers for a large test run? No problem:

docker-compose up -d --scale chrome=5

This single command will instantly create four additional Chrome Node containers, and they will automatically register with the Hub, ready to accept tests. The Grid Console at http://localhost:4444 will immediately reflect this new capacity. This on-demand scalability is a core tenet of modern DevOps culture and is impossible to achieve this easily with traditional, non-containerized setups.

To run your tests, your RemoteWebDriver should still point to http://localhost:4444/wd/hub, as the Hub's port is mapped to your host machine.

To tear down the entire grid and remove all containers and networks, simply run:

docker-compose down

This clean, ephemeral nature of a Dockerized selenium grid is perfect for CI pipelines, ensuring a fresh, pristine test environment for every single build, a best practice recommended by numerous thought leaders in continuous integration.

Advanced Features and Best Practices for a Robust Selenium Grid

Once your selenium grid is operational, you can explore its advanced features and adopt best practices to create a truly professional-grade testing infrastructure.

Observability and Live View

Selenium Grid 4 offers fantastic observability features out of the box. The Docker images come in -debug variants (e.g., selenium/node-chrome-debug) which include a VNC server. When you run a container using a debug image and map port 5900, you can connect with a VNC client to see a live view of the browser as your test executes. This is invaluable for debugging complex UI interactions.

To enable this, modify your docker-compose.yml for a debug node:

  chrome-debug:
    image: selenium/node-chrome-debug:latest
    ports:
      - "5900:5900"
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      # ... other environment variables

The GraphQL API

The new Grid Console is powered by a GraphQL API, which you can also query directly. This allows for sophisticated monitoring and automation. You can programmatically check the grid's status, see the session queue, and get detailed information about each node. You can explore the API schema and run queries using a tool like Postman or directly at the http://localhost:4444/graphql endpoint.

Here's an example query to get the total number of slots and active sessions:

query GridStatus {
  grid {
    totalSlots
    sessionCount
    sessionQueueSize
  }
}

This programmatic access is a boon for creating custom dashboards or integrating grid metrics into monitoring systems like Prometheus or Grafana, a practice that aligns with the Site Reliability Engineering (SRE) principles outlined by engineers at Google.

Dynamic Grid and Relay

For ultimate elasticity, Selenium Grid 4 supports a Dynamic Grid model where nodes can be added and removed on the fly. This is often orchestrated by tools like Kubernetes, which can automatically scale the number of node pods based on the length of the session queue. This advanced setup ensures you are only using compute resources when you need them.

Additionally, the Relay feature allows your local grid to proxy new session requests to third-party cloud testing providers like BrowserStack or Sauce Labs. This creates a hybrid model where you can run some tests on your local infrastructure and seamlessly offload others to the cloud, all through a single grid endpoint.

Best Practices for Test Code and Grid Security

  • Always Use driver.quit(): This cannot be overstated. Encapsulate your WebDriver logic in a try...finally block to ensure driver.quit() is always called, even if the test fails. This releases the session and node resources.
  • Design for Parallelism: Write your tests to be atomic and independent. Tests should not depend on the state left by a previous test. This is fundamental to reaping the benefits of parallel execution, a core concept in software testing standards like ISO/IEC/IEEE 29119.
  • Use Explicit Waits: Avoid Thread.sleep(). Use WebDriverWait and ExpectedConditions to wait for elements to be present or interactive. This makes your tests more resilient to variations in page load times.
  • Secure Your Grid: In a shared environment, do not expose the grid's Hub port directly to an open network. Place it behind a reverse proxy like Nginx or an application load balancer. Implement authentication and authorization to control who can create sessions on your grid.

Selenium Grid 4 is a powerful, modern, and stable platform that fundamentally transforms how we approach automated browser testing. By moving from a complex, often fragile system to a streamlined, observable, and container-friendly architecture, it has lowered the barrier to entry for building a scalable test infrastructure. We've journeyed from the simple one-command Standalone mode, through the classic distributed Hub and Node setup, and finally to the supremely scalable Docker Compose method. Each approach offers a different level of control and complexity, allowing you to choose the right fit for your project's needs. The true value of a selenium grid lies not just in running tests, but in enabling a culture of rapid feedback and high-quality software delivery. By embracing the capabilities of Selenium Grid 4, you are equipping your team with the tools necessary to test at the speed of modern development.

What today's top teams are saying about Momentic:

"Momentic makes it 3x faster for our team to write and maintain end to end tests."

- Alex, CTO, GPTZero

"Works for us in prod, super great UX, and incredible velocity and delivery."

- Aditya, CTO, Best Parents

"…it was done running in 14 min, without me needing to do a thing during that time."

- Mike, Eng Manager, Runway

Increase velocity with reliable AI testing.

Run stable, dev-owned tests on every push. No QA bottlenecks.

Ship it

FAQs

Momentic tests are much more reliable than Playwright or Cypress tests because they are not affected by changes in the DOM.

Our customers often build their first tests within five minutes. It's very easy to build tests using the low-code editor. You can also record your actions and turn them into a fully working automated test.

Not even a little bit. As long as you can clearly describe what you want to test, Momentic can get it done.

Yes. You can use Momentic's CLI to run tests anywhere. We support any CI provider that can run Node.js.

Mobile and desktop support is on our roadmap, but we don't have a specific release date yet.

We currently support Chromium and Chrome browsers for tests. Safari and Firefox support is on our roadmap, but we don't have a specific release date yet.

Β© 2025 Momentic, Inc.
All rights reserved.