TA #2 — Selenium Grid and Docker
[TA] — Test Automation article series
Selenium Grid is a smart proxy server that allows Selenium tests to route commands to remote web browser instances. Its aim is to provide an easy way to run tests in parallel on multiple machines.
Why Selenium Grid?
- Central entry point for all tests
- Management and control of the nodes/environment where the browsers run
- Scale UI testing infrastructure
- Shorter execution times for test suites (you still need good tests!)
- Enable running tests in parallel
- Cross-platform testing
- Load balancing
Components of a Grid

A Hub is a central point where all your tests are sent. Each Selenium Grid consists of exactly one hub. The hub will connect one or more nodes that tests will be delegated to.
Nodes are different Selenium instances that will execute tests on individual computer systems. There can be many nodes in a grid.
When to use Grid
Generally speaking, there’s two reasons why you might want to use Grid.
- To run your tests against multiple browsers, multiple versions of browser, and browsers running on different operating systems.
- To reduce the time it takes for the test suite to complete a test pass.
One of the reasons is to boost the time spent running the suite is to shorten the turnaround time for test results after developers check-in code for the AUT to give feedback as quickly as possible.

Main Concepts
Isolation
- Performance tends to degrade when resources are shared
- Unreleased browser sessions
- Temporal files not deleted
- Browsers tend to share some memory locations - Processes should run independently, ideally in containers
- Most known tools: QEMU, VirtualBox, Docker, VMWare
Performance Monitoring
- Resources are not unlimited (most of the time)
- How many tests can we run in parallel?
- How much RAM and CPU do we have?
How much RAM and CPU? How many tests in parallel? How many teams?
- Isolate browsers when possible.
- Rule of thumb, one CPU and one GB of RAM per browser.
- There is not a unique answer
Good Concepts to Follow
Stability -> Speed -> Coverage
- Stability
1. Use Linux when possible and acceptable
2. Try to run 1 test per host (container/VM) at a time
3. Save your configuration in Git and manage it with Puput/Chef/Ansible - Speed
1. Use small VMs/Containers for nodes
2. It is better to have 20 small nodes than 1 big one - Coverage
1. Add browsers one by one, depending on your requirements (Chrome and Firefox are the easiest ones to start)
2. More browsers, more versions and platforms to maintain
Docker Selenium
Docker provides a convenient way to provision and scale Selenium Grid infrastructure in a unit known as a container. Containers are standardised units of software that contain everything required to run the desired application, including all dependencies, in a reliable and repeatable way on different machines.
The Selenium project maintains a set of Docker images which you can download and run to get a working grid up and running quickly. Nodes are available for both Firefox and Chrome. Full details of how to provision a grid can be found within the Docker Selenium repository.
Prerequisite
The only requirement to run a Grid is to have Docker installed and working. Install Docker.
Docker
VMs (are houses) vs Docker Container (are apartment)

Why a Selenium Grid with Docker?
- Simplifies setup and teardown. A complete environment can be built from scratch in seconds.
- It becomes OS agnostic, it can run in any operating system where Docker is installed
- Simplifies scaling nodes up and down
- Portability
- Boosts CI reliability
1. With each run, a new Grid can be built
2. Clean environment
3. No pollution from previous tests
Example with Java and Maven
Let’s try it, download and unzip the Selenium-grid-test project.
We will use docker-compose to start out selenium hub, nodes, and application containers to run together.
# To execute this docker-compose yml file
# use `docker-compose -f docker-compose.yml up --build --abort-on-container-exit --scale chrome=2 --scale firefox=2`
version: "3"
services:
firefox:
image: selenium/node-firefox-debug
volumes:
- /dev/shm:/dev/shm
depends_on:
- hub
environment:
- HUB_HOST=hub
networks: ['selenium-grid']
chrome:
image: selenium/node-chrome-debug
volumes:
- /dev/shm:/dev/shm
depends_on:
- hub
environment:
- HUB_HOST=hub
networks: ['selenium-grid']
hub:
image: selenium/hub
ports:
- "4444:4444"
networks: ['selenium-grid']
tests:
image: tests:1.0
build:
context: ./
dockerfile: ./Dockerfile.dockerFile
depends_on:
- hub
volumes:
- ./.gradle:/root/.gradle
command: ["./wait-for-grid.sh", "./gradlew clean test --tests GoogleSearchTest"]
networks: ['selenium-grid']
networks: {selenium-grid: {}}
To start:
docker-compose -f docker-compose.yml up --build --abort-on-container-exit --scale chrome=2 --scale firefox=2
To teardown:
docker-compose -f docker-compose.yml down

Head to http://localhost:4444/grid/console and check our Selenium Grid powered by Docker Compose!
What if the Grid is not ready before tests run?
A smoke test on the Grid before running tests
Wait for it…
#!/bin/bash
# wait-for-grid.sh
set -e
cmd="$@"
while ! curl -sSL "http://hub:4444/wd/hub/status" 2>&1 \
| jq -r '.value.ready' 2>&1 | grep "true" >/dev/null; do
echo 'Waiting for the Grid'
sleep 1
done
>&2 echo "Selenium Grid is up - executing test"
exec $cmd
Selenium Grid in a CI with Jenkins

We will use a custom Jenkins image
The Dockerfile for this image is the following one:
FROM jenkins/jenkins:lts
USER root
RUN apt-get update \
&& apt-get install -y sudo curl\
&& apt-get install -y libltdl7\
&& rm -rf /var/lib/apt/lists/*
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
# getting the docker-cli
RUN curl -fsSL get.docker.com -o get-docker.sh
RUN sudo sh get-docker.sh
# Installing docker-compose
RUN sudo curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
RUN sudo chmod +x /usr/local/bin/docker-compose
USER jenkins
# Installing Git plugin. See: https://github.com/jenkinsci/docker#preinstalling-plugins
RUN /usr/local/bin/install-plugins.sh git:3.9.4
And configured docker-compose file
# To execute this docker-compose yml file
# use `docker-compose -f jenkins-docker-compose.yml up --build --abort-on-container-exit`
version: "3"
services:
jenkins_executor:
build:
context: ""
dockerfile: JenkinsDockerFile.dockerFile
labels:
kompose.service.type: nodeport
networks: ['jenkins']
ports:
- '8080:8080'
volumes:
- jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
networks: {jenkins: {}}
volumes:
jenkins_home:
Starting Jenkins (new terminal)
Command:
docker-compose -f jenkins-docker-compose.yml up --build
Getting Jenkins admin’s password from the log output
Head to http://localhost:8080/ and enter the password obtained above for the user admin.
Create Jenkins Job
- Click on create new jobs
- Enter the project name (e.g. docker-compose-test ), select Freestyle project and click OK
- On Source Code Management, select Git and enter https://github.com/naz1719/Simple-grid-test.git as Repository URL
- On the configuration page, click Add build step, then Execute shell
- In the command box enter
sudo docker-compose -f docker-compose.yml up --build --abort-on-container-exit --scale chrome=3 --scale firefox=3
- Click Save and Build Now
- Finally, click the job console output
P.S Ability to see the execution of UI test
We can see execution using f.e node-chrome-debug image by VNC Viewer
chrome:
image: selenium/node-chrome-debug
volumes:
- /dev/shm:/dev/shm
ports:
- "5556:5900"
# pwd to VNC Server : secret
depends_on:
- hub
environment:
- HUB_HOST=hub
networks: ['selenium-grid']
I’ve added port
- "5556:5900"
Let’s run tests and connect VNC Viewer with localhost:5556 host and password: secret

