How to run parameterized Selenium test using JUnit5

HOME

The previous tutorial has shown the various parameterized tests in JUnit5. This tutorial shows how to run a test multiple times with a different set of data. This helps to reduce the duplication of code. This is a very common scenario in any testing. Imagine, we want to test the requirement for a login page that uses a username and password to log in to the application. Username and password must satisfy some conditions like username can be only alphabets and no numeric and special characters. There could be multiple sets of data that can be used to test this requirement.

Pre-Requisite:

  1. Selenium – 3.141.59
  2. Maven
  3. Java 11
  4. JUnit Jupiter Engine – 5.8.2
  5. JUnit Jupiter API- 5.8.2

JUnit5 provides a lot of ways to parameterize a test – @ValueSource, @EnumSource, @MethodSource, @CsvSource, @CsvFileSource, and @ArgumentsSource.

Let us see an example where the test is not parameterized. In the below example, we want to verify the different error messages generated by passing incorrect values to username and password.

This is the base class – Login which contains the test method that uses a different set of test data.

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

public class LoginPage {

    WebDriver driver ;

    @FindBy(name="txtUsername")
    WebElement username;

    @FindBy(name="txtPassword")
    WebElement password;

    @FindBy(id="btnLogin")
    WebElement loginButton;

    @FindBy(id="spanMessage")
    WebElement actualErrorMessage;


    public LoginPage(WebDriver driver) {

        this.driver = driver;

        // This initElements method will create all WebElements
        PageFactory.initElements(driver, this);
    }

    public void setUserName(String strUserName) {
        username.sendKeys(strUserName);
    }

    // Set password in password textbox
    public void setPassword(String strPassword) {
        password.sendKeys(strPassword);
    }

    // Click on login button
    public void clickLogin() {
        loginButton.click();
    }

    // Get the error message
    public String getErrorMessage() {
        return actualErrorMessage.getText();
    }

    public void login(String strUserName, String strPasword) {

        // Fill user name
        this.setUserName(strUserName);

        // Fill password
        this.setPassword(strPasword);

        // Click Login button
        this.clickLogin();
    }

}

The below example shows 4 tests using a common test with 4 different sets of data.

import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NonParameterizedLoginTest  {

    WebDriver driver;
    LoginPage login;

    @BeforeEach
    void setUp() {

        WebDriverManager.chromedriver().setup();
        ChromeOptions chromeOptions = new ChromeOptions();
        driver = new ChromeDriver(chromeOptions);
        driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/");

    }

    @Test
    void invalidCredentials1() {

        login = new Login(driver);
        login.login("Admin","Admin");
        String actualErrorMessage = login.getErrorMessage();
        assertEquals("Invalid credentials", actualErrorMessage);

    }

    @Test
    void invalidCredentials2() {

        login = new Login(driver);
        login.login("","Admin");
        String actualErrorMessage = login.getErrorMessage();
        assertEquals("Username cannot be empty", actualErrorMessage);

    }

    @Test
    void invalidCredentials3() {

        login = new Login(driver);
        login.login("Admin","");
        String actualErrorMessage = login.getErrorMessage();
        assertEquals("Password cannot be empty", actualErrorMessage);

    }

    @Test
    void invalidCredentials4() {

        login = new Login(driver);
        login.login("","");
        String actualErrorMessage = login.getErrorMessage();
        assertEquals("Username cannot be empty", actualErrorMessage);

    }


    @AfterEach
    void tearDown() {
        if (driver != null) {
            driver.close();
        }
    }
    
}

We can see that the same method is called multiple times. This is a duplication of code. The output of the above program is

Now, we will parametrize the same test. To do so, we need to add a dependency to the 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>org.example</groupId>
    <artifactId>JUnit5Demo</artifactId>
    <version>1.0-SNAPSHOT</version>

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

    <dependencies>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>

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

        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>5.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>

                <dependencies>
                    <dependency>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <version>5.8.2</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

There are multiple ways to parameterize the test. To start with:

  1. Replace @Test annotation with @ParameterizedTest annotation provided by the JUnit5 framework.
  2. Add parameters to the loginTest() method. In this example, we will add a username and a password parameter.
  3. Add the parameters source. In this example, we will use the @CsvFileSource annotation.

In this example, will retrieve the data from CSV. This CSV file is placed under src/test/resources. Below is the example of the credentials.csv file.

To know all the different types of parameterization methods, please refer to this tutorial. This tutorial will show the 2 most common ways to parameterize tests in JUnit5.

  1. @CsvSource

@CsvSource allows us to express argument lists as comma-separated values (i.e., CSV String literals). Each string provided via the value attribute in @CsvSource represents a CSV record and results in one invocation of the parameterized test. An empty, quoted value (”) results in an empty String. This can be seen in the below example.

import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class ParameterizedLoginPageTest {

    WebDriver driver;

    LoginPage loginPage;

    @BeforeEach
     void setUp() {

        WebDriverManager.chromedriver().setup();
        ChromeOptions chromeOptions = new ChromeOptions();
        driver = new ChromeDriver(chromeOptions);
        driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/");

    }

    @ParameterizedTest
    @CsvSource({
            "admin123,admin123,Invalid credentials",
            "'',admin123,Username cannot be empty",
            "Admin,'',Password cannot be empty",
            "'','',Username cannot be empty"
    })

    void invalidCredentials1(String username, String password, String errorMessage) {

        loginPage = new LoginPage(driver);
        loginPage.login(username,password);
        String actualErrorMessage = loginPage.getErrorMessage();
        assertEquals(errorMessage, actualErrorMessage);

    }

    @AfterEach
     void tearDown() {
        driver.close();
    }
}

