As listed in main post and continue to Part 2, we will focus on setting up Selenium Grid using Docker compose in this Part 3 post.
Introduction
Docker Compose is a tool that was developed to help define and share multi-container applications. With Compose, we can create a YAML file to define the services and with a single command, can spin everything up or tear it all down.
So with Docker Compose, we can start Hub and all Nodes in one time run, instead of typing long command for each container start-up. It will ultimately save up a lot of time configuring those containers from scratch.
docker-compose-v3.yml
version: "3"
services:
chrome:
image: selenium/node-chrome:4.7.2-20221219
shm_size: 2gb
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:4.7.2-20221219
shm_size: 2gb
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
edge:
image: selenium/node-edge:4.7.2-20221219
shm_size: 2gb
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
selenium-hub:
image: selenium/hub:4.7.2-20221219
container_name: selenium-hub
ports:
- "4442:4442"
- "4443:4443"
- "4444:4444"
version 3: It is the latest version of the docker-compose files.
services(containers): This contains the list of the images and their configurations.
image: It defines which image will be used to spin up container.
shm_size: Use the host's shared memory.
ports: Published ports in exposed port : container port format.
container_name: Name of our containers.
depends_on: This defines the required dependency before spinning up the container. In our docker-compose.yml file, containers Chrome and Firefox are dependent upon container hub to spin up.
SE_EVENT_BUS_HOST: Hub host.
SE_EVENT_BUS_PUBLISH_PORT and SE_EVENT_BUS_SUBCRIBE_PORT: Ports 4442 and 4443 are exposed by default for Event Bus ports to help them communicate with Hub.
Optional:
SE_NODE_MAX_INSTANCES: This defines how many instances of same version of browser can run over the Remote System.
We can add more instance of Chrome to 4 instances by
docker compose -f docker-compose-v3.yml up --scale chrome=4
SE_NODE_MAX_SESSIONS: This defines maximum number of concurrent sessions that will be allowed.
Run the docker compose file
To execute this docker-compose yml file use
docker-compose -f docker-compose-v3.yml up
Add the -d flag at the end for detached execution
docker-compose -f docker-compose-v3.yml up -d
To stop the execution, hit Ctrl+C, and then
docker-compose -f docker-compose-v3.yml down
Execute compose file
And here is how they are in Docker Desktop (1 container for hub and 3 containers for 3 nodes)
And here is main page with 3 registered nodes
We can modify above yml to use noVNC by assign the default noVNC port of each node container (7900) to any port.
For example:
chrome:
image: selenium/node-chrome:4.7.2-20221219
shm_size: 2gb
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
ports:
- "7901:7900"
Then we can inspect what runs inside browser of container by" http://localhost:7901/?autoconnect=1&resize=scale&password=secret
Or we can see that easily by clicking on video icon under Sessions tab.
Go to "View test run visually on browser" in Part 2 for more details.
Point test to exposed hub port
Point RemoteWebDriver in your test to http://localhost:4444
driver = new RemoteWebDriver(new URL("http://localhost:4444"),chromeOptions);
There is an example that I have already written in this repo: https://github.com/trongtuyen96/selenium-grid-docker-zalenium
Head to /test/java/DockerComposeTest.java for more details. To execute the test properly, you need to run the DockerCompose.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="DockerComposeTest_Suite">
<test name="ChromeTest">
<parameter name="browser" value="chrome"/>
<classes>
<class name="DockerComposeTest"/>
</classes>
</test>
<test name="FirefoxTest">
<parameter name="browser" value="firefox"/>
<classes>
<class name="DockerComposeTest"/>
</classes>
</test>
<test name="EdgeTest">
<parameter name="browser" value="edge"/>
<classes>
<class name="DockerComposeTest"/>
</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.
Video recording for test execution
Tests execution can be recorded by using the selenium/video:ffmpeg-4.3.1-20221219 Docker image.
One container is needed per each container where a browser is running. This means if you are running 5 Nodes/Standalone containers, you will need 5 video containers, the mapping is 1-1.
Currently, the only way to do this mapping is manually (either starting the containers manually, or through docker-compose)
After the containers are stopped and removed, you should see a video file on your machine's /tmp/videos directory.
Please head to docker-compose-v3-video.yml for full details.
Summary
So it comes to an end now but we had a great series https://www.automatedtestingwithtuyen.com/post/selenium-grid-with-docker-series
here to learn and review.
I hope this series gives you a better understanding of Selenium Grid 4 in different modes with Docker and practically you can also set up the Grid and use it in your test automation.
Check out my repo: https://github.com/trongtuyen96/selenium-grid-docker-zalenium for more details.
Please drop your comments below if you have any queries, I will answer them as best as I can đ.
Happy testing !!!