Automation Testing Framework using Selenium WebDriver and Java : Day 5
Running automated test scripts on Selenium GRID with Docker containers.
In the last article of POM Automated Testing framework series, we learnt how to run our tests from command prompt with Maven commands and TestNG .xml with help of Surefire plugin.
Remote configurations in test script :
In order to run our tests on remote machine, we require Remote WebDriver configurations in test script. Remote machine could be a virtual machine(in this case Docker containers- browser instances), a machine next to you or a cloud machine.
In the test script, we need to add code which will invoke the RemoteWebDriver when we wish to run tests on a remote machine.
RemoteWebDriver constructor :
RemoteWebDriver is a class that inherits WebDriver. So when we create an object of this class it will be something like this :
WebDriver driver = new RemoteWebDriver(new URI(String url).toURL(), Capabilities cap);
Here the String url will be the hub url. The URL class constructors from java.net.URL package are deprecated now. So we use the URI class and use the toURL() method.
So a RemoteWebDriver class takes the huburl and browser capabilities as parameters.
Remote configurations in framework :
We need to configure our framework such a way that, based on our input, tests will be executed locally or remotely.
This input can provided from config.properties file. If it is false, the test execution will happen on local machine :
remote = true
huburl = http://localhost:4444/wd/hub
public class DriverManager {
// private WebDriver driver;
static ThreadLocal<WebDriver> tl_driver = new ThreadLocal<WebDriver>();
BrowserOptionsManager browserOptions;
Properties prop;
public WebDriver initDriver(Properties prop) {
this.prop = prop;
String browsername = prop.getProperty("browser");
System.out.println("Launching browser... " + browsername);
browserOptions = new BrowserOptionsManager(prop);
switch (browsername.toLowerCase()) {
case "chrome":
if (Boolean.parseBoolean(prop.getProperty("remote"))) {
init_remoteDriver("chrome");
} else {
// driver = new ChromeDriver();
tl_driver.set(new ChromeDriver(browserOptions.setChromeOptions()));
}
break;
case "edge":
if (Boolean.parseBoolean(prop.getProperty("remote"))) {
init_remoteDriver("edge");
} else {
// driver = new EdgeDriver();
tl_driver.set(new EdgeDriver(browserOptions.setEdgeOptions()));
}
break;
default:
System.out.println("Please provide a correct browser name..");
break;
}
get_tlDriver().get(prop.getProperty("url"));
get_tlDriver().manage().window().maximize();
get_tlDriver().manage().deleteAllCookies();
return get_tlDriver();
}
public WebDriver get_tlDriver() {
return tl_driver.get();
}
private void init_remoteDriver(String browser) {
System.out.println("Running tests on grid server :: " + browser);
try {
switch (browser) {
case "chrome":
tl_driver.set(
new RemoteWebDriver(new URI(prop.getProperty("huburl")).toURL(), browserOptions.setChromeOptions()));
break;
case "edge":
tl_driver.set(
new RemoteWebDriver(new URI(prop.getProperty("huburl")).toURL(), browserOptions.setEdgeOptions()));
break;
default:
System.out.println("Please provide a correct browser name..");
break;
}
} catch (MalformedURLException | URISyntaxException e) {
e.printStackTrace();
}
}
}
I have used if/else statement to execute tests locally or remotely. We can do the same from our BaseTest class as well. As we need to provide browser options/capabilities to the RemoteWebDriver constructor, I have created a separate class for the same.
public class BrowserOptionsManager {
private ChromeOptions co;
private EdgeOptions eo;
private Properties properties;
public BrowserOptionsManager(Properties prop) {
this.properties = prop;
}
public ChromeOptions setChromeOptions() {
co = new ChromeOptions();
if(Boolean.parseBoolean(properties.getProperty("remote")))
co.setCapability("browserName", "chrome");
return co;
}
public EdgeOptions setEdgeOptions() {
eo = new EdgeOptions();
if(Boolean.parseBoolean(properties.getProperty("remote"))) {
eo.setCapability("browserName", "msedge");
}
return eo;
}
}
Note that we don't exactly need to set a capability and then pass it to RemoteWebDriver constructor. We could pass an blank constructor of ChromeOptions/EdgeOptions/FirefoxOptions class.
WebDriver driver = new RemoteWebDriver(new URI(String huburl).toURL(), new ChromeOptions());
Setting up Docker Selenium GRID :
Here is a step by step guide to set up a Selenium GRID using Docker : https://debasmita-a.hashnode.dev/setting-up-selenium-grid-420-with-docker
Selenium GRID by default runs on localhost:4444 port. After setting up the GRID, launch the Selenium GRID on a browser.
Running tests on Selenium GRID :
Set remote property value to true in the config.properties file. Right click on testng.xml runner file and Run As->1 TestNG Suite.
The tests should launch on the grid.
In case if any java.util.concurrent.TimeoutException, try commenting the EdgeOptions setBrowserName capability and try running them again.
In the upcoming posts, we will see how to trigger script execution using Jenkins and GIT.
Thanks! and Happy Learning :)