Maven Tutorials

HOME

 Chapter 1 Maven – How to install Maven on Window

Eclipse IDE

Chapter 1 Maven – How to create a Java project using Command Line
Chapter 2 Maven – How to create Maven project in Selenium
Chapter 3 Maven – How to import Maven project in Eclipse
Chapter 4 Maven – How to add M2_REPO classpath variable to Eclipse

IntelliJ IDE

Chapter 1 How to create Maven project in IntelliJ
Chapter 2 How to import Java Maven project in IntelliJ
Chapter 3 How to create a Java Maven project using Command Line in IntelliJ

Maven Tutorial – How to create Maven project in Selenium

HOME

Step 2Select the Maven Project and click on the “Next” button.

Step 3You can select the default workplace or mention the location where you want to save the project.

Step 4 – Select maven-archetype-quickstart option as shown below and click on the “Next” button.

Step 5 Provide the Group Id, Artifact Id details and click the “Finish” button.

Step 6 – The structure of the project looks as shown in the below image.

Step 7 – POM file will look like below image

<?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>com.example</groupId>
  <artifactId>SeleniumMaven_Demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>SeleniumMaven_Demo</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

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

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

How to add dependencies to POM.xml file

Step 1 – Please visit website MVN Repository – https://mvnrepository.com/.

Step 2 – Search for Selenium Java in search box.

Step 3 – We will get the “Selenium Java” dependency as shown in the below image.

Step 5 – Copy the content as shown below and paste in pom.xml of the project.

Step 6 – The updated pom.xml will look like the below image.

Step 7 – Save the project. The selenium dependencies will be downloaded automatically and can be seen in Maven Dependencies folder.

Integration of Serenity with Cucumber and JUnit5

HOME

In the previous tutorial, I explained the Serenity BDD with Cucumber for Web Application using Junit4. In this tutorial, I will explain the same Test Framework using Serenity, Cucumber, and JUnit5. This tutorial gives a clear picture of the initial setup of a BDD Framework.

What is JUnit5?

JUnit 5 is composed of several different modules from three different sub-projects.

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

The JUnit Platform serves as a foundation for launching testing frameworks on the JVM. It also defines the TestEngine API for developing a testing framework that runs on the platform.

JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5. The Jupiter sub-project provides a TestEngine for running Jupiter based tests on the platform.

JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform. It requires JUnit 4.12 or later to be present on the class/module path.

JUnit5 is not completely integrated with Serenity with Cucumber. So, it is advisable to use jupiter-vintage-engine for the Cucumber TestRunner classes.

Dependency List:

  1. Serenity – 4.0.28
  2. JUnit Jupiter – 5.10.1
  3. JUnit Vintage – 5.10.1
  4. JUnit Platform Suite – 1.10.1
  5. Cucumber JUnit Platform – 7.15.0
  6. Java 17
  7. Maven – 3.9.5
  8. Maven Compiler Plugin – 3.11.0
  9. Maven Surefire Plugin – 3.2.1
  10. Maven FailSafe Plugin – 3.2.1

Implementation Steps

Step 1- Download and Install Java

Click here to know How to install Java.

Step 2 – Download and setup Eclipse IDE on the system

The Eclipse IDE (integrated development environment) provides strong support for Java developers which is needed to write Java code. Click here to know How to install Eclipse.

Step 3 – Setup Maven and create a new Maven Project

Click here to know How to install Maven.

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – SerenityCucumberJunit5Demo
Version – 0.0.1-SNAPSHOT
Package – com. example. SerenityCucumberJunit5Demo

Step 4 – Update Properties section in Maven pom.xml

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <serenity.version>4.0.28</serenity.version>
        <junit.jupiter.version>5.10.1</junit.jupiter.version>
        <junit.vintage.version>5.10.1</junit.vintage.version>
        <junit-platform-suite.version>1.10.1</junit-platform-suite.version>
        <cucumber-junit-platform-engine.version>7.15.0</cucumber-junit-platform-engine.version>
        <maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <maven.surefire.plugin.version>3.2.1</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.2.1</maven.failsafe.plugin.version>
        <tags></tags>
  </properties>

Step 5 – Add repositories and pluginRepository to Maven pom.xml

 <repositories>
        <repository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>bintray</name>
            <url>https://jcenter.bintray.com</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>bintray-plugins</name>
            <url>https://jcenter.bintray.com</url>
        </pluginRepository>
    </pluginRepositories>

Step 6 – Add Serenity, Serenity Cucumber, and JUnit dependencies to POM.xml

