Selenium Grid with Debug Docker containers

Nitin Bhardwaj
5 min readJun 16, 2020

In my last article, I explained how to set up Selenium Grid with Docker. If you haven’t read it, please read it first.

Since the tests run inside docker containers, you cannot see the browser opening up and all the steps being performed. The need of such utility will arise while debugging tests. Solution for this is present in the form of debug containers.

GETTING STARTED

For this article, I am going to use chrome and firefox debug containers.

  1. Pull the following docker images:

selenium/node-chrome-debug

$ docker pull selenium/node-chrome-debug

Grid Node with Chrome installed and runs a VNC server, needs to be connected to a Grid Hub

selenium/node-firefox-debug

$ docker pull selenium/node-firefox-debug

Grid Node with Firefox installed and runs a VNC server, needs to be connected to a Grid Hub

Verify the images on the system by using:

$ docker images

Note: node-firefox, node-chrome, hub images were set up in my previous article.

Since debug containers are being used now, you will have make to changes to your docker-compose.yml file.

After updating, your docker-compose.yml file should look something like this:

version: "3"
services:
hub:
image: selenium/hub
ports:
- "4444:4444"
environment:
GRID_MAX_SESSION: 16
GRID_BROWSER_TIMEOUT: 3000
GRID_TIMEOUT: 3000
chrome:
image: selenium/node-chrome-debug
container_name: web-automation_chrome
depends_on:
- hub
environment:
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 4
NODE_MAX_INSTANCES: 4
volumes:
- /dev/shm:/dev/shm
ports:
- "9001:5900"
links:
- hub
firefox:
image: selenium/node-firefox-debug
container_name: web-automation_firefox
depends_on:
- hub
environment:
HUB_PORT_4444_TCP_ADDR: hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 2
NODE_MAX_INSTANCES: 2
volumes:
- /dev/shm:/dev/shm
ports:
- "9002:5900"
links:
- hub

2. Download VNC Viewer

You can download VNC viewer from the link.

Open the VNC viewer and please proceed with installation steps. After installation, you will see the following screen:

3. Time to setup infrastructure!!

$ docker-compose -f /path/to/docker-compose.yml up -d

To verify if containers are up, use the following command:

$ docker ps

4. Integrate VNC viewer with docker containers.

Enter your <ip address of your container>:<container port address> in vnc viewer search tab. In my case, it is 0.0.0.0:9001 and 0.0.0.0:9002.

After this, vnc viewer will prompt for password. Default password is secret.

VNC viewer is now connected to your docker container.

Repeat the same steps for firefox container.

5. Time to run tests!!

Use the following command to run tests:

$ mvn clean test -Dsurefire.suiteXmlFiles=Testng.xml

As you can see, both the tests ran in chrome and firefox debug containers in parallel mode. This time they took 2 mins :14 seconds which is slower as compared to the non-debug containers. In non-debug containers, they took
1 min: 29 secs.

If the same tests are run on chrome-debug only, it takes 55 secs.

If the same tests are run on firefox-debug, it takes 1min: 22 secs.

Time used by single browser runs are similar to the ones in non-debug mode. Whereas, in parallel, same tests take almost twice the time.

Note: All the readings are taken after running the tests multiple times to ensure network bandwidth related issues can be avoided.

6. Tear Down the infrastructure.

$ docker-compose -f /path/to/docker-compose.yml down

Containers will be stopped. Grid network will be destroyed.

$ docker ps

You can verify the same using above command. No running containers will be there.

Adding sample code for reference below:

TestClass.java

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.*;

import java.net.MalformedURLException;
import java.net.URL;

public class TestClass {

private WebDriver driver;
PageClass pageClass;

@Parameters({"Port"})
@BeforeClass
public void initiateDriver(String Port) throws MalformedURLException {
if(Port.equalsIgnoreCase("9001"))
{
driver = new RemoteWebDriver(new URL("http:localhost:4444/wd/hub"), DesiredCapabilities.chrome());
driver.manage().window().maximize();
}
else if(Port.equalsIgnoreCase("9002")){
driver = new RemoteWebDriver(new URL("http:localhost:4444/wd/hub"), DesiredCapabilities.firefox());
driver.manage().window().maximize();
}

pageClass = new PageClass(driver);
}

@AfterClass
public void quitDriver()
{
driver.quit();
}

@Parameters("browser")
@Test
public void Test1(String browser){

System.out.println("Test1 :" + browser);
driver.get("https://www.amazon.in/");
pageClass.enterItemToSearch("books");
pageClass.getSearchedItem(0);
}

@Parameters("browser")
@Test
public void Test2(String browser){

System.out.println("Test2 :" + browser);
driver.get("https://www.amazon.in/");
pageClass.enterItemToSearch("headphones");
pageClass.getSearchedItem(0);
}
}

PageClass.java

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;

import java.util.List;

public class PageClass {

WebDriver driver;

@FindBy(how = How.ID,using = "twotabsearchtextbox")
private WebElement searchBox;

@FindBy(how = How.XPATH, using = "//div[@id='nav-search']//input[@type='submit']")
private WebElement searchButton;

@FindBy(how = How.XPATH,using = "//span[@class='a-size-medium a-color-base a-text-normal']")
private List<WebElement> searchResults;


public PageClass(WebDriver driver){
this.driver = driver;
PageFactory.initElements(driver, this);
}

public void enterItemToSearch(String itemName){
searchBox.sendKeys(itemName);
searchButton.click();
}

public void getSearchedItem(int index){
searchResults.get(index).click();
}


}

Testng.xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite thread-count="4" name="SeleniumGridDocker" parallel="tests">


<test name="Chrome Test">
<parameter name="browser" value="chrome" />
<parameter name="Port" value="9001" />
<classes>
<class name="TestClass" />
</classes>
</test>

<test name="Firefox Test">
<parameter name="browser" value="firefox" />
<parameter name="Port" value="9002" />
<classes>
<class name="TestClass" />
</classes>
</test>

</suite>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>SeleniumGridDocker</groupId>
<artifactId>SeleniumGridDocker</artifactId>
<version>1.0-SNAPSHOT</version>


<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.141.59</version>
</dependency>
</dependencies>
</project>

Feel free to reach out to me incase of any query regarding the sample code.

Summary

In this article, I have explained how to set up and use node-debug containers for chrome and firefox using VNC viewer. Since these containers require more resources than non-debug containers, I will advise to use them only for debugging purposes.

I hope this article has been helpful to the enthusiasts looking to explore cross browser testing using selenium grid and docker.

Take care. Keep Learning. Stay SAFE.

--

--