top of page
Search
Writer's pictureTuyen Nguyen

Part 2 - Set up Selenium Grid with Docker using different machines

Updated: Jul 29

As listed in main post and continue to Part 1, we will focus on setting up Selenium Grid using Docker in this Part 2 post.


Introduction

Docker is an open-source containerization platform that makes it easy to create, deploy, and run applications in a secure manner using containers. Docker provides virtualization at the Operating System (OS) level. All the software parts in Docker are organized in Containers.


When it comes to Selenium automation testing, it is important that a test run in one execution environment does not hinder the execution of tests run in another test environment (s). Hence, automation tests should be run in isolation, and Docker helps in realizing this ‘essential’ requirement.

  • Scalable and Reliable

  • Less overhead of installations

  • Improved Security

  • Lesser chances of discrepancies


Prerequisites

Make sure you have these below before started:

Yes, that's only it 😁.


Set up Selenium Grid with Docker - Standalone mode

There are 3 docker images for Chrome, Firefox and Edge used in this example.

They will use port 4444 by default for server and 7900 for NoVNC, so to use all 3 without error in allocated ports, mapping new ports need to be done.


Start Docker containers

Start Chrome standalone with port 4445

docker run -d -p 4445:4444 -p 7901:7900 --shm-size="2g" selenium/standalone-chrome:4.7.2-20221219
  • Container exposed on port http://localhost:4445

  • NoVNC (allow users inspect visually container activity with their browser) exposed on port 7901

  • For an image that contains a browser please use the flag --shm-size=2g to use the host's shared memory

  • In order to prevent pushing up to existing tags and breaking existing functionality, should use tagging convention

selenium/standalone-browserName-<Major>.<Minor>.<Patch>-<YYYYMMDD>

Start Firefox standalone with port 4446

docker run -d -p 4446:4444 -p 7902:7900 --shm-size="2g" selenium/standalone-firefox:4.7.2-20221219

Start Edge standalone with port 4447

docker run -d -p 4447:4444 -p 7903:7900 --shm-size="2g" selenium/standalone-edge:4.7.2-20221219

No need to pull image in advance as Docker will pull that image if it was not existed locally


And here is how they are in Docker Desktop (3 containers for 3 standalone)


Standalone Chrome at http://localhost:4445


Standalone Firefox at http://localhost:4446


Standalone Edge at http://localhost:4447


Point your test to exposed ports

Point RemoteWebDriver in your test to corresponding url.

case "chrome":
    ChromeOptions chromeOptions = new ChromeOptions();
    driver = new RemoteWebDriver(new URL("http://localhost:4445"),chromeOptions);
    break;
case "firefox":
    FirefoxOptions firefoxOptions = new FirefoxOptions();
    driver = new RemoteWebDriver(new URL("http://localhost:4446"),firefoxOptions);
    break;
case "edge":
    EdgeOptions edgeOptions = new EdgeOptions();
    driver = new RemoteWebDriver(new URL("http://localhost:4447"),edgeOptions);
    break;

There is an example that I have already written in this repo: https://github.com/trongtuyen96/selenium-grid-docker-zalenium


Head to /test/java/DockerStandaloneTest.java for more details. To execute the test properly, you need to run the DockerStandalone.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="DockerStandaloneTest_Suite">
    <test name="ChromeTest">
        <parameter name="browser" value="chrome"/>
        <classes>
            <class name="DockerStandaloneTest"/>
        </classes>
    </test>
    <test name="FirefoxTest">
        <parameter name="browser" value="firefox"/>
        <classes>
            <class name="DockerStandaloneTest"/>
        </classes>
    </test>
    <test name="EdgeTest">
        <parameter name="browser" value="edge"/>
        <classes>
            <class name="DockerStandaloneTest"/>
        </classes>
    </test>
</suite>

So the Chrome container will run test on Chrome browser, Firefox container will run test on Firefox and Edge container will run test on Edge.


View test run visually on browser

New version of standalone container from selenium has provided noVNC to allow user to inspect what is running in browser. We do not need to install VNC client to do this anymore.


To see what is happening inside the container, head to:

or simply: http://localhost:7901 and provide password "secret" when it is asked.


When there are no test running


And when test running


Another approach for us to view this is to click on video icon next to session id under Sessions tab.


Set up Selenium Grid with Docker - Hub and Node mode

The Hub and Nodes will be created on different machines/VMs, they need to know each other's IPs to communicate properly. If more than one node will be running on the same Machine/VM, they must be configured to expose different ports.


And as I already mentioned, using different containers for hub and nodes, it is the same concept with setting up Hub and Nodes on different machines, which requires us to specify Event Bus, Publish Event port and Subscribe Event port.


Hub - Machine/VM 1

By default, port 4444 is registered for server whereas 4442 and 4443 are exposed for Event Bus ports

docker run -d -p 4442-4444:4442-4444 --name selenium-hub selenium/hub:4.7.2-20221219


Node Chrome - Machine/VM 2

  • Default port of Node is 5555, so we simply expose that

  • Event Bus Host need to be set up with IP of Hub machine

  • Node host is current IP of this Node machine

  • Replace ^ with ` if you are using Linux/macOS/PowerShell, below example is for Windows CMD

docker run -d -p 5555:5555 ^
  --shm-size="2g" ^
  -e SE_EVENT_BUS_HOST=<ip-from-machine-1> ^
  -e SE_EVENT_BUS_PUBLISH_PORT=4442 ^
  -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ^
  -e SE_NODE_HOST=<ip-from-machine-2> ^
  selenium/node-chrome:4.7.2-20221219

Node Firefox - Machine/VM 3

Same set up applied for Firefox node machine with few modifications about node IP and image

docker run -d -p 5555:5555 ^
  --shm-size="2g" ^
  -e SE_EVENT_BUS_HOST=<ip-from-machine-1> ^
  -e SE_EVENT_BUS_PUBLISH_PORT=4442 ^
  -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ^
  -e SE_NODE_HOST=<ip-from-machine-3> ^
  selenium/node-firefox:4.7.2-20221219

Node Edge - Machine/VM 4

Same set up applied for Edge node machine with few modifications about node IP and image

docker run -d -p 5555:5555 ^
  --shm-size="2g" ^
  -e SE_EVENT_BUS_HOST=<ip-from-machine-1> ^
  -e SE_EVENT_BUS_PUBLISH_PORT=4442 ^
  -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ^
  -e SE_NODE_HOST=<ip-from-machine-4> ^
  selenium/node-edge:4.7.2-20221219

Point test to exposed IP of hub

This just works seamlessly

driver = new RemoteWebDriver(new URL("http://<ip-from-machine-1>:4444"),capabilities);

Try to write your own test and see how it works 😁.


Summary

The major downside of performing tests in a standalone container is low scalability. Hence, running Selenium in a standalone (or single) container is only suited for small projects. Whereas hub and node mode is definitely best fit for medium and a bit large demand (5 to < 100 nodes).


So it is all about setting and an example on how to run test with it. Hope it was able to bring an entirely fresh perspective to Selenium test automation for distributed testing to you.


for more details.


Next, Part 3, will be about setting up Grid with Docker compose. Stay tuned 😁!!!

3,128 views0 comments

Recent Posts

See All
Join my mailing list

Thanks for submitting!

© 2019 by Tuyen Nguyen

© 2019 by Tuyen Nguyen

  • White LinkedIn Icon
  • lm29-5xjdbzxe9s94-mn8yw
  • White Instagram Icon
bottom of page