<dependencies>
        <!-- JUnit 5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.jupiter.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>${junit.vintage.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Serenity -->
         <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-core</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>
        
         <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-cucumber</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-screenplay-webdriver</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

     <dependency>
         <groupId>org.junit.platform</groupId>
         <artifactId>junit-platform-suite</artifactId>
         <version>${junit-platform-suite.version}</version>
         <scope>test</scope>
     </dependency>

     <dependency>
         <groupId>io.cucumber</groupId>
         <artifactId>cucumber-junit-platform-engine</artifactId>
         <version>${cucumber-junit-platform-engine.version}</version>
         <scope>test</scope>
     </dependency>

    </dependencies>

Step 7 – Update the Build Section of pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>**/*.java</include>
                    </includes>
                    <parallel>methods</parallel>
                    <useUnlimitedThreads>true</useUnlimitedThreads>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
           <plugin>
               <groupId>net.serenity-bdd.maven.plugins</groupId>
               <artifactId>serenity-maven-plugin</artifactId>
               <version>${serenity.version}</version>
               <dependencies> 
                  <dependency>
                       <groupId>net.serenity-bdd</groupId>
                       <artifactId>serenity-single-page-report</artifactId>
                       <version>${serenity.version}</version>
                  </dependency>                
               </dependencies>
               <configuration>
                   <tags>${tags}</tags>
                   <reports>single-page-html</reports> 
               </configuration>
               <executions>
                  <execution>
                      <id>serenity-reports</id>
                      <phase>post-integration-test</phase>
                      <goals>
                          <goal>aggregate</goal>
                      </goals>
                   </execution>
               </executions>
           </plugin>
        </plugins>
    </build>
</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>com.example</groupId>
  <artifactId>SerenityCucumberJunit5Demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>SerenityCucumberJunit5Demo</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <serenity.version>4.0.28</serenity.version>
        <junit.jupiter.version>5.10.1</junit.jupiter.version>
        <junit.vintage.version>5.10.1</junit.vintage.version>
        <junit-platform-suite.version>1.10.1</junit-platform-suite.version>
        <cucumber-junit-platform-engine.version>7.15.0</cucumber-junit-platform-engine.version>
        <maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <maven.surefire.plugin.version>3.2.1</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.2.1</maven.failsafe.plugin.version>
        <tags></tags>
  </properties>
  
  <repositories>
        <repository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>bintray</name>
            <url>https://jcenter.bintray.com</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>bintray-plugins</name>
            <url>https://jcenter.bintray.com</url>
        </pluginRepository>
    </pluginRepositories>

 <dependencies>
        <!-- JUnit 5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.jupiter.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>${junit.vintage.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Serenity -->
         <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-core</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>
        
         <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-cucumber</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-screenplay-webdriver</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

     <dependency>
         <groupId>org.junit.platform</groupId>
         <artifactId>junit-platform-suite</artifactId>
         <version>${junit-platform-suite.version}</version>
         <scope>test</scope>
     </dependency>

     <dependency>
         <groupId>io.cucumber</groupId>
         <artifactId>cucumber-junit-platform-engine</artifactId>
         <version>${cucumber-junit-platform-engine.version}</version>
         <scope>test</scope>
     </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>**/*.java</include>
                    </includes>
                    <parallel>methods</parallel>
                    <useUnlimitedThreads>true</useUnlimitedThreads>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
           <plugin>
               <groupId>net.serenity-bdd.maven.plugins</groupId>
               <artifactId>serenity-maven-plugin</artifactId>
               <version>${serenity.version}</version>
               <dependencies> 
                  <dependency>
                       <groupId>net.serenity-bdd</groupId>
                       <artifactId>serenity-single-page-report</artifactId>
                       <version>${serenity.version}</version>
                  </dependency>                
               </dependencies>
               <configuration>
                   <tags>${tags}</tags>
                   <reports>single-page-html</reports> 
               </configuration>
               <executions>
                  <execution>
                      <id>serenity-reports</id>
                      <phase>post-integration-test</phase>
                      <goals>
                          <goal>aggregate</goal>
                      </goals>
                   </execution>
               </executions>
           </plugin>
        </plugins>
    </build>
</project>

Step 8 – Create a feature file under src/test/resources

The purpose of the Feature keyword is to provide a high-level description of a software feature, and to group related scenarios. To know more about the Feature file, please refer this tutorial.

Feature: Login to HRM  

   @ValidCredentials
   Scenario: Login with valid credentials
   
    Given User is on Home page
    When User enters username as "Admin"
    And User enters password as "admin123"
    Then User should be able to login successfully
    
    @InValidCredentials    
    Scenario Outline: Login with invalid credentials
   
    Given User is on Home page
    When User enters username as '<username>'
    And User enters password as '<password>'
    Then User should be able to see error message '<errorMessage>'
      
   Examples:
    |username   |password       |errorMessage               |
    |admin        |admin            |Invalid credentials        |
    |abc            |admin123       |Invalid credentials        |
    |abc            |abc123           |Invalid credentials         |
    |1$£"          | 45£"%           |Invalid credentials        |
 
   @ForgetPassword  
   Scenario: Verify Forget Password Functionality
   
    Given User is on Home page
    When User clicks on Forgot your password link
    Then User should be able to see new page which contains Reset Password button

Step 9 – Create junit-platform.properties file under src/test/resources (optional)

This is an optional step. Cucumber of version 6.7 and above provides the functionality to generate a beautiful cucumber report. For this, it is needed to add a file junit-platform.properties under src/test/resources.

cucumber.publish.enabled = true

Step 10 – Create the Step Definition class or Glue Code

A Step Definition is a Java method with an expression that links it to one or more Gherkin steps. When Cucumber executes a Gherkin step in a scenario, it will look for a matching step definition to execute. You can have all of your step definitions in one file, or in multiple files.

LoginPageDefinitions

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.example.SerenityCucumberJunit5Demo.steps.StepDashboardPage;
import com.example.SerenityCucumberJunit5Demo.steps.StepForgetPasswordPage;
import com.example.SerenityCucumberJunit5Demo.steps.StepLoginPage;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import net.serenitybdd.annotations.Steps;


public class LoginPageDefinitions {

	@Steps
	StepLoginPage loginPage;

	@Steps
	StepDashboardPage dashPage;

	@Steps
	StepForgetPasswordPage forgetpasswordPage;

	@Given("User is on Home page")
	public void openApplication() {
		loginPage.open();
	}

	@When("User enters username as {string}")
	public void enterUsername(String userName) {

		loginPage.inputUserName(userName);
	}

	@When("User enters password as {string}")
	public void enterPassword(String passWord) {
		loginPage.inputPassword(passWord);
		loginPage.clickLogin();
	}

	@Then("User should be able to login successfully")
	public void clickOnLoginButton() {
		dashPage.loginVerify();
	}

	@Then("User should be able to see error message {string}")
	public void unsucessfulLogin(String expectedErrorMessage) {
		String actualErrorMessage = loginPage.errorMessage();

		System.out.println("Actual Error Message :" + actualErrorMessage);

		assertEquals(expectedErrorMessage, actualErrorMessage);
	}

	@When("User clicks on Forgot your password link")
	public void clickForgetPasswordLink() {
		loginPage.clickForgetPasswordLink();
	}

	@Then("User should be able to see new page which contains Reset Password button")
	public void verifyForgetPasswordPage() {

		assertTrue(forgetpasswordPage.ForgetPasswordPage());
	}
}

Assertions in JUnit-Vintage Engine are imported from the below package:-

import static org.junit.jupiter.api.Assertions.*;

DashboardPageDefinitions

import com.example.SerenityCucumberJunit5Demo.steps.StepDashboardPage;
import net.serenitybdd.annotations.Step;
import net.serenitybdd.annotations.Steps;

public class DashboardPageDefinitions {

	@Steps
	StepDashboardPage dashPage;

	@Step
	public void verifyAdminLogin() {
		dashPage.loginVerify();
	}
}

The corresponding Test Step classes are – StepLoginPage and StepDashboardPage.

There are multiple ways to identify a web element on the web page – one of the ways is to use @FindBy or $(By.).

I prefer to use @FindBy as I need not find the same element multiple times. Using @FindBy, I have identified a web element and defined a WebElementFacacde for the same which is reusable.

StepLoginPage

import net.serenitybdd.annotations.Step;
import net.serenitybdd.core.annotations.findby.FindBy;
import net.serenitybdd.core.pages.PageObject;
import net.serenitybdd.core.pages.WebElementFacade;


public class StepLoginPage extends PageObject {

	@FindBy(name = "username")
	WebElementFacade username;

	@FindBy(name = "password")
	WebElementFacade password;

	@FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[3]/button")
	WebElementFacade submitButton;

	@FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/div/div[1]/div[1]/p")
	WebElementFacade errorMessage;

	@FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[4]/p")
	WebElementFacade linkText;

	@Step("Enter Username")
	public void inputUserName(String userName) {
		username.sendKeys((userName));
	}

	@Step("Enter Password")
	public void inputPassword(String passWord) {
		password.sendKeys((passWord));
	}

	@Step("Click Submit Button")
	public void clickLogin() {
		submitButton.click();
	}

	@Step("Error Message on unsuccessful login")
	public String errorMessage() {
		String actualErrorMessage = errorMessage.getText();
		System.out.println("Actual Error Message :" + actualErrorMessage);

		return actualErrorMessage;
	}

	@Step("Click Forget Password Link")
	public void clickForgetPasswordLink() {
		linkText.click();

		System.out.println("Clicked on Forgot Password Link");
	}

}

StepDashboardPage

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import net.serenitybdd.annotations.Step;
import net.serenitybdd.core.annotations.findby.FindBy;
import net.serenitybdd.core.pages.PageObject;
import net.serenitybdd.core.pages.WebElementFacade;

public class StepDashboardPage extends PageObject {

	@FindBy(xpath = "//*[@id='app']/div[1]/div[1]/header/div[1]/div[1]/span/h6")
	WebElementFacade dashboardText;

	@Step("Successful login")
	public void loginVerify() {
		String dashboardTitle = dashboardText.getText();
		assertThat(dashboardTitle, containsString("Dashboard"));
	}
}

StepForgetPasswordPage

import net.serenitybdd.annotations.Step;
import net.serenitybdd.core.annotations.findby.FindBy;
import net.serenitybdd.core.pages.PageObject;
import net.serenitybdd.core.pages.WebElementFacade;

public class StepForgetPasswordPage extends PageObject {

	@FindBy(xpath = "//*[@id='app']/div[1]/div[1]/div/form/h6")
	WebElementFacade forgetLink;

	@Step("Verify Forget Password Page ")
	public boolean ForgetPasswordPage() {
		Boolean resetPasswordButton = forgetLink.isDisplayed();

		return resetPasswordButton;
	}
}

Step 11 – Create a Serenity-Cucumber Runner class

Cucumber runs the feature files via JUnit and needs a dedicated test runner class to actually run the feature files. When you run the tests with Serenity, you use the CucumberWithSerenity test runner. You also need to use the @CucumberOptions class to provide the root directory where the feature files can be found.

import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;

import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;

@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("/features")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example.SerenityCucumberJunit5Demo.definitions")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "io.cucumber.core.plugin.SerenityReporterParallel,pretty,timeline:build/test-results/timeline")

public class SerenityRunnerTest {

}

Step 12 – Create serenity.conf file under src/test/resources

The serenity configuration file is used to configure the drivers so the test cases can run successfully. This file contains an operating system-specific binary. The binary file sits between your test and the browser. It acts as an intermediary, an interface between your tests and the browser you are using.

You can also configure the webdriver.base.url property for different environments in the serenity.conf configuration file.

headless.mode = false

webdriver {
  driver = chrome
  capabilities {
    browserName = "chrome"
    acceptInsecureCerts = true
    "goog:chromeOptions" {
      args = ["remote-allow-origins=*","test-type", "no-sandbox", "ignore-certificate-errors", "--window-size=1000,800",
        "incognito", "disable-infobars", "disable-gpu", "disable-default-apps", "disable-popup-blocking",
        "disable-dev-shm-usage", "disable-extensions", "disable-web-security", "disable-translate", "disable-logging"]
    }
  }
}



#
# Define drivers for different platforms. Serenity will automatically pick the correct driver for the current platform
#

environments {
  default {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/"
  }
  dev {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/dev"
  }
  staging {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/staging"
  }
  prod {
    webdriver.base.url = "https://opensource-demo.orangehrmlive.com/prod"
  }
}

Step 13 – Create serenity.properties file at the root of the project

serenity.project.name = Serenity and Cucumber and JUnit5 Demo

Step 14 – Run the tests from Command Line

Open the command line and go to the location where pom.xml of the project is present and type the below command.

mvn clean verify

Step 15 – Test Execution Status

The image displayed above shows the execution status.

The feature file contains 3 test cases. Test Case 2 is a Test Scenario that has 4 examples. So, in total we have 6 tests. This information is clearly mentioned in the new version of Serenity.

Step 16 – Serenity Report Generation

The best part about Serenity is the report generation by it. The Reports contain all possible types of information, you can think of with minimal extra effort. There are multiple types of reports are generated. We are interested in index.html and serenity-summary.html. To know more about Serenity Reports, please refer to tutorials for Index.html and Serenity-Summary.html. Below is the new Serenity Report.

  1. index.html

2. serenity-summary.html

Step 17 – Cucumber Report Generation (Optional)

Every Test Execution generates a Cucumber Report (Version 6.7.0) and above as shown in the image.

Copy the URL and paste it to a browser and it shows the report as shown below:

To know more about Cucumber Reports, refer to this tutorial.

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

How to save Log4j 2 logs in output file using YML file

HOME

 <!-- Log4j Dependency -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>3.0.0-alpha1</version>
    </dependency>

<!-- Jackson Dataformat YAML -->
    <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-yaml</artifactId>
      <version>2.16.0</version>
    </dependency>

<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>com.example</groupId>
  <artifactId>Log4j2_Demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Log4j2_Demo</name>
  <url>http://maven.apache.org</url>

  <properties>
    <selenium.version>4.15.0</selenium.version>
    <testng.version>7.8.0</testng.version>
    <log4j.version>3.0.0-alpha1</log4j.version>
    <jackson.version>2.16.0</jackson.version>
    <maven.compiler.version>3.11.0</maven.compiler.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.surefire.failsafe.version>3.1.2</maven.surefire.failsafe.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencies>

    <!-- TestNG Dependency -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>


    <!-- Log4j Dependency -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j.version}</version>
    </dependency>

    <!-- Selenium Dependency -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium.version}</version>
    </dependency>

    <!-- Jackson Dataformat YAML -->
    <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-yaml</artifactId>
      <version>${jackson.version}</version>
    </dependency>


  </dependencies>

  <build>

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven.surefire.failsafe.version}</version>
        <configuration>
          <skipTests>false</skipTests>
          <skip>false</skip>
          <testFailureIgnore>true</testFailureIgnore>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven.compiler.version}</version>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
          <fork>true</fork>
        </configuration>
      </plugin>
    </plugins>

  </build>