The output of the above program is

2. @CsvFileSource

@CsvFileSource lets us use comma-separated value (CSV) files from the classpath or the local file system.

We can see in the below example, that we have skipped the first line from the credentials.csv file as it is the heading of the file. invalidCredentials() method got 4 different set of the test data from CSV file using parameterization. JUnit5 ignores the headers via the numLinesToSkip attribute.

In @CsvFileSource, an empty, quoted value (“”) results in an empty String in JUnit5.

import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class ParameterizedLoginPageTest {

    WebDriver driver;

    LoginPage loginPage;

    @BeforeEach
     void setUp() {

        WebDriverManager.chromedriver().setup();
        ChromeOptions chromeOptions = new ChromeOptions();
        driver = new ChromeDriver(chromeOptions);
        driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/");

    }

    @ParameterizedTest
    @CsvSource({
            "admin123,admin123,Invalid credentials",
            "'',admin123,Username cannot be empty",
            "Admin,'',Password cannot be empty",
            "'','',Username cannot be empty"
    })


    @ParameterizedTest
    @CsvFileSource(files = "src/test/resources/credentials.csv", numLinesToSkip = 1)
    void invalidCredentials(String username, String password, String errorMessage) {

        loginPage = new LoginPage(driver);
        loginPage.login(username,password);
        String actualErrorMessage = loginPage.getErrorMessage();
        assertEquals(errorMessage, actualErrorMessage);

    }


    @AfterEach
     void tearDown() {
        driver.close();
    }
}
     

The result of the above program is

Congratulations!! We have seen how Selenium tests are parameterized in JUnit5. Happy Learning.

Run Selenium Tests in GitLab CI/CD

HOME

This tutorial explains the process to run the Selenium Tests in GitLab pipeline. This is a very important steps towards achieving CI/CD. Ideally, the tests need to run after any change (minor/major) before merging the latest change to master branch. Suppose there are 100 changes merged to the master branch in a day and it is expected to run the tests every time before deployment. In this case, any QA won’t want to start the tests manually 100 times in a day. Now, what should be done to overcome this problem. Now, adding tests to GitLab pipeline comes to picture. We can add a test stage to the pipeline and the tests will run automatically when the pipeline run.

Pre-Requisite:

  1. Selenium
  2. TestNG/JUnit (for Assertions)
  3. Java 11
  4. Maven/ Gradle
  5. GitLab Account

What is GitLab CI/CD Workflow?

Once the proposed changes are built, then push the commits to a feature branch in a remote repository that’s hosted in GitLab. The push triggers the CI/CD pipeline for your project. Then, GitLab CI/CD runs automated scripts (sequentially or in parallel) to build as well as to test the application. After successful run of the tests scripts, GitLab CI/CD deploys your changes automatically to any environment (DEV/QA/UAT/PROD) . But if the test stage is failed in the pipeline, then the deployment is stopped.

After the implementation works as expected:

  • Get the code reviewed and approved.
  • Merge the feature branch into the default branch.
    • GitLab CI/CD deploys your changes automatically to a production environment.

To use GitLab CI/CD, we need to keep 2 things in mind:

a) Make sure a runner is available in GitLab to run the jobs. If there is no runner, install GitLab Runner and register a runner for your instance, project, or group.

b) Create a .gitlab-ci.yml file at the root of the repository. This file is where CI/CD jobs are defined.

The Selenium tests run on headless browser in pipeline.

What is headless browser?

A headless browser is like any other browser, but without a Head/GUI (Graphical User Interface).  A headless browser is used to automate the browser without launching the browser. While the tests are running, we could not see the browser, but we can see the test results coming on the console.

To explain, I have created 2 Selenium tests and used TestNG for asserting the tests. The tests will run on headless Chrome browser. One more thing to keep in mind that when tests run on headless Chrome browser, the window screen won’t be full screen. So, the screen needs to be maximized explicitly otherwise some of the tests would fail.

Step 1 – Create a new Maven Project

Step 2- Add the below mentioned pom.xml that shows all the dependencies need to add to the project

 <dependencies>

        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>5.1.0</version>
        </dependency>

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

        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.5</version>
            <scope>test</scope>
        </dependency>
                   
    </dependencies>
    <build>
     <plugins>
     
     <!--  Compiler Plugin -->
    
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
           <source>11</source>
           <target>11</target>
        </configuration>
    </plugin>
     
      <!--  Plugin used to execute tests -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M5</version>
        <configuration>
          <suiteXmlFiles>
            <suiteXmlFile>testng.xml</suiteXmlFile>
          </suiteXmlFiles>
        </configuration>
      </plugin>
     </plugins>
  </build>
</project>

As explained in one of the previous tutorial, it is needed to add maven-surefire-plugin to run the TestNG tests through commandline.

Step 3 – Create the Test Code

This is the BaseTest Class where the webdriver is initialized , headless mode, full screen and at the end close the webdriver.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

import io.github.bonigarcia.wdm.WebDriverManager;

public class BaseTest {
	
