Selenium 4 Grid : How to use Standalone Grid

HOME

Selenium Grid routes command received by the client to distant browser instances, allowing WebDriver scripts to be run on remote machines (virtual or real). Its goal is to make running tests in parallel on numerous machines as simple as possible.

Selenium Grid allows us to run tests on numerous workstations in parallel and centrally manage diverse browser versions and setups (instead of in each individual test).

Selenium Grid 4 makes use of a variety of new technologies to make scaling up easier while still allowing for local execution.

Selenium Grid 4 is a brand-new implementation that doesn’t use the same codebase as the previous version.

A Selenium Grid is made up of several components. Using a Grid role, you can start each one individually or all of them at once, depending on your needs.

Why do we need Selenium Grid?

Imagine we need to run 1000 tests and it takes 20 hrs to run these tests. With the help pf Selenium Grid, we can have 4 different machines (VMs or separate physical machines) to run those tests. We can roughly reduce the execution time to one-fourth, which means the test execution will be finished in 5 hrs.

Grid is also used to support running tests against multiple runtime environments, specifically, against different browsers at the same time. For example, a ‘grid’ of virtual machines can be set up with each supporting a different browser that the application to be tested must support. So, machine 1 has Google Chrome, machine 2, has Edge, and machine 3 has the latest Firefox. When the test suite is run, Selenium-Grid receives each test-browser combination and assigns each test to run against its required browser. Grid makes cross-browser and parallel testing very easy.

1. Standalone

The term “standalone” refers to the combination of all components that, in the view of the user, operate as if they were one. After launching it in Standalone mode, you’ll have a fully functional Grid of one.

Standalone is also the quickest way to get a Selenium Grid up and running. The server will be listening on http://localhost:4444 by default, and you should use that URL in your RemoteWebDriver tests. The server will look for available drivers in the System PATH and utilize them.

java -jar selenium-server-4.1.2.jar standalone

2. Hub and Nodes

It enables the classic Hub & Node(s) setup. These roles are suitable for small and middle-sized Grids.

Hub – A Hub is the union of the following components:

  • Router
  • Distributor
  • Session Map
  • New Session Queue
  • Event Bus

By default, the server will be listening on http://localhost:4444, and that’s the URL you should point your RemoteWebDriver tests.

java -jar selenium-server-4.1.2.jar hub

Node – One or more Nodes can be started in this setup, and the server will detect the available drivers that it can use from the System PATH.

java -jar selenium-server-4.1.2.jar node --detect-drivers true

3. Distributed

On Distributed mode, each component needs to be started on its own. This setup is more suitable for large Grids.

  1. Event Bus: serves as a communication path to other Grid components in subsequent steps.
java -jar selenium-server-4.1.2.jar  event-bus

2. Session Map: responsible for mapping session IDs to the Node where the session is running.

java -jar selenium-server-4.1.2.jar sessions

3. New Session Queue: adds the new session request to a queue, then the distributor processes it.

java -jar selenium-server-4.1.2.jar sessionqueue

4. Distributor: Nodes register to it, and assigns a Node for a session request.

java -jar selenium-server-4.1.2.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false

5. Router: the Grid entrypoint, in charge of redirecting requests to the right component.

java -jar selenium-server-4.1.2.jar router --sessions http://localhost:5556 --distributor http://localhost:5553 --sessionqueue http://localhost:5559

6. Nodes

java -jar selenium-server-4.1.2.jar node 

Implementation of Standalone Selenium Grid

Now, let us see how to run Selenium tests in Selenium Grid using the Standalone option.

Step 1 – Download driver.exe for the browsers

I have downloaded the driver.exe (chrome, gecko) in Downloads.

Step 2 – Download selenium-server jar

Go to Selenium Official website. Navigate to Downloads and it shows that the latest stable version of Selenium Grid is 4.3.0. Click on that and download the jar file. Make sure to keep the browsers.exe and selenium-server jar file in the same folder.

Step 3 – Execute selenium-server jar

Open a command line terminal. Use the below command to run selenium-server standalone jar files.

java -jar selenium-server-4.3.0.jar standalone --port 4446

It’s optional to mention the port number at the end of the command. By default, it will use port 4444. It is good practice to mention the port at the end to avoid any conflict between the ports.

Step 4 – Add dependencies to the Maven project

Let us add the necessary dependencies to the pom.xml in the case of the Maven Project.

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>Selenium4Demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>Selenium4Demo</name>
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>

<dependencies>
   <dependency>
     <groupId>org.seleniumhq.selenium</groupId>
     <artifactId>selenium-java</artifactId>
     <version>4.1.2</version>
  </dependency>

   <dependency>
      <groupId>io.github.bonigarcia</groupId>
      <artifactId>webdrivermanager</artifactId>
      <version>5.1.0</version>
   </dependency>
  
   <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>7.4.0</version>
      <scope>test</scope>
   </dependency>