</project>

Configuration:
  status: warn

  appenders:
    Console:
      name: LogToConsole
      PatternLayout:
        Pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"

    File:
      name: File
      fileName: logs/app.log
      PatternLayout:
      Pattern: "%d %p %C{1.} [%t] %m%n"


  Loggers:
    logger:
      - name: com.example
        level: debug
        additivity: false
        AppenderRef:
          - ref: LogToConsole
          - ref: File

    Root:
      level: error
      AppenderRef:
        ref: LogToConsole

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

private static Logger logger = LogManager.getLogger();

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

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

import java.util.concurrent.TimeUnit;

public class Log4j_XML_Example {

    WebDriver driver;

    By userName = By.name("username");
    By passWord = By.name("password");
    By loginBtn = By.xpath("//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[3]/button");
    By loginTitle = By.xpath("//*[@id='app']/div[1]/div/div[1]/div/div[2]/h5");
    By dashboardPage = By.xpath("//*[@id='app']/div[1]/div[1]/header/div[1]/div[1]/span/h6");
    By actualErrorMessage =  By.xpath("//*[@class='orangehrm-login-error']/div[1]/div[1]/p");

    // Creating a logger
    private static Logger logger = LogManager.getLogger();

    @BeforeMethod
    public void setUp() {

        logger.info("Open a Chrome Web Browser");
        ChromeOptions options=new ChromeOptions();

        logger.info("Make the Web Browser full screen");
        options.addArguments("--start-maximized");
        driver=new ChromeDriver(options);

        logger.info("Wait for 10 sec");
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("https://opensource-demo.orangehrmlive.com/");
        logger.info("Open the application");
    }

