Running Selenium tests on multiple browsers

In the post on UI testing with Selenium – record and refactor, the tests ran locally using Chrome. They were subsequently modified to run faster by running Selenium tests in parallel. For tests to be actually useful in the real world, they need to run on multiple browsers, on different platforms and not be reliant on a desktop system.

Local vs Remote

During test development and debugging it’s useful to have tests executing locally to observe their behaviour. When running in anger, the tests should be running via a CI system, allowing the tests to be scheduled and test results to be viewed centrally. The browsers themselves could be located anywhere – either an on premise execution grid or using one of the cloud based providers.

Choosing at runtime

Hard coding the tests for any reason makes maintenance very complex – for maximum flexibility, anything that could be changed should passed to the tests as an argument.

Remote WebDriver

In our previous examples we have been creating a new instance of WebDriver object with:

driver = new ChromeDriver();

But this is specific to a local browser – to choose the type and location (local or remote) at runtime, we need to write a class to build the required WebDriver object on request.

Factory Class

We will create a static class to build the WebDriver object required for the test, and then modify the tests so that they call the Browser Factory, which returns the required object e.g.:

driver = StaticBrowserFactory.buildBrowser();

or for the ThreadLocal case (from running Selenium tests in parallel):

driver.set(StaticBrowserFactory.buildBrowser());

The class itself is relatively simple, mainly consisting of a ‘case’ statement structure to create Options for the various browser types e.g.:

case FIREFOX:
    options = new FirefoxOptions();
    break;

And a simple boolean structure to create either a remote (with a URL) or local WebDriver object e.g.:

if (gridAddress != null) {
    browserObject = RemoteWebDriver.builder().oneOf(options).address(gridAddress).build();
} else {
    browserObject = RemoteWebDriver.builder().oneOf(options).build();
}

It can be called with a no arguments constructor (as detailed above, and using passed arguments at runtime to define the browser), or called with arguments to create a specific browser – e.g.:

StaticBrowserFactory.buildBrowser(browserType.FIREFOX);

The full class is StaticBrowserFactory.java

Selenium Grid

Remote WebDrivers run on a Selenium Grid – this is very easy to provision and run using Docker, which is a container virtualisation platform. Once installed (if you haven’t already got it), clone the repository from https://github.com/ObjectiveTester/AllThingsTesting.com-examples.git and open a terminal in the

same directory as docker-compose.yml:

AllThingsTesting.com-examples/BrowserFactory/docker-grid

And type the following command:

docker-compose up -d

Accessing http://localhost:4444 in a web browser shows the Grid console

Selenium Grid console

Local test execution

Opening a terminal in the directory:

AllThingsTesting.com-examples/BrowserFactory

And running the tests with the following command:

mvn clean test -Dbrowser=chrome -Dwebdriver.chrome.driver=<path-to-chromedriver>

Runs the test locally for development and debugging purposes.

Remote test execution (Docker Grid)

Starting the tests with:

mvn clean test -Dbrowser=chrome -Dgrid=http://localhost:4444

or

mvn clean test -Dbrowser=firefox -Dgrid=http://localhost:4444

Starts the tests on the Docker hosted Selenium Grid, and monitoring the console will show the sessions running.

Threaded test execution

To take advantage of all the resources of the Selenium Grid, running the tests with:

mvn clean test -Dbrowser=chrome -Dgrid=http://localhost:4444
-Djunit.jupiter.execution.parallel.enabled=true
-Djunit.jupiter.execution.parallel.mode.default=same_thread -Djunit.jupiter.execution.parallel.mode.classes.default=concurrent

Allows the tests to use more than one of the Grid instances of the specified browser.

Remote test execution (in the cloud)

The Factory Class supports additional parameters to define the platform and version of a browser. This is intended to be used when running tests on one of the cloud based testing platforms such as
https://saucelabs.com/
or
https://www.browserstack.com/

Adding additional parameters such as:

-Dplatform="Windows 10" -Dbrowser=chrome
-Dplatform="macOS 12" -Dbrowser=safari
-Dplatform="Windows 7" -Dbrowser=firefox
-Dplatform="Windows 11" -Dbrowser=edge

runs the test on the selected platform and browser (using the latest version). Specific versions can also be defined e.g.:

-Dplatform="macOS 10.15" -Dbrowser=chrome -Dversion=89.0

These parameters define the test run as requested, and the cloud platform stores details of the execution. e.g.:

Remote archive

The tests can now be moved to execute in a CI environment, executing either on a locally hosted Selenium grid or a remote cloud provider whilst still retaining the flexibility to be developed and debugged locally.

One thought on “Running Selenium tests on multiple browsers

Comments are closed.