</dependencies>

Step 5 – Create the tests

Creating an instance of the Remote WebDriver and passing the selenium endpoint and chrome options defined in it.

To run a Remote WebDriver client, we first need to connect to the RemoteWebDriver. We do this by pointing the URL to the address of the server running our tests. In order to customize our configuration, we set desired capabilities. Below is an example of instantiating a remote WebDriver object pointing to our remote web server running our tests on Chrome.

HelperClass

This class contains the initialization of the Remote web driver and the closing of the web driver.

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;


public class HelperClass {

	protected static ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<RemoteWebDriver>();
    public static String remote_url = "http://localhost:4446";

    @BeforeMethod
    public void setDriver() throws MalformedURLException {
    	
        ChromeOptions options = new ChromeOptions();
        driver.set(new RemoteWebDriver(new URL(remote_url), options));
        driver.get().get("https://opensource-demo.orangehrmlive.com/");
        driver.get().manage().window().maximize();

        driver.get().manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
        WebDriverWait wait = new WebDriverWait(driver.get(), Duration.ofSeconds(10));
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='divUsername']/span")));
    }

    public WebDriver getDriver() {
        return driver.get();
    }

    @AfterMethod
    public  void closeBrowser() {
        driver.get().quit();
        driver.remove();
    }
}

Selenium4GridTest

This class contains all the tests like login test, invalid credential, verify heading of the login page, verify LinkedIn link on the login page, and verify the heading of Forgot Password page.

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.openqa.selenium.By;
import org.testng.annotations.Test;

public class Selenium4GridTest extends HelperClass{

	    @Test
	    public void invalidCredentials() {
	    	
	        getDriver().findElement(By.xpath("//*[@id='txtUsername']")).sendKeys("1234");
	        getDriver().findElement(By.xpath("//*[@id='txtPassword']")).sendKeys("12342");
	        getDriver().findElement(By.xpath("//*[@id='btnLogin']")).click();
	        String actualErrorMessage = getDriver().findElement(By.xpath("//*[@id='spanMessage']")).getText();
	        System.out.println("Actual ErrorMessage :" + actualErrorMessage);
	        assertEquals(actualErrorMessage,"Invalid credentials");

	    }

	    @Test
	    public void loginPageHeading() {

	        String loginText = getDriver().findElement(By.xpath("//*[@id='logInPanelHeading']")).getText();
	        System.out.println("Actual loginText :" + loginText);
	        assertEquals(loginText,"LOGIN Panel");

	    }

	    @Test
	    public void forgotPasswordPageHeading()  {

	        getDriver().findElement(By.xpath("//*[@id='forgotPasswordLink']/a")).click();
	        String forgetPasswordTitle= getDriver().findElement(By.xpath(" //*[@id='content']/div[1]/div[2]/h1")).getText();
	        System.out.println("Actual Page Title of Forgot Password Page :" + forgetPasswordTitle);
	        assertEquals(forgetPasswordTitle,"Forgot Your Password?");
	    }

	    @Test
	    public void verifyLinkedIn() {

	        Boolean linkedInIcon = getDriver().findElement(By.xpath("//*[@id='social-icons']/a[1]/img")).isEnabled();
	        System.out.println("Actual linkedIn Text :" + linkedInIcon);
	        assertTrue(linkedInIcon);

	    }
	}

Step 6 – Create a testng.xml

It is very easy to create testng.xml for Eclipse IDE. Right-click on the project -> TestNG -> Convert to TestNG.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test thread-count="5" name="Test">
    <classes>
      <class name="org.example.Selenium4GridTest"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Step 7 – Execute the tests through the command line

To run it from the command prompt, open a command prompt and go to the project and run the following command:

mvn clean test

Step 8 – Execute the tests from testng.xml

We can right-click on testng.xml, and select Run As -> TestNG Suite.

Step 9 – Navigate to the sessions tab on the Selenium Grid UI upon running the command.

It would reflect an active session.

Step 10 – Review the test execution result

The logs can be viewed in the command prompt as shown below:

Step 11 – TestNG Report Generation

TestNG generates the test reports in test-output folder.

We are interested in index.html report. This report contains various information, like time taken by each step in the test, time taken by each test, testng.xml, and number of tests passed or failed.

Emailable-Report.html

The output reports in TestNG reporting look like below as all tests are passed:

Congratulations!! We are able to run Selenium 4 tests on the new Selenium 4 Grid. Happy Learning!!

Leave a comment