    @Test(description = "This test validates title of login functionality", priority = 0)
    public void verifyLoginPageTitle() {

        logger.info("Verify the Login page title");
        String expectedTitle = driver.findElement(loginTitle).getText();

        logger.info("Expected Title :" + expectedTitle);
        Assert.assertTrue(expectedTitle.equalsIgnoreCase("Login"));
    }

    @Test(description = "This test validates successful login to Home page", priority = 1)
    public void verifyloginPage() {

        logger.info("Enter Username");
        driver.findElement(userName).sendKeys("Admin");

        logger.info("Enter Password");
        driver.findElement(passWord).sendKeys("admin123");

        driver.findElement(loginBtn).submit();
        logger.info("New page - Dashboard is opened");
        String newPageText = driver.findElement(dashboardPage).getText();

        logger.info("Heading of new page :" + newPageText);
        Assert.assertTrue(newPageText.contains("Dashboard"));

    }

    @Test(description = "This test validates unsuccessful login", priority = 2)
    public void verifyIncorrectCredentials() {

        logger.info("Enter Username");
        driver.findElement(userName).sendKeys("12345");

        logger.info("Enter Password");
        driver.findElement(passWord).sendKeys("admin123");

        driver.findElement(loginBtn).submit();
        logger.info("Error Message is displayed");
        String ErrorMessage = driver.findElement(actualErrorMessage).getText();

        logger.info("Error Message :" + ErrorMessage);
        Assert.assertEquals(ErrorMessage, "Invalid credentials");
    }

    @AfterMethod
    public void teardown() {

        logger.info("Close the webpage");
        driver.quit();
    }

}

If you want to add RollingFile details in the file, you can refer to the below file for the same.

    RollingFile:
      - name: LogToRollingFile
        fileName: logs/app.log
        filePattern: "logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"
        PatternLayout:
          pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
        Policies:
          SizeBasedTriggeringPolicy:
            size: 1KB
        DefaultRollOverStrategy:
          max: 5

How to download and install Apache POI

HOME

This tutorial describes how to download and install Apache POI.

Selenium does not have an inbuilt method to read data from an Excel File. However, there are various libraries in JAVA that help in reading/writing data from Excel files. Apache POI is one of the most used libraries, which provides various classes and methods to read/write data from various formats of Excel files(xls, xlsx etc).

What is Apache POI?

Apache POI, where POI stands for (Poor Obfuscation Implementation)  is the Java API for Microsoft Documents that offers a collection of Java libraries that helps us to read, write, and manipulate different Microsoft files such as Excel sheets, PowerPoint, and Word files.

Download Apache POI

Step 1To download Apache POI, go to its official site, here. Click on the Download as shown in the image. This link will navigate to the page showing the latest release of Apache POI.  The latest Apache POI version is 5.2.3. You can follow the same steps for any version of POI.

Step 2 This page shows the latest Apache POI Release Artifacts. Here, you can see POI 5.0.0 is the latest one. Download any one of the Binary Distribution options. One option is .ztar.gz and another option is .zip. I have selected .zip option.

Step 3 After clicking on the link, it navigates to another page as shown below. I have used the highlighted link to download the POI library files.

Step 4 Once POI.zip is downloaded and extracted, this is how the folder looks like

How to add POI libraries in Eclipse?

Step 1 Below is the Java project present in Eclipse.

Step 2 To add POI libraries to this project, Right-click on the project, hover over the Build path, select Configure Build Path.

Step 3  It will open the “Properties” of the project. After that, select the Libraries tab. Finally, click on the Add External JARs as highlighted below.

Step 4 Select the JARs in the parent folder of the unzipped POI files. Subsequently, click on the Open button to include them in the Eclipse project.

Step 5 – Next, select the JARs under the ooxml-lib folder in the unzipped POI folder as highlighted below:

Step 6 – Select the JARs under the lib folder in the unzipped POI folder as highlighted below.

Step 7 – After that, once all the POI JARs add, click on the Apply and Close button as highlighted below.

Step 8 – Once all the POI libraries successfully install in the Eclipse project, they will reflect under the Referenced Libraries folder in the left pane of the Eclipse project structure, as shown below:

How to add POI libraries to Maven Java Project

You can add the poi and poi-ooxml jar files to the Maven project by mentioning the dependencies in pom.xml.

 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.0.0</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>

You need to make sure that these two dependencies should be of the same version.

That’s it! We have downloaded and installed Apache POI.

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

Log4j 2 Tutorials

HOME

Cucumber Tutorial – How to setup Cucumber with Eclipse

HOME

In the previous tutorials, we discussed BDD (Behaviour Driven Development) and GherkinCucumber is one such open-source tool, which supports Behaviour Driven Development (BDD). In simple words, Cucumber can be defined as a testing framework, driven by plain English. It serves as documentation, automated tests, and development aid – all in one.

In this tutorial, we will set up Cucumber with Eclipse

Implementation Steps

1. Download and Install Java

Java is a robust programming language. Java is a general-purpose programming language that is concurrent; class-based and object-oriented language. Java follows the concept of “write once and run anywhere (WORA)” which means that compiled Java code can be run on all different platforms that support Java without the need for recompilation. Cucumber supports the Java platform for execution. Click here to know How to install Java.

2. Download and Start Eclipse

Eclipse is an Integrated Development Environment (IDE). It contains a base workspace and an extensible plug-in system for customizing the environment. To download Eclipse, please refer to this tutorial – How to install Eclipse.