	WebDriver driver;
	
	@BeforeMethod
	public void beforeTests() {
        WebDriverManager.chromedriver().setup();
        ChromeOptions options=new ChromeOptions();
        options.setHeadless(true);
        options.addArguments("window-size=1920,1200");
        driver=new ChromeDriver(options);
        driver.get("https://opensource-demo.orangehrmlive.com/");
    }

	@AfterMethod
    public void afterTests() {
        driver.quit();
    }

}

There are 2 different pages which need to be tested – LoginPage and ForgetPasswordPage

LoginPage contain the tests to login to the application. After successful login, the application moves to the next webpage – HomePage. You can see that BaseTest class is extended in both the Test classes.

import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.Test;

@Test
public class LoginPage extends BaseTest{
	
	@Test
	public void validCredentials() throws InterruptedException {

	        driver.findElement(By.name("txtUsername")).sendKeys("Admin");	        
	        driver.findElement(By.name("txtPassword")).sendKeys("admin123");
	        driver.findElement(By.id("btnLogin")).click();
	         String newPageText = driver.findElement(By.xpath("//*[@id='content']/div/div[1]/h1")).getText();
	        System.out.println("newPageText :" + newPageText);
	        Assert.assertEquals(newPageText,"Dashboard");

	}

}

ForgetPasswordPage

import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.Test;

@Test
public class ForgetPasswordPage extends BaseTest{
	
	@Test
	public void getHeading() {
		
		Thread.sleep(1000);
		driver.findElement(By.xpath("//*[@id='forgotPasswordLink']/a")).click();
		String heading = driver.findElement(By.xpath("//*[@id='content']/div[1]/div[2]/h1")).getText();
		System.out.println("Title : "+ heading );
		Assert.assertEquals(heading, "Forgot Your Password?");
	}
	
}

Step 4 – Create testng.xml to run the tests

Now, lets create a testng.xml to run the TestNG tests. If JUnit is used instead of TestNG, then this step is not needed.

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

Step 5 – Run the tests through commandline

Now, let us execute the tests through commandline. Go to the place where pom.xml of the project is placed and use the below command to run the tests. This step make sure that all the test are running as expected.

mvn compile test

GitLab Section

Step 6 – Create a blank project in GitLab

To know, how to create a blank new project in GitLab, please refer this tutorial.

Step 7 – Push the project from local repository to Gitlab Repository

To know, how to push the changes in GitLab, please refer this tutorial.

Step 8 – Create a .gitlab-ci.yml file in the project in GitLab

There are many ways to create a new file in GitLab. One of the way is to create file as shown in the below image.

It is a YAML file where you configure specific instructions for GitLab CI/CD. In the .gitlab-ci.yml, we can define:

  • The scripts you want to run.
  • Other configuration files and templates you want to include.
  • Dependencies and caches.
  • The commands you want to run in sequence and those you want to run in parallel.
  • The location to deploy your application to.
  • Whether you want to run the scripts automatically or trigger any of them manually.
image: markhobson/maven-chrome

stages:
  - test

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

test:
  stage: test
  allow_failure: true

# Run the tests  
  script:
    - mvn $MAVEN_OPTS clean package
    - mvn compile test