3. Maven –  How to install Maven on Windows 

Apache Maven is a software project management and comprehension tool. It uses the concept of a project object model (POM), Maven can manage a project’s build, reporting, and documentation from a central piece of information. MAVEN helps us in creating the project structure and managing and downloading the dependencies. We need to define the required dependencies in pom.xml. To install Maven on Windows, please refer to this tutorial – How to install Maven.

4. Install Cucumber Eclipse Plugin

The Cucumber plugin is an Eclipse plugin that allows eclipse to understand the Gherkin syntax. Cucumber Eclipse Plugin highlights the keywords present in Feature File. To install Cucumber Eclipse Plugin, please refer to this tutorial – How to install Cucumber Eclipse Plugin

5. Configure Cucumber with Maven

Step 1 – Create a new Maven Project.

Click here to know the steps to create a new Maven project –  How to create a Maven project.

Step 2 – Open pom.xml of the project
       

Step 3 − Add dependency for selenium

This will indicate to Maven that Selenium jar files are to download from the central repository to the local repository.                                                                             

Open pom.xml in the edit mode, create dependencies tag (), inside the project tag.                   

 <!-- Selenium -->
 <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>4.15.0</version>
 </dependency>

Step 4 –  Add dependency for Cucumber-Java

This will indicate Maven, which Cucumber files are to be downloaded from the central repository to the local repository.  Create one more dependency tag.

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-java</artifactId>
    <version>7.14.0</version>
</dependency>

Step 5 – Add dependency for Cucumber-JUnit

This will indicate Maven, which Cucumber JUnit files are to download from the central repository to the local repository. Create one more dependency tag. 

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-junit</artifactId>
    <version>7.14.0</version>
    <scope>test</scope>
</dependency>

Step 6 –  Add dependency for JUnit

This will indicate Maven, which JUnit files are to be downloaded from the central repository to the local repository. Create one more dependency tag.

<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.13.2</version>
   <scope>test</scope>
</dependency>

Below is the screenshot which shows that Maven Project called Cucumber_JUnit4_Demo.

After adding the above mention dependencies, pom.xml looks like the image below

<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>Cucumber_JUnit4_Demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Cucumber_JUnit4_Demo</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <cucumber.version>7.14.0</cucumber.version>
    <selenium.version>4.15.0</selenium.version>
    <junit.version>4.13.2</junit.version>
  </properties>

  <dependencies>

    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-java</artifactId>
      <version>${cucumber.version}</version>
    </dependency>

    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-junit</artifactId>
      <version>${cucumber.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- Selenium -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium.version}</version>
    </dependency>

    <!-- JUnit4 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>

After adding the dependencies and then building the project, the below image shows the entire jar files added to the Maven Dependency.

Congratulations!! We are done with the setup of the Cucumber in Eclipse. Happy Learning.

Integration Testing of Springboot with Cucumber and JUnit4

Last Updated On

HOME

In this tutorial, I am going to build an automation framework to test the Springboot application with Cucumber, Rest Assured, and JUnit4.

Table of Contents

  1. What is Springboot?
  2. What is Cucumber?
  3. Dependency List
  4. Test Automation Framework Implementation
    1. Add SpringbootTest, Rest-Assured, and Cucumber dependencies to the project
    2. Create a directory src/test/resources and create a feature file under src/test/resources
    3. Create the Step Definition class or Glue Code for the Test Scenario under src/test/java
    4. Create a Cucumber Runner class under src/test/java
    5. Run the tests from JUnit
    6. Run the tests from Command Line
    7. Cucumber Report Generation

What is Springboot?

Spring Boot is an open-source micro framework maintained by a company called Pivotal. It provides Java developers with a platform to get started with an auto-configurable production-grade Spring application. With it, developers can get started quickly without losing time on preparing and configuring their Spring application.

What is Cucumber?

A cucumber is a software tool that supports behavior-driven development (BDD). Cucumber can be defined as a testing framework, driven by plain English. It serves as documentation, automated tests, and development aid – all in one.

Dependency List

  1. Springboot – 2.5.2
  2. Cucumber – 6.10.4
  3. Java 11
  4. JUnit – 4.13.2
  5. Maven – 3.8.1
  6. RestAssured – 4.3.3
  7. JUnit Vintage Engine (To run the tests through command line)

Below is the structure of a SpringBoot application project.

Below are various Java classes present in a SpringBoot REST Application.

  • SpringBootRestServiceApplication.java – The Spring Boot Application class is generated with Spring Initializer. This class acts as the launching point for the application.
  • pom.xml – This contains all the dependencies needed to build this project. 
  • Student.java – This is JPA Entity for Student class
  • StudentRepository.java – This is JPA Repository for Student. This is created using Spring Data JpaRepository.
  • StudentController.java – Spring Rest Controller exposing all services on the student resource.
  • CustomizedExceptionHandler.java – This implements global exception handling and customizes the responses based on the exception type.
  • ErrorDetails.java – Response Bean to use when exceptions are thrown from API.
  • StudentNotFoundException.java – Exception thrown from resources when the student is not found.
  • data.sql –  Data is loaded from data.sql into the Student table. Spring Boot would execute this script after the tables are created from the entities.
  • application.properties – Spring Boot automatically loads the application.properties whenever it starts up. You can de-reference values from the property file in the Java code through the environment.

Student.java

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Entity
public class Student {
    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    @Size(min = 4, message = "Name should have atleast 4 characters")
    private String name;

    @NotBlank(message = "passportNumber is mandatory")
    private String passportNumber;

    public Student() {
        super();
    }

    public Student(Long id, String name, String passportNumber) {
        super();
        this.id = id;
        this.name = name;
        this.passportNumber = passportNumber;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassportNumber() {
        return passportNumber;
    }

    public void setPassportNumber(String passportNumber) {
        this.passportNumber = passportNumber;
    }
}

StudentController

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

@RestController
public class StudentController {

    @Autowired
    private StudentRepository studentRepository;

    @GetMapping("/students/{id}")
    public EntityModel<Student> retrieveStudent(@PathVariable long id) {
        Optional<Student> student = studentRepository.findById(id);

        if (!student.isPresent())
            throw new StudentNotFoundException("id-" + id);

        EntityModel<Student> resource = EntityModel.of(student.get());

        WebMvcLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllStudents());

        resource.add(linkTo.withRel("all-students"));

        return resource;
    }
}

StudentRepository

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudentRepository extends JpaRepository<Student, Long>{

}

SpringBootRestServiceApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootRestServiceApplication {

    public static void main(String[] args) {

        SpringApplication.run(SpringBootRestServiceApplication.class, args);
    }

}

application.properties

spring.jpa.defer-datasource-initialization=true

data.sql

insert into student values(10001,'Annie', 'E1234567');
insert into student values(10002,'John', 'A1234568');
insert into student values(10003,'David','C1232268');

Test Automation Framework Implementation

Step 1 – Add SpringbootTest, Rest-Assured, and Cucumber dependencies to the project

To Test a SpringBoot Application, we are using SpringBoot Test, JUnit, Cucumber, and Rest Assured. Below mentioned dependencies are added in POM.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>

        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>4.3.3</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>6.10.4</version>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>6.10.4</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-spring</artifactId>
            <version>6.10.4</version>
            <scope>test</scope>
        </dependency>

Step 2 – Create a directory src/test/resources and create a feature file under src/test/resources

By default, the Maven project has src/test/java directory only. Create a new directory under src/test with the name of resources. Create a folder name as Features within src/test/resources directory.

Create a feature file to test the Springboot application.

Below is a sample feature file.

Feature: Verify springboot application using Cucumber

@ReceiveUserDetails
Scenario Outline: Send a valid Request to get user details
Given I send a request to the URL "/students" to get user details
Then the response will return status 200 and id <studentID> and names "<studentNames>" and passport_no "<studentPassportNo>"

Examples:
|studentID    |studentNames  |studentPassportNo|
|10001        |Annie         |E1234567         |
|10002        |John          |A1234568         |
|10003        |David         |C1232268         |

Step 3 – Create the Step Definition class or Glue Code for the Test Scenario under src/test/java

The corresponding step definition file of the above feature file is shown below.

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.spring.CucumberContextConfiguration;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;

@CucumberContextConfiguration
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SpringbootCucumberTestDefinitions {

    private final static String BASE_URI = "http://localhost";

    @LocalServerPort
    private int port;

    private ValidatableResponse validatableResponse;

    private void configureRestAssured() {
        RestAssured.baseURI = BASE_URI;
        RestAssured.port = port;
    }

    protected RequestSpecification requestSpecification() {
        configureRestAssured();
        return given();
    }

    @Given("I send a request to the URL {string} to get user details")
    public void iSendARequest(String endpoint) throws Throwable {
        validatableResponse = requestSpecification().contentType(ContentType.JSON)
                .when().get(endpoint).then();
        System.out.println("RESPONSE :"+validatableResponse.extract().asString());
    }

    @Then("the response will return status {int} and id {int} and names {string} and passport_no {string}")
    public void extractResponse(int status, int id, String studentName,String passportNo) {
        validatableResponse.assertThat().statusCode(equalTo(status))
                .body("id",hasItem(id)).body(containsString(studentName))
                .body(containsString(passportNo));

    }

}

The @CucumberContextConfiguration annotation tells Cucumber to use this class as the test context configuration for Spring. It is imported from:-

import io.cucumber.spring.CucumberContextConfiguration;

With the @SpringBootTest annotation, Spring Boot provides a convenient way to start up an application context to be used in a test.  It is imported from package:-

import org.springframework.boot.test.context.SpringBootTest;

By default, @SpringBootTest does not start the webEnvironment to refine further how your tests run. It has several options: MOCK(default), RANDOM_PORT, DEFINED_PORT, NONE.

RANDOM_PORT loads a WebServerApplicationContext and provides a real web environment. The embedded server is started and listens on a random port. LocalServerPort is imported from package:-

import org.springframework.boot.web.server.LocalServerPort;

The assertions are imported from the Hamcrest package:-

import static org.hamcrest.Matchers.*;

Step 4 – Create a Cucumber Runner class under src/test/java

A runner will help us to run the feature file and act as an interlink between the feature file and StepDefinition Class. To know more about Runner, refer to this link. The TestRunner should be created within the directory src/test/java.

import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(plugin = "pretty", features = {"src/test/resources/Features"}, glue = { "com.example.demo.definitions"})

public class CucumberRunnerTests {
}

The @CucumberOptions annotation is responsible for pointing to the right feature package, configuring the plugin for a better reporting of tests in the console output, and specifying the package where extra glue classes may be found. We use it to load configurations and classes that are shared between tests.

Step 5 – Run the tests from JUnit

You can execute the test script by right-clicking on TestRunner class -> Run As JUnit in Eclipse.

In case you are using IntelliJ, select “Run CucumberRunnerTests“.

SpringBootTest creates an application context containing all the objects we need for the Integration Testing It, starts the embedded server, creates a web environment, and then enables methods to do Integration testing.

Step 6 – Run the tests from the Command Line

To run the tests from the command line, we need to add junit-vintage-engine dependency. Starting with Spring Boot 2.4, JUnit 5’s vintage engine has been removed from the spring-boot-starter-test. If we still want to write tests using JUnit 4, we need to add the following Maven dependency:

        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <scope>test</scope>
        </dependency>

Use the below command to run the tests:-

mvn clean test

Step 7 – Cucumber Report Generation

To get Cucumber Test Reports, add cucumber.properties under src/test/resources and add the below instruction in the file. To know more about Cucumber Report Service, refer to this tutorial.

cucumber.publish.enabled=true

Below is the image of the report generated after the completion of the execution. This report can be saved on GitHub for future use.

That’s it! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

SpringBoot WireMock
SpringBoot Dependency Injection using Autowired
 Testing of Gradle SpringBoot Application with Serenity, Cucumber and JUnit4
Testing of SpringBoot Application with Serenity BDD, Cucumber and JUnit5 
 How to run SpringBoot tests with GitHub Actions

Selenium Interview Questions and Answers 2026

HOME

driver.findElement(By.id("email")) 


driver.findElement(By.xpath("/html/body/form/content"));

Double Slash “//” – Double slash is used to create an XPath with a relative path i.e. the XPath would be created to start selection from anywhere within the document. For example, the below example will select any element in the document which has an attribute named “id” with the specified value “email”.