# Store artifacts
  artifacts:
    when: always
    name: "report"
    paths:
    - target/surefire-reports/*
    expire_in: 1 h

Image – markhobson/maven-chrome is used in this test. It is a docker image for Java automated UI tests.

This gitlab-ci.yml has only 1 stage – test that contains the command to run the tests as well as also create an artifact that contains all the surefire reports which can be saved as Test Evidence.

Step 9 – Run the tests in GitLab pipeline

Now, when a new change is committed, a pipeline kicks off and it runs all the tests.

Step 10 – Check the status of pipeline

Once the Status of pipeline changes to either failed or passed.. that means the tests are already executed.

As you can see the Status is failed here that means that the execution is completed. Lets see the logs of the execution and it shows that out of 2 tests, 1 test passed and 1 test failed. This shows that tests are running successfully in GitLab pipeline.

As I have added an artifact also in the gitalb-ci.yml, that is highlighted in the image. This artifact creates a folder with name “report” and the reports in this folder comes from the path /target/surefire-reports. This artifact gives us an option to download the reports or browse the report. This report will be available for 1 hour only as mentioned in the gitlab-ci.yml.

Step 11 – Download the report

Once, will click on download button, it will download “report.zip”. Unzip the folder and it looks like something as shown below:

Example of Emailable-Report.html

Example of Index.html

Congratulations. This tutorial has explain the steps to run Selenium tests in GitLab CI/CD. Happy Learning!!

Run TestNG tests from Command Line

HOME

The previous tutorial has explained the Integration of Selenium with TestNG and the tests are executed through either TestNG Suite or testng.xml. This tutorial explains the steps to run the TestNG Tests through the command line.

Pre-Requisite

  1. Selenium
  2. TestNG
  3. Maven
  4. Java 11
  5. Maven Compiler Plugin
  6. Maven Surefire Plugin

Imagine we need to run the TestNG Tests in CI/CD pipelines like Jenkins or GitLab, then we can’t right click and select TestNG Suite or tesng.xml to run the tests. In such situations, the tests can be executed through command line.

We need to add plugins to pom.xml to compile the test code and then run the tests. To know more about Maven Surefire Plugin for TestNG, refer this blog.

 <build>
      <plugins>

         <!--  Compiler Plugin -->
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
               <source>11</source>
               <target>11</target>
            </configuration>
         </plugin>
         
         <!--  Plugin used to execute tests -->
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
               <suiteXmlFiles>
                  <suiteXmlFile>testng.xml</suiteXmlFile>
               </suiteXmlFiles>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

It is needed to add testng.xml to suiteXmlFile to start the execution of the tests.

<suiteXmlFiles>
       <suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>

Create sample class which has @Test methods. In the example below we have created a class as below:

import static org.testng.Assert.assertTrue;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestNGRunFromCommandLine {
	
	 WebDriver driver;
	 
	    @BeforeTest
	    public void setUp() {
	        System.setProperty("webdriver.gecko.driver",
	                "C:\\Users\\Vibha\\Software\\geckodriver\\geckodriver.exe");
	 
	        driver = new FirefoxDriver();
	        driver.get("https://opensource-demo.orangehrmlive.com/");
	 
	        driver.manage().window().maximize();
	    }
	 
	    @Test(description = "This test validates title of login functionality", priority = 0)
	    public void verifyLoginPage() {
	 
	        String expectedTitle = driver.findElement(By.xpath("//*[@id='logInPanelHeading']")).getText(); 
	        System.out.println("Title :" + expectedTitle);
	        assertTrue(expectedTitle.equalsIgnoreCase("LOGIN Panel"));
	    }
	 
	    @Test(description = "This test validates  successful login to Home page", priority = 1)
	    public void verifyHomePage() {
	 
	        System.out.println("Username Entered");
	        driver.findElement(By.name("txtUsername")).sendKeys("Admin");
	 
	        System.out.println("Password Entered");
	        driver.findElement(By.name("txtPassword")).sendKeys("admin123");
	         
	        driver.findElement(By.id("btnLogin")).submit();        
 
	        String newPageText = driver.findElement(By.xpath("//*[@id='content']/div/div[1]/h1")).getText();
	        System.out.println("newPageText :" + newPageText);
	        assertThat(newPageText, containsString("Dashboard"));
	    }
	 
	    @AfterTest
	    public void teardown() {
	 
	        driver.quit();
	    }
	}

The below is the testng.xml file, which will execute all the tests that are available under ‘TestNGRunFromCommandLine‘ class.

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

Below commands are used to execute ‘testng.xml’ file from command line. First, we need to go the place where pom.xml of the project is placed. Then use the mvn compile test to compile the code and execute the TestNG tests.

cd C:\Users\Vibha\Projects\Vibha_Personal\ParallelTestsTestNG
mvn compile test

After executing above command, it should execute the tests that we have specified in testng.xml file. Below is the screen shot after the execution of the tests.

This execution generate various TestNG Reports. We are concerned about emailable-report.html and index.html.

Emailable-Report.html

Emailable report is a type of summary report that one can transfer to other people in the team through any medium. Click on option “emailable-report.html”. Click on option web browser. The output reports in TestNG reporting will looks like below:

Index.html

Index report contains the index-like structure of different parts of the report, such as failed tests, test file, passed test, etc.

Right click on the index.html from the project directory. Select option open with web browser option.

The result will look like this:

Congratulations. This tutorial has explain running the tests of TestNG using Command Line. Happy Learning!!

How to run Edge tests in headless mode in Selenium4

HOME

This tutorial explains the steps to run the Selenium tests for Chrome browser and Firefox in headless mode. We are going to run the tests in Selenium 4.

There are 2 ways to add dependencies to the Selenium project.

Manually add the dependencies to the project

Download Selenium Version from here

Download Microsoft Edge Binary from here

Download the latest version of WebDriverManager

Once the Selenium and WebDriverManager folders are downloaded, unzip the folder. Once the zip file is extracted, reference these jar files in the project. For this, navigate to project properties and click Build Path-> Configure Build Path in Eclipse. Click “Add External Jars“. After clicking on the “Add External JARs“, selected all the extracted JARs. The JARs files are present in the project.

Add the below dependencies to pom.xml or build.gradle

Selenium 4

 <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.1.2</version>
</dependency>

What is headless browser?

A headless browser is like any other browser, but without a Head/GUI (Graphical User Interface).  A headless browser is used to automate the browser without launching the browser. While the tests are running, we could not see the browser, but we can see the test results coming on the console.

We know that to execute Selenium automation scripts on browsers like edge, we must download the binary files of EDGE driver – msedgedriver. After this, we need to set the path to these binaries in the automation script or add the classpath location. Here, we want to execute Selenium WebDriver automation scripts on the Microsoft Edge browser, then you need first to download msedgedriver.exe and then use the System.setProperty  method to set its path as follows:

		// Set the path of EdgeDriver
		System.setProperty("webdriver.edge.driver",
				"C:\\Users\\Vibha\\Software\\edgedriver_win64\\msedgedriver.exe");

The complete program looks like as shown below:

import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;

public class EdgeHeadlessInSelenium4 {

	public static void main(String[] args) {
		// Set the path of EdgeDriver
		System.setProperty("webdriver.edge.driver",
				"C:\\Users\\Vibha\\Software\\edgedriver_win64\\msedgedriver.exe");

		// Create an object of Edge Options class
		EdgeOptions edgeOptions = new EdgeOptions();

		// pass the argument –headless to Edge Options class.
		edgeOptions.addArguments("--headless");

		// Create an object of WebDriver class and pass the Edge Options object as
		// an argument
		WebDriver driver = new EdgeDriver(edgeOptions);

		System.out.println("Executing Edge Driver in Headless mode..");
		driver.get("https://duckduckgo.com/");

		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL  : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}

}

How to run headless Microsoft Edge Tests in Selenium using WebDriverManager?

WebDriverManager

<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>5.1.0</version>
</dependency>

WebDriverManager has an automated way to download browser executables(exes) or binaries. It supports different browsers like Chrome, Firefox, Microsoft Edge, Internet Explorer, Opera, or PhantomJS.

WebDriverManager.edgedriver().setup: checks for the latest version of the specified WebDriver binary. If the binaries are not present on the machine, then it will download the WebDriver binaries. Next, it instantiates the Selenium WebDriver instance with the EdgeDriver.

import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class EdgeHeadlessWithWebDriverManagerInSelenium4 {

	public static void main(String[] args) {

		// WebDriverManager downloads Edge browser executables or binaries.
		WebDriverManager.edgedriver().setup();

		// Create an object of Edge Options class
		EdgeOptions edgeOptions = new EdgeOptions();

		// pass the argument –headless to Edge Options class.
		edgeOptions.addArguments("--headless");

		// Create an object of WebDriver class and pass the Edge Options object as
		// an argument
		WebDriver driver = new EdgeDriver(edgeOptions);

		System.out.println("Executing Edge Driver in Headless mode..");

		driver.get("https://www.bing.com/");
		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}
}

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!

How to disable infobar warning for Chrome tests in Selenium

HOME

This tutorial explains the steps to disable infobar warning generated by Selenium for running tests in Chrome. Selenium tests run on Chrome shows a warning message – “Chrome is being controlled by automated test software as shown in the below image.”

We want to run the Selenium tests on Chrome, but without above shown warning message. This can be achieved by using excludeSwitches.

chromeOptions.setExperimentalOption("excludeSwitches", Arrays.asList("enable-automation"));

The complete program is shown below:

import java.util.Arrays;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class ChromeDisableInfobars {

	public static void main(String[] args) {

		WebDriverManager.chromedriver().setup();

		// Create an object of Chrome Options class
		ChromeOptions chromeOptions = new ChromeOptions();

		// prevents Chrome from displaying the notification 'Chrome is being controlled
		// by automated software'
		chromeOptions.setExperimentalOption("excludeSwitches", Arrays.asList("enable-automation"));

		// Create an object of WebDriver class and pass the Chrome Options object as an
		// argument
		WebDriver driver = new ChromeDriver(chromeOptions);

		driver.get("https://duckduckgo.com/");

		System.out.println("Title of Page :" + driver.getTitle());

		// close the browser
		driver.quit();

	}
}

We are done. Congratulations!! Happy Learning.

How to run Firefox tests in headless mode in Selenium

HOME

This tutorial explains the steps to run the Selenium tests on Firefox browser in headless mode. We are going to run the tests in Selenium. To run the Selenium tests on Chrome browser in headless mode, refer this tutorial.

To start with, we need to add dependencies to the project.

Manually add the dependencies to the project

Download Selenium Version from here

Download Firefox Binary from here – Version 97.0.1

Download the latest version of WebDriverManager (Download this if you want to use WebDriverManager to download browser executables(exes) or binaries automatically, then skip downloading FireFox Binary).

Add the below dependencies to pom.xml or build.gradle.

Selenium 3

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>

What is headless browser?

A headless browser is like any other browser, but without a GUI (Graphical User Interface).  A headless browser is used to automate the browser without launching the browser. While the tests are running, we could not see the browser, but we can see the test results coming on the console. This makes the test execution faster than normal execution. This is suitable for parallel testing as UI tests needs a lot of memory and resources.

The path of Gecko Driver (used for Firefox browser) needs to be set up in the Test using System.setProperty().Here, we use the methods setHeadless (true) of the FirfoxOptions class provided by Selenium WebDriver.

The complete program looks like as shown below:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

public class FirefoxOptionsHeadless1 {

	public static void main(String[] args) {

		// Set the path of GeckoDriver
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver\\geckodriver.exe");

		// Create an object of Firefox Options class
		FirefoxOptions options = new FirefoxOptions();

		// Set Firefox Headless mode as TRUE
		options.setHeadless(true);

		// Create an object of WebDriver class and pass the Firefox Options object
		// as an argument
		WebDriver driver = new FirefoxDriver(options);

		// Navigate to site url
		driver.get("https://duckduckgo.com/");

		System.out.println("Executing Firefox Driver in Headless mode..");
		System.out.println("Page Title : " + driver.getTitle());
		System.out.println("Page URL  : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();
	}
}

How to run headless Firefox Tests in Selenium using WebDriverManager?

WebDriverManager

<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>5.1.0</version>
</dependency>

WebDriverManager.firefoxdriver().setup(): checks for the latest version of the specified WebDriver binary. If the binaries are not present on the machine, then it will download the WebDriver binaries. In this case, it is not needed to download Firefox binary and set up the path

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class FirefoxOptionsHeadless2 {

	public static void main(String[] args) {

		WebDriverManager.firefoxdriver().setup();

		// Create an object of Firefox Options class
		FirefoxOptions options = new FirefoxOptions();

		// Set Firefox Headless mode as TRUE
		options.setHeadless(true);

		// Create an object of Firefox Driver class and pass the Firefox Options object
		// as an argument
		WebDriver driver = new FirefoxDriver(options);

		// Navigate to the url
		driver.get("https://duckduckgo.com/");

		System.out.println("Executing Firefox Driver in Headless mode..");
		System.out.println("Page Title : " + driver.getTitle());
		System.out.println("Page URL  : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();
	}

}

Congratulations!! We have run the tests in headless mode in FireFox.

Parallel testing of DataProviders in TestNG

HOME

The previous tutorial has explained the DataProviders in TestNG. The DataProvider in TestNG is a way to pass the parameters in the test functions. Using DataProvider in TestNG, we can easily inject multiple values into the same test case. It comes inbuilt in TestNG and is popularly used in data-driven frameworks.

 It is an option for the parallel execution of tests in TestNG. 

It is advisable to create 2 classes – one class contains the Test cases and another class define TestNG parameters – DataProviders.

Let us create a class for the DataProvider method with all the Test Data as shown below:

import org.testng.annotations.DataProvider;

public class DataProviderDemo {	
	
	 @DataProvider(name = "testData", parallel=true)
	 public Object[][] dataProvFunc() {
	       return new Object[][] {           
	    	   {"","","Username cannot be empty"},    	  
	    	   {"","Test","Username cannot be empty"},
	    	   {"$%1234","2345%$","Invalid credentials"}          
	    	 };
	    }
	}

 An extra parameter “parallel” is required to initiate parallel execution in TestNG using dataprovider.

Below is the test which uses the parameter from dataprovider and run the tests parallelly.

A new ThreadLocal is instantiated for each test class since it’s in the BeforeClass annotation.

private static final ThreadLocal<WebDriver> WEB_DRIVER_THREAD_LOCAL = new ThreadLocal<WebDriver>();

Below is the complete test code:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class DataProviderParallelTests {
	
	public WebDriver driver;
	private static final ThreadLocal<WebDriver> WEBDRIVER_THREADLOCAL = new ThreadLocal<WebDriver>();
	
	 @BeforeMethod
    public void setUp(){

        System.setProperty("webdriver.chrome.driver",
                "C:\\Users\\Vibha\\Software\\chromedriver\\chromedriver.exe");
        driver = new ChromeDriver();
        WEBDRIVER_THREADLOCAL.set(driver);
        System.out.println("Before method Thread Id:" + Thread.currentThread().getId());
        
    }
	
	@Test(dataProvider = "testData", dataProviderClass = DataProviderDemo.class)
    public void invalidLoginTest(String username, String password, String errorMessage) throws InterruptedException {
		     
	    driver = WEBDRIVER_THREADLOCAL.get();
	    driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/");
     
        Thread.sleep(2000);
        driver.findElement(By.name("txtUsername")).sendKeys(username);
        System.out.println("Username :" + username);
        
        Thread.sleep(2000);
        driver.findElement(By.name("txtPassword")).sendKeys(password);
        System.out.println("password :" + password);
        
        Thread.sleep(2000);
        String expectedError = driver.findElement(By.id("spanMessage")).getText();
        System.out.println("Error Message :" + expectedError);
        Assert.assertTrue(expectedError.contains(errorMessage));

    }
		 
	@AfterMethod
	public void tear_down() {
		 
		 WebDriver driver = WEBDRIVER_THREADLOCAL.get();
		 System.out.println("After method Thread Id:" + Thread.currentThread().getId());
	        if (driver != null) {
	            driver.quit();
	     }
    }	
}

testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite" thread-count="2" data-provider-thread-count="2">
  <test name="Test">
    <classes>
      <class name="DataProvider.DataProviderParallelTests"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

In this file, data-provider-thread-count is set to 2, then two browsers will be opened and the first two tests will run from the list. 

Run the test script from testng.xml, Right-Click on the XML, and select Run As -> TestNG Suite.

The execution status shown below shows that 2 threads are active at a time, which execute 2 set of dataprovider parameters – Thread 14 and Thread 15. Once the tests are finished for Thread 14 and Thread 15, they are closed and a new Thread 15 again initiated to start test execution of 3rd parameter.

TestNG generates multiple test reports under folder test-output. We are mainly concerned about 2 reports – emailable-report.html and index.html.

Emailable-report.html

Emailable reports are a type of summary reports that one can transfer to other people in the team through any medium. 

Index.html

Index report contains the index-like structure of different parts of the report, such as failed tests, test files, passed tests, etc. We can divide this report into two parts. The left part contains the index, and this is the reason it is called an index report, while the right part contains the explored content of that index.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

How to run Selenium Tests using on Internet Explorer

HOME

Internet Explorer is going away in near future. But still it is a browser which holds around 1% of browser market share. When anyone refers to automated browser testing, it somehow means that the testing will be performed on the latest browsers like Chrome, Firefox, etc. But along with these browsers, it is also expected to work on Internet Explorer (IE).

The Internet Explorer driver that is used by Selenium Tests can be downloaded from here.

In order to run the Selenium Tests on IE, it is needed to set the %PATH%.

How to add %PATH%

Go To -> View Advanced System Settings -> Environment Variables ->Clicks on the Path and add the path where IE binary is located on the machine.

How to run tests using Selenium IE driver in Selenium Java?

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;

public class IEDemo {

	public WebDriver driver;

	@Before
	public void setUp() {

		System.setProperty("webdriver.ie.driver",
				"C:\\Users\\Vibha\\Software\\IEDriverServer_x64_2.39.0\\IEDriverServer.exe");

		driver = new InternetExplorerDriver();
	}

	@Test
	public void verifyPageTitle() {

		System.out.println("Opening Internet Explorer Web Browser");
		driver.get("https://www.bing.com/");
		System.out.println("Title of Page : " + driver.getTitle());
		Assert.assertEquals(driver.getTitle(), "Bing");
	}

	@Test
	public void verifyPageUrl() {

		System.out.println("Opening Internet Explorer Web Browser");
		driver.get("https://www.bing.com/");
		System.out.println("URL of Page : " + driver.getCurrentUrl());
		Assert.assertEquals(driver.getCurrentUrl(), "https://www.bing.com/");
	}

	@After
	public void tearDown() {

		// Close the driver
		driver.close();

	}
}

Execution

The string webdriver.ie.driver is set to the location which contains the Selenium IE driver. The InternetExplorerDriver method is used for instantiating the IE driver class.

The test method is implemented under the @Test annotation.

 In the tearDown method, the resources held by IE driver are freed using the close() method in Selenium.

Congratulations!! We are able to open an Internet Explorer browser and perform tests. Happy Learning!!

How to manage driver executables using WebDriverManager

HOME

The traditional way to use any browser in Selenium tests is to download browser binaries and we need to set the path of these files in our script like below or its location should be added to the classpath.

System.setProperty("webdriver.chrome.driver", "/absolute/path/to/binary/chromedriver");

The process of manually downloading and managing these drivers for each operating systems is very painful. We also have to check when new versions of the binaries are released / new browsers versions are released. We should check the compatibility for all the executables and add it.

How to download all the driver executables automatically ???

The automatic download of the drivers can be done by WebDriverManager. WebDriverManager is a library that allows controlling web browsers programmatically. It provides a cross-browser API that can be used to drive web browsers (e.g., Chrome, Edge, or Firefox, among others) using different programming languages (e.g., Java, JavaScript, Python, C#, or Ruby). The primary use of Selenium WebDriver is implementing automated tests for web applications.

The communication between the WebDriver API and the driver binary is done using a standard protocol called W3C WebDriver (formerly the so-called JSON Wire Protocol). Then, the communication between the driver and the browser is done using the native capabilities of each browser.

How To add WebDriverManager to a Selenium project manually?

Download the latest version of WebDriverManager from here.

It will download a zip file. Now extract the jar/zip file. It will show various jar under the folder, as shown below:

Once we extract the zip file, we have to reference these jar files in our project. For this, navigate to project properties and click Build Path-> Configure Build Path in Eclipse

Click “Add External Jars” as per the steps highlighted below to include all the WebDriverManager jars extracted.

After clicking on the “Add External JARs“, all the selected extracted JARs are added to the project.

When this finishes, the project references show these referenced jars in the project explorer as highlighted below, and they are ready to be consumed in the Selenium test scripts.

Chrome

The below code snippet shows a quick usage of WebDriverManager with Chrome:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class Demo {

	public static void main(String[] args) {

		WebDriverManager.chromedriver().setup();

		// Create an object of Chrome Options class
		ChromeOptions chromeOptions = new ChromeOptions();

		// Create an object of WebDriver class and pass the Chrome Options object as
		// an argument
		WebDriver driver = new ChromeDriver(chromeOptions);

		System.out.println("Executing Chrome Driver");

		driver.get("https://www.bing.com/");
		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}
}

FireFox Driver

The below code snippet shows a quick usage of WebDriverManager with FireFox:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class FireFoxDemo {

	public static void main(String[] args) {

		WebDriverManager.firefoxdriver().setup();

		// Create an object of Firefox Options class
		FirefoxOptions firefoxOptions = new FirefoxOptions();

	    // Create an object of WebDriver class and pass the Firefox Options object
		// as an argument
		WebDriver driver = new FirefoxDriver(firefoxOptions);

		System.out.println("Executing Firefox Driver");

		driver.get("https://www.bing.com/");
		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}
}

Microsoft Edge

The below code snippet shows a quick usage of WebDriverManager with Microsoft Edge:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class EdgeDemo {

	public static void main(String[] args) {

		WebDriverManager.edgedriver().setup();

		// Create an object of Edge Options class
		EdgeOptions edgeOptions = new EdgeOptions();

		// Create an object of WebDriver class and pass the Edge Options object
		// as an argument
		WebDriver driver = new EdgeDriver(edgeOptions);

		System.out.println("Executing Microsoft Edge Driver");

		driver.get("https://www.bing.com/");
		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}
}

The basic use of these managers is the following:

WebDriverManager.chromedriver().setup();
WebDriverManager.firefoxdriver().setup();
WebDriverManager.edgedriver().setup();
WebDriverManager.operadriver().setup();
WebDriverManager.chromiumdriver().setup()
WebDriverManager.iedriver().setup();

How To add WebDriverManager to a Selenium project using Maven or Gradle?

To use WebDriverManager in a Maven built project, the below mentioned dependency is needed to add to the pom.xml.

<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>5.1.0</version>
</dependency>

For Gradle project, add the below to the build.gradle.

dependencies {
    testCompile("io.github.bonigarcia:webdrivermanager:5.1.0")
}

How to instantiate a specific browser version using WebDriverManager?

WebDriverManager provides an ability to download specific version of browser. For example, the latest chromedriver version is 100.0.4896.20 (released on 2022-03-04). But if we want an earlier version, say, Chromedriver version 98.0.4758.102, we have to add the following code.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class Demo {

	public static void main(String[] args) {

		WebDriverManager.chromedriver().driverVersion("98.0.4758.102").setup();

		// Create an object of Chrome Options class
		ChromeOptions chromeOptions = new ChromeOptions();

		// Create an object of WebDriver class and pass the Chrome Options object as
		// an argument
		WebDriver driver = new ChromeDriver(chromeOptions);

		System.out.println("Executing Chrome Driver");

		driver.get("https://www.bing.com/");
		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}
}

As we can see from the above screenshot, as a result of executing the above program, the Chromedriver started successfully. We can see the details of starting the chrome driver instance in the first line of output. Here we have set the Chrome version to 98.0.4758.102″.

Congratulations!! We have learnt to download drivers automatically.

How to run Chrome tests in headless mode in Selenium

HOME

This tutorial explains the steps to run the Selenium tests for Chrome browser in headless mode. We are going to run the tests in Selenium 3.

There are 2 ways to add dependencies to the Selenium project.

  1. Manually add the dependencies to the project.

Download Selenium Version from here

Download ChromeDriver Binary

Download the latest version of WebDriverManager

Once the Selenium and WebDriverManager folders are downloaded, unzip the folder. Once the zip file is extracted, reference these jar files in the project. For this, navigate to project properties and click Build Path-> Configure Build Path in Eclipse. Click “Add External Jars“. After clicking on the “Add External JARs“, selected all the extracted JARs. The JARs files are present in the project.

2. Add the below dependencies to pom.xml or build.gradle.

Add below dependencies to the project.

Selenium 3

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>

What is headless browser?

A headless browser is like any other browser, but without a Head/GUI (Graphical User Interface).  A headless browser is used to automate the browser without launching the browser. While the tests are running, we could not see the browser, but we can see the test results coming on the console.

Headless browser testing is generally faster when compared to actual UI testing as it doesn’t wait for the whole page to render before performing any action.

When we need to execute automated test cases remotely on a server or in any of the build and release pipelines for continuous integration servers like Gitlab or Jenkins, it is not always possible to install real browsers on such remote machines. We can use headless browsers to run automation tests efficiently.

It is easy to perform multi-tasking with a Headless browser. The browser or our machine can do anything else while the tests run in the background.

We know that to execute Selenium automation scripts on browsers like chrome or firefox, we must download the binary files of these drivers like chromedriver and geckodriver, etc. After this, we need to set the path to these binaries in the automation script or add the classpath location. Here, we want to execute Selenium WebDriver automation scripts on the Chrome browser, then you need first to download chromedriver.exe and then use the System.setProperty  method to set its path as follows:

	// Set the path of ChromeDriver
	System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver_win32_98.0.4758.102\\chromedriver.exe");

The complete program looks like as shown below:

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ChromeOptionsHeadless1 {

	public static void main(String[] args) {

		// Set the path of ChromeDriver
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\SingVi04\\Vibha\\Software\\chromedriver_win32_98.0.4758.102\\chromedriver.exe");

		// Create an object of Chrome Options class
		ChromeOptions options = new ChromeOptions();

		// pass the argument –headless to Chrome Options class.
		options.addArguments("--headless");

		// Create an object of Chrome Driver class and pass the Chrome Options object as
		// an argument
		ChromeDriver driver = new ChromeDriver(options);

		System.out.println("Executing Chrome Driver in Headless mode..");
		driver.get("https://duckduckgo.com/");

		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL  : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}
}

How to run headless Chrome Tests in Selenium using WebDriverManager?

WebDriverManager

<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>5.1.0</version>
</dependency>

WebDriverManager has an automated way to download browser executables(exes) or binaries. It supports different browsers like Chrome, Firefox, Microsoft Edge, Internet Explorer, Opera, or PhantomJS.

WebDriverManager.chromedriver().setup: checks for the latest version of the specified WebDriver binary. If the binaries are not present on the machine, then it will download the WebDriver binaries. Next, it instantiates the Selenium WebDriver instance with the ChromeDriver.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class ChromeOptionsHeadless2 {

	public static void main(String[] args) {

		// WebDriverManager downloads chrome browser executables or binaries.
		WebDriverManager.chromedriver().setup();

		// Create an object of Chrome Options class
		ChromeOptions options = new ChromeOptions();

		// pass the argument –headless to Chrome Options class.
		options.addArguments("--headless");

		// Create an object of Chrome Driver class and pass the Chrome Options object as
		// an argument
		ChromeDriver driver = new ChromeDriver(options);

		System.out.println("Executing Chrome Driver in Headless mode..");
		driver.get("https://duckduckgo.com/");

		System.out.println("Title of Page :" + driver.getTitle());
		System.out.println("Page URL  : " + driver.getCurrentUrl());

		// Close the driver
		driver.close();

	}

}

Congratulations!! We are able to run Chrome tests in Selenium in headless mode.