driver.findElement(By.xpath("//*[@id = 'email']")

For more details, click here


4. How do we can launch the browser using WebDriver?

Firstly, we should instantiate a Chrome/Chromium session by doing the following

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
           
 ChromeOptions options = new ChromeOptions();
 WebDriver driver = new ChromeDriver(options);

The chromedriver is implemented as a WebDriver remote server that instructs the browser what to do by exposing Chrome’s internal automation proxy interface.

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

FirefoxOptions firefoxOptions = new FirefoxOptions();
WebDriver driver = new FirefoxDriver(firefoxOptions);

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

EdgeOptions options = new EdgeOptions();
WebDriver driver = new EdgeDriver(options);

For more details, click here 


5. What are the different types of Drivers available in WebDriver?

The different drivers available in WebDriver are

  • FirefoxDriver
  • InternetExplorerDriver
  • ChromeDriver
  • SafariDriver
  • OperaDriver
  • AndroidDriver
  • IPhoneDriver
  • HtmlUnitDriver

6. Explain the different exceptions in Selenium WebDriver

Exceptions in Selenium are similar to exceptions in other programming languages. The most common exceptions in Selenium are:


1. TimeoutException: This exception is thrown when a command performing an operation does not complete in the expected time.

2. NoSuchElementException: This exception is thrown when an element with given attributes is not found on the web page. Suppose webdriver is trying to click on XPath – “//*[@id=’yDmH0d’]/div/div[2]/div[2]/form/content” which doesn’t exist on that particular web page, then the below exception is displayed – org.openqa.selenium.NoSuchElementException.

3. ElementNotVisibleException: This exception is thrown when the element is present in DOM (Document Object Model), but not visible on the web page.

4. StaleElementException: This exception is thrown when the element is either deleted or no longer attached to the DOM. This exception occurs, when Selenium navigates to a different page, comes back to the same old page, and performs operations on the old page. Technically, it occurs when the element defined in the Selenium code is not found in the cache memory and the Selenium code is trying to locate it. 


7. What are the different types of waits available in WebDriver?

How do you achieve synchronization in WebDriver?

There are three types of wait in Selenium WebDriver

 1.   Implicit Wait – The implicit wait will tell to the web driver to wait for a certain amount of time before it throws a “NoSuchElementException“. The default setting is 0. Once we set the time, the web driver will wait for that time before throwing an exception. Implicit waits are used to provide a default waiting time (say 30 seconds) between each consecutive test step/command across the entire test script.
We need to import java.util.concurrent.TimeUnit to use ImplicitWait.

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));

2.    Explicit Wait – An explicit wait is a code you define to wait for a certain condition to occur before proceeding further in the code. The explicit wait will tell the web driver to wait for certain conditions like visibilityOfElementLocated and the maximum amount of time before throwing the NoSuchElementException exception. Unlike Implicit waits, explicit waits are applied for a particular instance only.

 Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
  wait.until(d -> revealed.isDisplayed());

3.  Fluent Wait – Fluent Wait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition.

Users may configure the wait to ignore specific types of exceptions whilst waiting, such as  NoSuchElementException when searching for an element on the page.

Fluent Wait commands are mainly used when the web elements which sometimes visible in a few seconds and sometimes take more time than usual. Mainly in Ajax applications. We could set the default pooling period based on the requirement.

Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

For more details, click here 


8. How to set the size of the Window in Selenium WebDriver?

First, fetch the size of the browser window in pixels by the below code Dimension

//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();

Now, change the size of the window by using

driver.manage().window().setSize(new Dimension(1024, 768)); 

9. How to set the position of Window in Selenium?

First fetch the coordinates of the top left coordinate of the browser window by

// Store the dimensions and query them later
Point position = driver.manage().window().getPosition();
         int x1 = position.getX();
         int y1 = position.getY();

// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

The window can be moved to the chosen position by

// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));

10. What is the difference between driver.findElement() and driver.findElements() commands?

FindElement – This method locates the first web element on the current web page matching the criteria mentioned as the parameter.  
If the web element is not found, it will throw an exception – NoSuchElementException. 

driver.findElement(By.xpath("Xpath location"));

FindElements – This method locates all the web elements on the current web page matching the criteria mentioned as parameters. 

If not found any WebElement on the current page as per the given element locator mechanism, it will return the empty list.     

findElements (By arg0):List<WebElement

For more details, click here 


11. How to type in a textbox using Selenium?

The user can use sendKeys(“String to be entered”) to enter the string in the textbox. The sendKeys type a key sequence in the DOM element even if a modifier key sequence is encountered.

Syntax - sendKeys(CharSequence… keysToSend ) : void
Command – driver.findElement(By.xpath("//*[@name = 'email']")).sendKeys("abc123@gmail.com") 

For more details, click here


12. How can we get a text of a web element?

The get command is used to retrieve the inner text of the specified web element. The command doesn’t require any parameter but returns a string value. It is also one of the extensively used commands for verification of messages, labels, errors, etc displayed on the web pages. 

String Text = driver.findElement(By.id(“Text”)).getText();

13. How to input text in the text box without calling the sendKeys()?

//Creating the JavascriptExecutor interface object by Type casting                                     JavascriptExecutor js = (JavascriptExecutor)driver;              

//Launching the Site        
driver.get("https://www.google.com/");                      
js.executeScript("document.getElementsByName('q')[0].value = 'Selenium Introduction';");

Actions actions = new Actions(driver);
actions.moveToElement(element).click().sendKeys("Selenium Introduction").build().perform();

For more details, click here


14. How to read a JavaScript variable in Selenium WebDriver? 

//To initialize the JS object
JavascriptExecutor JS = (JavascriptExecutor) webdriver;

//To get the site title
String title = (String)JS.executeScript("return document.title");
System.out.println("Title of the webpage : " + title);

For more details, click here


15. What is JavaScriptExecutor and in which cases JavaScriptExecutor will help in Selenium automation?

There are some conditions where we cannot handle problems with only WebDriver. Web controls don’t react well to selenium commands. In this kind of situation, we use Javascript. It is useful for custom synchronizations, hiding or showing web elements, changing values, testing flash/HTML5, and so on. 
To do these, we can use Selenium’s JavascriptExecutor interface which executes JavaScript through Selenium driver.

It providesexecutescript” & “executeAsyncScript methods, to run JavaScript in the context of the currently selected frame or window.

JavascriptExecutor js = (JavascriptExecutor) driver; 
js.executeScript(Script,Arguments);

Script – This is the JavaScript that needs to be executed.

Arguments – It is the arguments to the script. It’s optional
Let’s see some scenarios we could handle using this Interface:
1. To type Text in Selenium WebDriver without using sendKeys() method 2. To click a Button in Selenium WebDriver using JavaScript
3. To handle Checkbox
4. To generate an Alert Pop window in Selenium
5. To refresh the browser window using Javascript
6. To get inner text of the entire webpage in Selenium
7. To get the Title of our webpage
8. To get the domain
9. To get the URL of a webpage
10. To perform Scroll on an application using  Selenium


For more details, click here


16. How To Highlight Element Using Selenium WebDriver?

By using the JavascriptExecutor interface, we could highlight the specified element

//Create the JavascriptExecutor interface object by Type casting               
JavascriptExecutor js = (JavascriptExecutor)driver; 

//Higlight element - Total PageCount
WebElement TotalCount = driver.findElement(By.id("Stats1"));
js.executeScript("arguments[0].style.border='3px dotted blue'", TotalCount); 

For more details, click here


17. List some scenarios that we cannot automate using Selenium WebDriver?


18. How can you find if an element is displayed on the screen?

WebDriver facilitates the user with the following methods to check the visibility of the web elements. These web elements can be buttons, drop boxes, checkboxes, radio buttons, labels, etc.

  • isDisplayed()
  • isSelected()
  • isEnabled()
isDisplayed():
boolean elePresent = driver.findElement(By.xpath("xpath")).isDisplayed();
isSelected():
boolean eleSelected= driver.findElement(By.xpath("xpath")).isSelected(); 
isEnabled():
boolean eleEnabled= driver.findElement(By.xpath("xpath")).isEnabled();

19. Explain how you can switch back from a frame?

To switch back from a frame use the method defaultContent().  

driver.switchTo().defaultContent(); 

20. What is the difference between getWindowhandles() and getwindowhandle() ?

getwindowhandles(): It is used to get the address of all the open browser and its return type is Set<String>

getwindowhandle(): It is used to get the address of the current browser where the control is and return type is string.

For more details, click here


21. How to select the value in a dropdown?

To perform any operation on DropDown, we need to do 2 things:-

1) Import package org.openqa.selenium.support.ui.Select 
2) Create a new Select object of the class Select

Select oSelect = new Select());
Different Select Commands
Select yselect = new Select(driver.findElement(By.id("year")));
yselect.selectByValue("1988");
 Select mselect = new Select(driver.findElement(By.id("month")));
 mselect.selectByVisibleText("Apr");
Select bselect = new Select(driver.findElement(By.name("birthday_day")));
bselect.selectByIndex(8);

For more details, click here


22. How to switch to a new window (new tab) that opens up after you click on a link?

If you click on a link in a web page and it opens a new window, but WebDriver will not know which window the Operating system consider active. To change the WebDriver’s focus/ reference to the new window we need to use the switchTo() command. driver.switchTo().window();

Here, ‘windowName’ is the name of the window you want to switch your reference to.

In case you do not know the name of the window, then you can use the driver.getWindowHandle() command to get the name of all the windows that were initiated by the WebDriver. Note that it will not return the window names of browser windows which are not initiated by your WebDriver.

Once you have the name of the window, then you can use an enhanced for loop to switch to that window. Look at the piece of code below.

String handle= driver.getWindowHandle();
for (String handle : driver.getWindowHandles()) 
{
driver.switchTo().window(handle); 
}

//Store the ID of the original window
String originalWindow = driver.getWindowHandle();

//Check we don't have other windows open already
 assert driver.getWindowHandles().size() == 1;

 //Click the link which opens in a new window
 driver.findElement(By.linkText("new window")).click();

 //Wait for the new window or tab
 wait.until(numberOfWindowsToBe(2));
  
//Loop through until we find a new window handle
for (String windowHandle : driver.getWindowHandles()) {
    if(!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle);
        break; 
    } 
}
  
//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"));  

For more details, click here


23. How to handle browser (chrome) notifications in Selenium?

In Chrome, we can use ChromeOptions as shown below.

ChromeOptions options = new ChromeOptions();
options.addArguments("disable-infobars");
WebDriver player = new ChromeDriver(options);

24. How to delete Browser Cookies with Selenium Web Driver?

driver.Manage().Cookies.DeleteAllCookies();
driver.manage().deleteCookieNamed("cookie_name");
// Get the cookie
Cookie cookie = driver.manage().getCookieNamed("cookie_name");

// Delete the specific cookie
driver.manage().deleteCookie(cookie);

25. What are the different types of navigation commands?

  • driver.navigate().forward(); – to navigate to the next web page with reference to the browser’s history.
  • driver.navigate().back(); – takes back to the previous webpage with reference to the browser’s history.
  • driver.navigate().refresh(); – to refresh the current web page thereby reloading all the web elements.
  • driver.navigate().to(“url”); – to launch a new web browser window and navigate to the specified URL.

For more details, click here


26. How can we handle Web-based Pop-ups or Alerts in Selenium?

To handle Web-based alerts or popups, we need to do switch to the alert window and call Selenium WebDriver Alert API methods.

  • dismiss(): To click on Cancel button.
  • accept(): To Click on OK button.
  • getText(): To get the text which is present on the Alert.
  • sendKeys(): To enter the text into the alert box.

For more details, click here


27. What are the ways to refresh a browser using Selenium WebDriver?

1. Using driver.navigate().refresh() command.
2. Using driver.get(“URL”) on the current URL or using driver.getCurrentUrl()
3. Using driver.navigate().to(“URL”) on the current URL or driver.navigate().to(driver.getCurrentUrl());
4. Using sendKeys(Keys.F5) on any textbox on the webpage.        



28. What are the different mouse actions that can be performed?

The different mouse events supported in selenium are
1. click(WebElement element)
2. doubleClick(WebElement element)
3. contextClick(WebElement element)
4. mouseDown(WebElement element)
5. mouseUp(WebElement element)
6. mouseMove(WebElement element)
7. mouseMove(WebElement element, long xOffset, long yOffset)

For more details, click here


29. Write the code to double-click an element in selenium?

To double-click an element in Selenium, you can use the Actions class, which provides the doubleClick() method. The code to double-click an element in selenium is mentioned below

driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

WebElement clickable = driver.findElement(By.id("clickable"));
new Actions(driver)
.doubleClick(clickable)
.perform();

30. Write the code to right-click an element in selenium?

To right-click an element in Selenium, you can use the Actions class, which provides the contextClick() method for performing a right-click action. Below is an example:

 driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

WebElement clickable = driver.findElement(By.id("clickable"));
new Actions(driver)
.contextClick(clickable)
.perform();

31. How to mouse hover an element in selenium?

// Launch the URL
driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

WebElement hoverable = driver.findElement(By.id("hover"));
	     
new Actions(driver)
.moveToElement(hoverable)
.perform();

Using the Action class, drag and drop can be performed in selenium.

// Launch the URL
driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

WebElement hoverable = driver.findElement(By.id("hover"));
	     
new Actions(driver)
.moveToElement(hoverable)
.perform();

    Or
driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
 
WebElement draggable = driver.findElement(By.id("draggable"));
WebElement droppable = driver.findElement(By.id("droppable"));
new Actions(driver)
.dragAndDrop(draggable, droppable)
.perform();

33. How can we capture screenshots in selenium?

Using the getScreenshotAs method of the TakesScreenshot interface, we can take the screenshots in selenium.

File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("D:\\testScreenShot.jpg"));


Set<Cookie> cookies = driver.manage().getCookies();
driver.manage().getCookieNamed(arg0);
Cookie cookie = new Cookie("cookieName", "cookieValue");
driver.manage().addCookie(cookie);
driver.manage().deleteCookieNamed("cookieName");
driver.manage().deleteAllCookies();


Advanced Selenium Interview Questions and Answers 2026

Advance Selenium Tutorials

HOME