Run Cucumber7 with JUnit5 Tests from Maven Command Line

HOME

The previous tutorial will have explained to run Cucumber tests with JUnit4 or TestNG from Command-Line. Cucumber7 with JUnit5 has a lot of new configuration options. This tutorial will cover all the possible options.

To setup a framework with Cusumber7 and JUnit5, please refer to this tutorial – Integration of Cucumber7 with Selenium and JUnit5.

Below is the sample CucumberRunnerTests class for JUnit5.

import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;

@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("com/example")
@SelectClasspathResource("/features")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example")

public class CucumberRunnerTests  {

}

Run Test from Command Line

1. Open the command prompt and change the directory to the project location where pom.xml is present.

cd C:\Users\Vibha\eclipse-workspace_personnel\Cucumber7JUnit5_Demo

2. All feature files should be in src/test/resources and create the Cucumber Runner class as CucumberRunnerTest.
Note:- The Runner class name should end with Test to execute the tests from Command Line
Run the following command in the command prompt:

mvn clean test

mvn clean test runs Cucumber Features using Cucumber’s JUnit Runner.

3. The below screenshot shows the build success output.

Overriding Cucumber Options

Cucumber provides several options that can be passed to on the command line.

1. Running Scenarios using Tags from Command Line

If you are using Maven and want to run a subset of scenarios tagged with @ValidCredentials.

mvn clean test -Dcucumber.filter.tags="@ValidCredentials"

2. Running a Feature file from Command Line

Suppose you want to run a single Feature File from the command line, then use the below syntax

mvn clean test -Dcucumber.features=src/test/resources/features/LoginPage.feature

3. Passing plugin from Command Line

If we want to pass a plugin, please use the below-specified command:

mvn clean test -Dcucumber.plugin=html:target/cucumber-reports/cucumberReport.html

You can see that the cucumberReport.html is generated by the plugin.

4. Passing multiple Parameter from Command Line

If we want to pass more than one parameter, then we can use the following command

mvn clean test -Dcucumber.features=src/test/resources/features/LoginPage.feature -Dcucumber.filter.tags="@ValidCredentials"

You can see that only 1 test is executed and rest 4 tests are skipped out of total 5 tests as shown in the Report.

5. Running a Scenario without a tag from Command Line

If we want to run a single Scenario from the command line and no tag is assigned to that scenario, this is how we specify

mvn clean test -Dcucumber.features=src/test/resources/features/LoginPage.feature:11

6. Ignoring a subset of scenarios

If we do not want to run any Scenario from the command line, this is how we specify

mvn clean test -Dcucumber.filter.tags="not @ValidCredentials"

There is a total of 5 tests, but only 4 will be executed and 1 will be skipped. The output of the above program is shown below:

7. Pass glue code through command line

If we want to pass glue code from the command line, this is how we specify

mvn clean test -Dcucumber.glue=com.example

8. Pass dry run value through command line

dry-run option can either be set as true or false. If it is set as true, it means that Cucumber will only check that every step mentioned in the Feature File has corresponding code written in the Step Definition file or not. By default, dry-run is False.

mvn clean test -Dcucumber.execution.dry-run=true

This image shows the steps in the feature file that does not have step definitions.

The cucumber report shows that out of 2 tests, 1 is executed and another one is undefined.

9. Pass snippet type value through command line

The default option for snippets is UNDERSCORE. This settings can be used to specify the way code snippets will be created by Cucumber.

mvn clean test -Dcucumber.snippet-type=camelcase

You can see that the code snippet is in camelCase. In the previous example, it underscored.

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

Advertisement

Background in Cucumber

HOME

What is Background in Cucumber?

The background is used in Cucumber to define a step or series of steps that are shared by all the tests in the feature file.

A Background provides context for the scenarios that follow it. It may include one or more Given steps, which are executed prior to each scenario but after any Before hooks.

A Background is placed at the same level of indentation as the first Scenario/Example.

Below is an example of a Background in a Feature file.

Feature: Login to HRM Application

  Background:
    Given User is on HRMLogin page "https://opensource-demo.orangehrmlive.com/"

  @ValidCredentials
  Scenario: Login with valid credentials

    When User enters username as "Admin" and password as "admin123"
    Then User should be able to login successfully and new page open

  @MissingUsername
  Scenario: Login with blank username

    When User enters username as " " and password as "admin123"
    Then User should be able to see a message "Required" below Username

In the above example, we have two different scenarios, where a user is successfully able to log in to the application and an unsuccessful attempt to log in. But the common step is to open the website for both scenarios. This is why we create another Scenario for opening the browser but named it Background rather than a Scenario. So that it executes for both Scenarios.

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class LoginPageDefinitions {

    @Given("User is on HRMLogin page {string}")
    public void loginTest(String url) {

        System.out.println("I am in Login Page");

    }

    @When("User enters username as {string} and password as {string}")
    public void goToHomePage(String userName, String passWord) {

        System.out.println("Go to Home Page");

    }

    @Then("User should be able to login successfully and new page open")
    public void verifyLogin() {

        System.out.println("Home Page is opened");

    }

    @Then("User should be able to see a message {string} below Username")
    public void verifyMissingUsernameMessage(String message) {

        System.out.println("Login failed with an error message");
    }

}

We need a runner class to execute the feature file. Below is an example of the Runner class.

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(tags = "", features = "src/test/resources/features/LoginPage.feature", glue = "org.example.definitions",
        plugin = {})
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {
}

The output of the above program is

Background with Hooks

Background can contain one or more Given steps, which are run before each scenario, but after any Before hooks.

Below is an example of the background with hooks. The feature file is the same. I’m just adding the hooks to the Step Definition class.

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class LoginPageDefinitions {

    @Before()
    public void beforeScenario(){
        System.out.println("Start the browser and Clear the cookies");
    }

    @Given("User is on HRMLogin page {string}")
    public void loginTest(String url) {

        System.out.println("I am in Login Page");

    }

    @When("User enters username as {string} and password as {string}")
    public void goToHomePage(String userName, String passWord) {

        System.out.println("Go to Home Page");

    }

    @Then("User should be able to login successfully and new page open")
    public void verifyLogin() {

        System.out.println("Home Page is opened");

    }

    @Then("User should be able to see a message {string} below Username")
    public void verifyMissingUsernameMessage(String message) {

        System.out.println("Login failed with an error message");
    }

  @After()
    public void afterScenario(){
        System.out.println("Log out the user and close the browser");
    }

}

The output of the above program is

Points to remember

  • Background should not be used to create complicated states unless the client requires that information.
    For example, if the client doesn’t care about the user and site names, use a higher-level step like Given I am logged in as a site owner
  • Keep the Background section brief.
    When reading the scenarios, the client must remember this information. Consider moving some of the irrelevant details into higher-level steps if the Background is longer than four lines.
  • Make your background section stand out
    Use interesting names and try to tell a story. The human brain remembers stories much better than it remembers names like “User A,” “User B,” “Site 1,” and so on.

Page Object Model with Selenium, Cucumber, and TestNG

HOME

In the previous tutorial, I explained the Page Object Model with Selenium, Cucumber and JUnit. In this tutorial, I’ll create a BDD Framework for the testing of web applications using the Page Object Model with Selenium, Cucumber, and TestNG.

This framework consists of

  1. Cucumber Java – 7.11.1
  2. Cucumber TestNG – 7.11.1
  3. Java 11
  4. Maven – 3.8.6
  5. Selenium – 4.3.0
  6. TestNG – 7.7.1

What Is Page Object Model (POM)?

The Page Object model is an object design pattern in Selenium, where web pages are represented as classes, the various elements on the page are defined as variables in the class and all possible user interactions can then be implemented as methods in the class.

What is Cucumber?

Cucumber is one such open-source tool, which supports Behavior 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.

Steps to setup Cucumber Test Automation Framework using Page Object Model

  1. Download and Install Java on the system
  2. Setup Maven on System
  3. Install Cucumber Eclipse Plugin (Only for Eclipse IDE)
  4. Create a new Maven Project
  5. Create a source folder – src/test/resources to create test scenarios in the Feature file
  6. Add Selenium, Cucumber and JUnit4 dependencies to the project
  7. Add Maven Compiler Plugin and Surefire Plugin
  8. Create a feature file under src/test/resources
  9. Create the classes for locators, actions, and utilities in src/main/java
  10. Create a StepDefinition class in src/test/java
  11. Create a Hook class in src/test/java
  12. Create a Cucumber Runner class in the src/test/java directory
  13. Run the tests from TestNG
  14. Run the tests from testng.xml
  15. Run the tests from Command Line
  16. Cucumber Report Generation
  17. TestNG Report Generation

Project Structure

Step 1- Download and Install Java

Cucumber and Selenium need Java to be installed on the system to run the tests. Click here to know How to install Java.

Step 2 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. Click here to know How to install Maven.

Step 3 – Install Cucumber Eclipse Plugin (Only for Eclipse)

The cucumber plugin is an Eclipse plugin that allows eclipse to understand the Gherkin syntax. When we are working with cucumber we will write the feature files that contain Feature, Scenario, Given, When, Then, And, But, Tags, Scenario Outline, and Examples. By default, eclipse doesn’t understand these keywords so it doesn’t show any syntax highlighter. Cucumber Eclipse Plugin highlights the keywords present in Feature File. Refer to this tutorial to get more detail – How to setup Cucumber with Eclipse.

Step 4 – Create a new Maven Project

To create a new Maven project, go to the File -> New Project-> Maven-> Maven project-> Next -> Enter Group ID & Artifact ID -> Finish.

Click here to know How to create a Maven project.

Step 5 – Create source folder src/test/resources to create test scenarios in the Feature file

A new Maven Project is created with 2 folders – src/main/java and src/test/java. To create test scenarios, we need a new source folder called – src/test/resources. To create this folder, right-click on test directory ->select New ->Directory, and then it shows Maven Source Directories as resources as shown below.

Double-click on the resources directory and a new source directory under your new Maven project is created as shown in the below image.

Step 6 – Add Selenium, TestNG, and Cucumber dependencies to the project

Add below mentioned Selenium, TestNG, and Cucumber dependencies to the project. I have added WebDriverManager dependency to the POM.xml to download the driver binaries automatically. To know more about this, please refer to this tutorial – How to manage driver executables using WebDriverManager.

   <properties>
        <cucumber.version>7.11.1</cucumber.version>
        <selenium.version>4.3.0</selenium.version>
        <webdrivermanager.version>5.2.1</webdrivermanager.version>
        <testng.version>7.7.1</testng.version>
        <maven.compiler.plugin.version>3.10.1</maven.compiler.plugin.version>
        <maven.surefire.plugin.version>3.0.0-M7</maven.surefire.plugin.version>
        <maven.compiler.source.version>11</maven.compiler.source.version>
        <maven.compiler.target.version>11</maven.compiler.target.version>
    </properties>

    <dependencies>

        <!-- Cucumber with Java Dependency -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
        </dependency>

        <!-- Cucumber with TestNG Dependency -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-testng</artifactId>
            <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

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

        <!-- Web Driver Manager Dependency -->
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>${webdrivermanager.version}</version>
        </dependency>

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

    </dependencies>

Step 7 – Add Maven Compiler Plugin and Surefire Plugin

The compiler plugin is used to compile the source code of a Maven project. This plugin has two goals, which are already bound to specific phases of the default lifecycle:

  • compile – compile main source files
  • testCompile – compile test source files
<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${maven.compiler.plugin.version}</version>
				<configuration>
					<source>${maven.compiler.source.version}</source>
					<target>${maven.compiler.target.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>${maven.surefire.plugin.version}</version>
				<configuration>
                <includes>
                    <include>**/*Tests.java</include>
                </includes>
				</configuration>
			</plugin>
		</plugins>

The complete POM.xml looks like as shown below

<?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>POM_CucumberTestNG_Demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <cucumber.version>7.11.1</cucumber.version>
        <selenium.version>4.3.0</selenium.version>
        <webdrivermanager.version>5.2.1</webdrivermanager.version>
        <testng.version>7.7.1</testng.version>
        <maven.compiler.plugin.version>3.10.1</maven.compiler.plugin.version>
        <maven.surefire.plugin.version>3.0.0-M7</maven.surefire.plugin.version>
        <maven.compiler.source.version>11</maven.compiler.source.version>
        <maven.compiler.target.version>11</maven.compiler.target.version>
    </properties>

    <dependencies>

        <!-- Cucumber with Java Dependency -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
        </dependency>

        <!-- Cucumber with TestNG Dependency -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-testng</artifactId>
            <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

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

        <!-- Web Driver Manager Dependency -->
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>${webdrivermanager.version}</version>
        </dependency>

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

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source.version}</source>
                    <target>${maven.compiler.target.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>**/*Tests.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 8 – Create a feature file in the src/test/resources

Create a folder with name features. Now, create the feature file in this folder. The feature file should be saved with the extension .feature. This feature file contains the test scenarios created to test the application. The Test Scenarios are written in Gherkins language in the format of Given, When, Then, And, But.

Below is an example of Test Scenarios in the feature file. I have failed one test scenario intentionally – @MissingUsername.

Feature: Login to HRM Application 

Background: 
   Given User is on HRMLogin page "https://opensource-demo.orangehrmlive.com/"
 
   @ValidCredentials
   Scenario: Login with valid credentials
     
    When User enters username as "Admin" and password as "admin123"
    Then User should be able to login sucessfully and new page open
    
   @InvalidCredentials
   Scenario Outline: Login with invalid credentials
     
    When User enters username as "<username>" and password as "<password>"
    Then User should be able to see error message "<errorMessage>"
    
  Examples:
  | username    | password   | errorMessage                       |
  | Admin        | admin12$$ | Invalid credentials               |
  | admin$$     | admin123   | Invalid credentials               |
  | abc123       | xyz$$          | Invalid credentials               |
  
  
   @MissingUsername
   Scenario: Login with blank username
     
    When User enters username as " " and password as "admin123"
    Then User should be able to see a message "Required1" below Username
      

Step 9 – Create the classes for locators, actions, and utilities in src/main/java

Create folders – actions, locators, and utils in src/main/java.

Create a Java Class for each page where define WebElements as variables using Annotation @FindBy. Create another Java class that contains methods for actions performed on WebElements. Here, I’m going to create 2 classes for locators – LoginPageLocators and HomePageLocators as well as 2 classes for actions – LoginPageActions and HomePageActions

The Locator class contains WebElements which are identified by @FindBy annotation as shown below:-

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

Action class contains methods for the action to be performed on the web elements identified in the locator class.

The initElements is a static method of PageFactory class that is used to initialize all the web elements located by @FindBy annotation. Only after the WebElements are initialized, they can be used in the methods to perform actions.

public Login(WebDriver driver) {
           this.driver = driver;
           // This initElements method will create all WebElements
           PageFactory.initElements(driver, this);
     }

Below is the sample code of the LoginPageLocators.

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

public class LoginPageLocators {

	@FindBy(name = "username")
    public WebElement userName;
 
    @FindBy(name = "password")
    public WebElement password;
    
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[1]/div/span")
    public WebElement missingUsernameErrorMessage;
    
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[3]/button")
    public WebElement login;
 
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/div/div[1]/div[1]/p")
    public  WebElement errorMessage;
       
}

Below is the sample code for the HomePageLocators.

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

public class HomePageLocators {

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

}

Create the action classes for each web page. These action classes contain all the methods needed by the step definitions. In this case, I have created 2 action classes – LoginPageActionsHomePageActions 

LoginPageActions

import org.example.locators.LoginPageLocators;
import org.example.utils.HelperClass;
import org.openqa.selenium.support.PageFactory;

public class LoginPageActions {

    LoginPageLocators loginPageLocators = null;

    public LoginPageActions() {

        this.loginPageLocators = new LoginPageLocators();

        PageFactory.initElements(HelperClass.getDriver(),loginPageLocators);
    }

    // Get the error message when username is blank
    public String getMissingUsernameText() {
        return loginPageLocators.missingUsernameErrorMessage.getText();
    }

    // Get the Error Message
    public String getErrorMessage() {
        return loginPageLocators.errorMessage.getText();
    }

    public void login(String strUserName, String strPassword) {

        // Fill user name
        loginPageLocators.userName.sendKeys(strUserName);

        // Fill password
        loginPageLocators.password.sendKeys(strPassword);

        // Click Login button
        loginPageLocators.login.click();

    }

HomePageActions

import org.example.locators.HomePageLocators;
import org.example.utils.HelperClass;
import org.openqa.selenium.support.PageFactory;

public class HomePageActions {

    HomePageLocators homePageLocators = null;

    public HomePageActions() {

        this.homePageLocators = new HomePageLocators();
        PageFactory.initElements(HelperClass.getDriver(),homePageLocators);
    }

    // Get the User name from Home Page
    public String getHomePageText() {
        return homePageLocators.homePageUserName.getText();
    }

}

 Create a Helper class where we are initializing the web driver, initializing the web driver wait, defining the timeouts, and creating a private constructor of the class, it will declare the web driver, so whenever we create an object of this class, a new web browser is invoked. 

import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;

public class HelperClass {

	 private static HelperClass helperClass;
     
	    private static WebDriver driver;
	    public final static int TIMEOUT = 10;
	      
	     private HelperClass() {
	           
	        WebDriverManager.chromedriver().setup();
	        driver = new ChromeDriver();
	        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT));
	        driver.manage().window().maximize();
	     }      
	              
	    public static void openPage(String url) {
	        driver.get(url);
	    }
	  	      
	    public static WebDriver getDriver() {
	        return driver;              
	    }
	      
	    public static void setUpDriver() {
	          
	        if (helperClass==null) {
	              
	            helperClass = new HelperClass();
	        }
	    }
	      
	    public static void tearDown() {
	           
	        if(driver!=null) {
	             driver.close();
	             driver.quit();
	        }
	           
	       helperClass = null;
	   } 
	      
	}

Step 10 – Create a StepDefinition class in src/test/java

Create a Java Class called Definition where we will create the Test Code related to the Given, When, Then of Feature file in src/test/java.

Now, we need to create the Step Definition of the Feature File – LoginPageDefinitions.java.

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.example.actions.HomePageActions;
import org.example.actions.LoginPageActions;
import org.example.utils.HelperClass;
import org.testng.Assert;

public class LoginPageDefinitions {

    LoginPageActions objLogin = new LoginPageActions();
    HomePageActions objHomePage = new HomePageActions();

    @Given("User is on HRMLogin page {string}")
    public void loginTest(String url) {

        HelperClass.openPage(url);

    }

    @When("User enters username as {string} and password as {string}")
    public void goToHomePage(String userName, String passWord) {

        // login to application
        objLogin.login(userName, passWord);

        // go the next page

    }

    @Then("User should be able to login successfully and new page open")
    public void verifyLogin() {

        // Verify home page
        Assert.assertTrue(objHomePage.getHomePageText().contains("Dashboard"));

    }

    @Then("User should be able to see error message {string}")
    public void verifyErrorMessage(String expectedErrorMessage) {

        // Verify home page
        Assert.assertEquals(objLogin.getErrorMessage(),expectedErrorMessage);

    }

    @Then("User should be able to see a message {string} below Username")
    public void verifyMissingUsernameMessage(String message) {

        Assert.assertEquals(objLogin.getMissingUsernameText(),message);
    }

}

Step 11 – Create a Hook class in src/test/java

Create the hook class that contains the Before and After hook to initialize the web browser and close the web browser. I have added the code to take the screenshot of the failed scenario in @After Hook.

Below is the code for the Hooks class.

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import com.example.utils.HelperClass;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;

public class Hooks {

	@Before
    public static void setUp() {

       HelperClass.setUpDriver();
    }

	@After
	public static void tearDown(Scenario scenario) {

		//validate if scenario has failed
		if(scenario.isFailed()) {
			final byte[] screenshot = ((TakesScreenshot) HelperClass.getDriver()).getScreenshotAs(OutputType.BYTES);
			scenario.attach(screenshot, "image/png", scenario.getName()); 
		}	
		
		HelperClass.tearDown();
	}
}

Step 12 – Create a JUnit Cucumber Runner class in the src/test/java

Cucumber needs a TestRunner class to run the feature files. It is suggested to create a folder with the name of the runner in the src/test/java directory and create the Cucumber TestRunner class in this folder. Below is the code of the Cucumber TestRunner class.

Below is the code for CucumberRunnerTests class.

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(tags = "", features = "src/test/resources/features/LoginPage.feature", glue = "org.example.definitions",
        plugin = {})

public class CucumberRunnerTests extends AbstractTestNGCucumberTests {
}

Note:- The name of the Runner class should end with Test otherwise we can’t run the tests using Command Line.

Step 13 – Run the tests from TestNG

You can execute the test script by right-clicking on TestRunner class -> Run As TestNG. (Eclipse)

In the case of the IntelliJ project, right-click on the runner class and select Run ‘CucumberRunnerTests’.

The output of the above program is

Step 14 – Run the tests from testng.xml

Create a TestNG.xml as shown below and run the tests as TestNG.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
    <test  name="Cucumber with TestNG Test">
        <classes>
            <class name="org.example.runner.CucumberRunnerTests"/>
        </classes>
    </test> <!-- Test -->
</suite> <!-- Suite -->

The testng.xml is highlighted below:

Step 15 – Run the tests from Command Line

Run the below command in the command prompt to run the tests and to get the test execution report.

mvn clean test

The output of the above program is

Step 16 – Cucumber Report Generation

To get Cucumber Test Reports, add cucumber.properties under src/test/resources and add the below instruction in the file.

cucumber.publish.enabled=true

Below is the image of the Cucumber Report generated using the Cucumber Service.

In the above example, as we can see, one of the tests has failed. So, when a test fails, we have written the code to take a screenshot of the failed step. The Attached Image shows the image of the failed test. You can click on that to see the screenshot.

Step 17 – TestNG Report Generation

TestNG generates various types of reports under the target->surefire-reports folder like emailable-report.html, index.html, testng-results.xml.

We are interested in the “emailable-report.html” report. Open “emailable-report.html“, as this is an HTML report, and open it with the browser. The below image shows emailable-report.html.

emailable-report.html

Index.html

TestNG also produces an “index.html” report. The below image shows the index.html report.

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

Implemention of ‘Masterthought’ Reports in Cucumber with JUnit4

HOME

Masterthought library provides pretty HTML reports for Cucumber. The cucumber JSON file is used to generate the HTML for the website. This Java report publisher was made particularly with publishing cucumber reports to the Jenkins build server in mind. It releases aesthetically pleasing HTML reports with charts displaying the outcomes of cucumber runs.

Pre-Requisite

  1. Java 11 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

This framework consists of:

  1. Selenium – 4.3.0
  2. Java 11
  3. Cucumber – 7.6.0
  4. Maven – 3.8.1
  5. JUnit– 4.13.2
  6. Cucumber Reporting Plugin – 5.7.4

Project Structure

Implementation Steps

  1. Download and Install Java on the system
  2. Download and setup Eclipse IDE on the system
  3. Setup Maven
  4. Install Cucumber Eclipse Plugin (For Eclipse IDE)
  5. Create a new Maven Project
  6. Add SeleniumJUnit4Cucumber, and Masterthought dependencies to the project
  7. Create a feature file under src/test/resources
  8. Create the test code locating the web elements in src/main/java
  9. Create the Step Definition class or Glue Code in src/test/java
  10. Create a JUnit4 Cucumber Runner class in src/test/java
  11. Run the tests from Command Line
  12. Cucumber Report Generation

Step 1- Download and Install Java

Cucumber and Selenium need Java to be installed on the system to run the tests. 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

To build a test framework, we need to add a number of dependencies to the project. It is a very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool that is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

Step 4 – Install Cucumber Eclipse Plugin (Only for Eclipse IDE)

The Cucumber Eclipse plugin is a plugin that allows eclipse to understand the Gherkin syntax. The Cucumber Eclipse Plugin highlights the keywords present in Feature File. Click here to know more – Install Cucumber Eclipse Plugin.

Step 5 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

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

Step 6 – Add SeleniumTestNGCucumber, and Masterthought dependencies to the project

Masterthought Dependency

<dependency>
            <groupId>net.masterthought</groupId>
            <artifactId>cucumber-reporting</artifactId>
            <version>${maven.cucumber.reporting.version}</version>
</dependency>

Masterthought Plugin

<plugin>
        <groupId>net.masterthought</groupId>
        <artifactId>maven-cucumber-reporting</artifactId>
        <version>${maven.cucumber.reporting.version}</version>
 
        <executions>
            <execution>
                <id>execution</id>
                <phase>test</phase>
                <goals>
                    <goal>generate</goal>
                </goals>
                <configuration>
                    <projectName>Cucumber Reporting Example With JUnit4</projectName>
                    <outputDirectory>${project.build.directory}/cucumber-report-html</outputDirectory>
                    <inputDirectory>${project.build.directory}</inputDirectory>
                    <jsonFiles>
                        <param>**/*.json</param>
                    </jsonFiles>
                </configuration>
            </execution>
        </executions>
</plugin>

The complete POM.xml for the project is shown 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.example</groupId>
	<artifactId>CucumberReportingJUnit4_Demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>


	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<cucumber.version>7.6.0</cucumber.version>
		<selenium.version>4.3.0</selenium.version>
		<webdrivermanager.version>5.2.1</webdrivermanager.version>
		<junit.version>4.13.2</junit.version>
		<apache.common.version>2.4</apache.common.version>
		<maven.compiler.plugin.version>3.10.1</maven.compiler.plugin.version>
		<maven.surefire.plugin.version>3.0.0-M7</maven.surefire.plugin.version>
		<maven.compiler.source.version>11</maven.compiler.source.version>
		<maven.compiler.target.version>11</maven.compiler.target.version>
		<maven.cucumber.reporting.version>5.7.4</maven.cucumber.reporting.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>

		<!-- Web Driver Manager -->
		<dependency>
			<groupId>io.github.bonigarcia</groupId>
			<artifactId>webdrivermanager</artifactId>
			<version>${webdrivermanager.version}</version>
		</dependency>

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

		<!-- Apache Common -->
		<dependency>
			<groupId>org.apache.directory.studio</groupId>
			<artifactId>org.apache.commons.io</artifactId>
			<version>${apache.common.version}</version>
		</dependency>

        <!-- MasterThought -->
		<dependency>
			<groupId>net.masterthought</groupId>
			<artifactId>cucumber-reporting</artifactId>
			<version>${maven.cucumber.reporting.version}</version>
		</dependency>

	</dependencies>

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

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>${maven.surefire.plugin.version}</version>
			</plugin>

			<plugin>
				<groupId>net.masterthought</groupId>
				<artifactId>maven-cucumber-reporting</artifactId>
				<version>${maven.cucumber.reporting.version}</version>

				<executions>
					<execution>
						<id>execution</id>
						<phase>test</phase>
						<goals>
							<goal>generate</goal>
						</goals>
						<configuration>
							<projectName>Cucumber Reporting Example With JUnit4</projectName>
							<outputDirectory>${project.build.directory}/</outputDirectory>
							<inputDirectory>${project.build.directory}</inputDirectory>
							<jsonFiles>
								<param>**/*.json</param>
							</jsonFiles>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Step 7 – Create a feature file (LoginPage.feature) containing all the test scenarios under src/test/resources/features

It is recommended to create a features folder in src/test/resources directory. Create all the feature files in this features folder. Feature file should be saved as an extension of .feature.

Feature: Login to HRM Application 

Background:
   Given User is on HRMLogin page "https://opensource-demo.orangehrmlive.com/"
 
   @ValidCredentials
   Scenario: Login with valid credentials
       
     When User enters username as "Admin" and password as "admin123"
     Then User should be able to login successfully and new page open
    
  @InvalidCredentials
   Scenario Outline: Login with invalid credentials
     
     When User enters username as "<username>" and password as "<password>"
     Then User should be able to see error message "<errorMessage>"
    
  Examples:
   | username   | password  | errorMessage                      |
   | $$$$$      | ££££££££  | Invalid credentials               |
   | admin      | Admin123  | Invalid credentials               | 
   | Admin123   | admin     | Invalid credentials               |
     

Step 8 – Create the test code locating the web elements in src/main/java

LoginPageLocators

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

public class LoginPageLocators {

	@FindBy(name = "username")
    public WebElement userName;
 
    @FindBy(name = "password")
    public WebElement password;
 
    @FindBy(id = "logInPanelHeading")
    public WebElement titleText;
 
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[3]/button")
    public WebElement login;
 
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/div/div[1]/div[1]/p")
    public  WebElement errorMessage;
        
}

HomePageLocators

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

public class HomePageLocators {

	@FindBy(xpath = "//*[@id='app']/div[1]/div[1]/header/div[1]/div[1]/span/h6")
	public  WebElement homePageUserName;
 
}

LoginPageActions

import org.openqa.selenium.support.PageFactory;
import com.example.locators.LoginPageLocators;
import com.example.utils.HelperClass;

public class LoginPageActions {

LoginPageLocators loginPageLocators = null; 
	
    public LoginPageActions() {

    	this.loginPageLocators = new LoginPageLocators();

		PageFactory.initElements(HelperClass.getDriver(),loginPageLocators);
	}
    
    public void login(String strUserName, String strPassword) {
    	 
        // Fill user name
    	loginPageLocators.userName.sendKeys(strUserName);
 
        // Fill password
    	loginPageLocators.password.sendKeys(strPassword);
 
        // Click Login button
    	loginPageLocators.login.click();
 
    }

    //Get the title of Login Page")
    public String getLoginTitle() {
        return loginPageLocators.titleText.getText();
    }
     
    // Get the error message of Login Page
    public String getErrorMessage() {
        return loginPageLocators.errorMessage.getText();
    }

}

HomePageActions

import org.openqa.selenium.support.PageFactory;
import com.example.locators.HomePageLocators;
import com.example.utils.HelperClass;

public class HomePageActions {

	HomePageLocators homePageLocators = null;
   
	public HomePageActions() {
    	
		this.homePageLocators = new HomePageLocators();

		PageFactory.initElements(HelperClass.getDriver(),homePageLocators);
    }
 
    // Get the User name from Home Page
    public String getHomePageText() {
        return homePageLocators.homePageUserName.getText();
    }

}

HelperClass

import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;

public class HelperClass {
	
	private static HelperClass helperClass;
	private static WebDriver driver;
    public final static int TIMEOUT = 10;
	
	 private HelperClass() {
		 
		WebDriverManager.chromedriver().setup();
	    driver = new ChromeDriver();
	    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT));
	    driver.manage().window().maximize();

	 }      	    	

    public static void openPage(String url) {
        driver.get(url);
    }
	
	public static WebDriver getDriver() {
		return driver;
				
	}
	
	public static void setUpDriver() {
		
		if (helperClass==null) {
			
			helperClass = new HelperClass();
		}
	}
	
	 public static void tearDown() {
		 
		 if(driver!=null) {
			 driver.close();
			 driver.quit();
		 }
		 
		 helperClass = null;

	 } 	
}

Step 9 – Create the Step Definition class or Glue Code in src/test/java

It is recommended to create a definitions folder in src/test/java directory. The StepDefinition files should be created in this definitions directory. within the folder called definitions.

LoginPageDefinitions

import org.junit.Assert;
import com.example.actions.HomePageActions;
import com.example.actions.LoginPageActions;
import com.example.utils.HelperClass;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class LoginPageDefinitions{	

	LoginPageActions objLogin = new LoginPageActions();
    HomePageActions objHomePage = new HomePageActions();
 
    @Given("User is on HRMLogin page {string}")
    public void loginTest(String url) {
    	
    	HelperClass.openPage(url);
 
    }
 
    @When("User enters username as {string} and password as {string}")
    public void goToHomePage(String userName, String passWord) {
 
        // login to application
        objLogin.login(userName, passWord);
 
        // go the next page
        
    }
    
    @Then("User should be able to login successfully and new page open")
    public void verifyLogin() {
 
        // Verify home page
       Assert.assertTrue(objHomePage.getHomePageText().contains("Dashboard"));
 
    }
    
    @Then("User should be able to see error message {string}")
    public void verifyErrorMessage(String expectedErrorMessage) {
 
        // Verify error message
    	Assert.assertEquals(expectedErrorMessage,objLogin.getErrorMessage());
 
    }
    
}

Hooks

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import com.example.utils.HelperClass;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;

public class Hooks {
	
	@Before
    public static void setUp() {

       HelperClass.setUpDriver();
    }
	
	@After
	public static void tearDown(Scenario scenario) {
		//validate if scenario has failed
		if(scenario.isFailed()) {
			final byte[] screenshot = ((TakesScreenshot) HelperClass.getDriver()).getScreenshotAs(OutputType.BYTES);
			scenario.attach(screenshot, "image/png", scenario.getName()); 
		}	
	
		HelperClass.tearDown();
	}
}


Step 10 – Create a JUnit 4 Cucumber Runner class in src/test/java

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

@RunWith(Cucumber.class)
@CucumberOptions(tags = "", features = "src/test/resources/features/LoginPage.feature", glue = "com.example.definitions",
  plugin= {"pretty", "json:target/cucumber-reports/reports.json",
"json:target/cucumber-reports/cucumber.runtime.formatter.JSONFormatter"})
 
public class CucumberRunnerTests  {
 
}

Step 11 – Run the tests from Command Line

Use the below command to execute the tests

mvn clean test

The output of the above program is

Step 12 – Cucumber Report Generation

Refresh your project and check inside \target\cucumber-html-reports that the report generated with name feature-overview.

There are different types of HTML reports gets generated as a part of the test execution cycle.

1. feature-overview – This HTML report gives an overall overview of test execution. Main HTML report which covers all different sections like Features, Tags, Steps, and Failures.

2. failures-overview – This HTML report gives an overview of all failed tests.

3. step-overview – This HTML report shows step statistics for the current cycle.

4. tag-overview – This HTML report shows passing and failing statistics for different tags used in test execution.

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

Implemention of ‘Masterthought’ Reports in Cucumber with TestNG

HOME

Masterthought library provides pretty HTML reports for Cucumber. The cucumber JSON file is used to generate the HTML for the website. This Java report publisher was made particularly with publishing cucumber reports to the Jenkins build server in mind. It releases aesthetically pleasing HTML reports with charts displaying the outcomes of cucumber runs.

Cucumber lacks a sophisticated reporting feature. Cucumber generates a number of simple reports as part of the BDD framework; using the output from these same reports, we can use the Masterthought reporting plugin to produce more extensive HTML reports. Masterthought reporting plugin generates not only fancy reports but also detailed ones by reading a default report ‘cucumber.json’  generated by cucumber.

Pre-Requisite

  1. Java 11 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

This framework consists of:

  1. Selenium – 4.3.0
  2. Java 11
  3. Cucumber – 7.6.0
  4. Maven – 3.8.1
  5. TestNG – 7.6.0
  6. Cucumber Reporting Plugin – 5.7.4

Project Structure

Implementation Steps

  1. Download and Install Java on the system
  2. Download and setup Eclipse IDE on the system
  3. Setup Maven
  4. Install Cucumber Eclipse Plugin (For Eclipse IDE)
  5. Create a new Maven Project
  6. Add SeleniumTestNG, Cucumber, and Masterthought dependencies to the project
  7. Create a feature file under src/test/resources
  8. Create the test code locating the web elements in src/main/java
  9. Create the Step Definition class or Glue Code in src/test/java
  10. Create a TestNG Cucumber Runner class in src/test/java
  11. Create testng.xml
  12. Run the tests from Command Line
  13. Cucumber Report Generation

Step 1- Download and Install Java

Cucumber and Selenium need Java to be installed on the system to run the tests. 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

To build a test framework, we need to add a number of dependencies to the project. It is a very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool that is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

Step 4 – Install Cucumber Eclipse Plugin (Only for Eclipse IDE)

The Cucumber Eclipse plugin is a plugin that allows eclipse to understand the Gherkin syntax. The Cucumber Eclipse Plugin highlights the keywords present in Feature File. Click here to know more – Install Cucumber Eclipse Plugin.

Step 5 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

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

Step 6 – Add SeleniumTestNG, Cucumber, and Masterthought dependencies to the project

Masterthought Dependency

<dependency>
			<groupId>net.masterthought</groupId>
			<artifactId>cucumber-reporting</artifactId>
			<version>${maven.cucumber.reporting.version}</version>
</dependency>

Masterthought Plugin

<plugin>
		<groupId>net.masterthought</groupId>
		<artifactId>maven-cucumber-reporting</artifactId>
		<version>${maven.cucumber.reporting.version}</version>

		<executions>
			<execution>
				<id>execution</id>
				<phase>test</phase>
				<goals>
					<goal>generate</goal>
				</goals>
				<configuration>
					<projectName>Cucumber Reporting Example</projectName>
					<outputDirectory>${project.build.directory}/cucumber-report-html</outputDirectory>
					<inputDirectory>${project.build.directory}</inputDirectory>
					<jsonFiles>
						<param>**/*.json</param>
					</jsonFiles>
				</configuration>
			</execution>
		</executions>
</plugin>

The complete POM.xml for the project is shown 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.example</groupId>
	<artifactId>CucumberReportingTestNG_Demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<cucumber.version>7.6.0</cucumber.version>
		<selenium.version>4.3.0</selenium.version>
		<webdrivermanager.version>5.2.1</webdrivermanager.version>
		<testng.version>7.6.0</testng.version>
		<apache.common.version>2.4</apache.common.version>
		<maven.compiler.plugin.version>3.10.1</maven.compiler.plugin.version>
		<maven.surefire.plugin.version>3.0.0-M7</maven.surefire.plugin.version>
		<maven.compiler.source.version>11</maven.compiler.source.version>
		<maven.compiler.target.version>11</maven.compiler.target.version>
		<maven.cucumber.reporting.version>5.7.4</maven.cucumber.reporting.version>
	</properties>

	<dependencies>

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

		<dependency>
			<groupId>io.cucumber</groupId>
			<artifactId>cucumber-testng</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>

		<!-- Web Driver Manager -->
		<dependency>
			<groupId>io.github.bonigarcia</groupId>
			<artifactId>webdrivermanager</artifactId>
			<version>${webdrivermanager.version}</version>
		</dependency>

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

		<!-- Apache Common -->
		<dependency>
			<groupId>org.apache.directory.studio</groupId>
			<artifactId>org.apache.commons.io</artifactId>
			<version>${apache.common.version}</version>
		</dependency>

       <!-- Cucumber Reporting-->
		<dependency>
			<groupId>net.masterthought</groupId>
			<artifactId>cucumber-reporting</artifactId>
			<version>${maven.cucumber.reporting.version}</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${maven.compiler.plugin.version}</version>
				<configuration>
					<source>${maven.compiler.source.version}</source>
					<target>${maven.compiler.target.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>${maven.surefire.plugin.version}</version>
				<configuration>
					<testFailureIgnore>True</testFailureIgnore>
					<suiteXmlFiles>
						<suiteXmlFile>testng.xml</suiteXmlFile>
					</suiteXmlFiles>
				</configuration>
			</plugin>

			<plugin>
				<groupId>net.masterthought</groupId>
				<artifactId>maven-cucumber-reporting</artifactId>
				<version>${maven.cucumber.reporting.version}</version>

				<executions>
					<execution>
						<id>execution</id>
						<phase>test</phase>
						<goals>
							<goal>generate</goal>
						</goals>
						<configuration>
							<projectName>Cucumber Reporting Example</projectName>
							<outputDirectory>${project.build.directory}/cucumber-report-html</outputDirectory>
							<inputDirectory>${project.build.directory}</inputDirectory>
							<jsonFiles>
								<param>**/*.json</param>
							</jsonFiles>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Step 7 – Create a feature file (LoginPage.feature) containing all the test scenarios under src/test/resources/features

It is recommended to create a features folder in src/test/resources directory. Create all the feature files in this features folder. Feature file should be saved as an extension of .feature.

Feature: Login to HRM Application 

Background:
    Given User is on HRMLogin page "https://opensource-demo.orangehrmlive.com/"
 
   @ValidCredentials
   Scenario: Login with valid credentials
       
    When User enters username as "Admin" and password as "admin123"
    Then User should be able to login successfully and new page open
    
   @InvalidCredentials
   Scenario Outline: Login with invalid credentials
     
    When User enters username as "<username>" and password as "<password>"
    Then User should be able to see error message "<errorMessage>"
    
  Examples:
   | username   | password  | errorMessage                       |
   | $$$$$        | ££££££££  | Invalid credentials               |
   | admin        | Admin123  | Invalid credentials              | 

Step 8 – Create the test code locating the web elements in src/main/java

LoginPageLocators

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

public class LoginPageLocators {

	@FindBy(name = "username")
    public WebElement userName;
 
    @FindBy(name = "password")
    public WebElement password;
 
    @FindBy(id = "logInPanelHeading")
    public WebElement titleText;
 
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[3]/button")
    public WebElement login;
 
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/div/div[1]/div[1]/p")
    public  WebElement errorMessage;
        
    @FindBy(xpath = "//*[@href='https://www.facebook.com/OrangeHRM/mycompany']") //Invalid Xpath
    public  WebElement faceBookIcon;  
    
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[1]/div/span")
    public WebElement missingUsernameErrorMessage;
}

HomePageLocators

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

public class HomePageLocators {

	@FindBy(xpath = "//*[@id='app']/div[1]/div[1]/header/div[1]/div[1]/span/h6")
	public  WebElement homePageUserName;
 
}

LoginPageActions

import org.openqa.selenium.support.PageFactory;
import com.example.testng.locators.LoginPageLocators;
import com.example.testng.utils.HelperClass;

public class LoginPageActions {

LoginPageLocators loginPageLocators = null; 
	
    public LoginPageActions() {

    	this.loginPageLocators = new LoginPageLocators();

		PageFactory.initElements(HelperClass.getDriver(),loginPageLocators);
	}
    
    public void login(String strUserName, String strPassword) {
    	 
        // Fill user name
    	loginPageLocators.userName.sendKeys(strUserName);
 
        // Fill password
    	loginPageLocators.password.sendKeys(strPassword);
 
        // Click Login button
    	loginPageLocators.login.click();
 
    }
 
    //Get the title of Login Page")
    public String getLoginTitle() {
        return loginPageLocators.titleText.getText();
    }
      
    // Get the error message of Login Page
    public String getErrorMessage() {
        return loginPageLocators.errorMessage.getText();
    }
      
}

HomePageActions

import org.openqa.selenium.support.PageFactory;
import com.example.testng.locators.HomePageLocators;
import com.example.testng.utils.HelperClass;

public class HomePageActions {

	HomePageLocators homePageLocators = null;
   
	public HomePageActions() {
    	
		this.homePageLocators = new HomePageLocators();

		PageFactory.initElements(HelperClass.getDriver(),homePageLocators);
    }
 
    // Get the User name from Home Page
    public String getHomePageText() {
        return homePageLocators.homePageUserName.getText();
    }

}

HelperClass

import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;

public class HelperClass {
	
	private static HelperClass helperClass;
	
	private static WebDriver driver;
    public final static int TIMEOUT = 10;
	
	 private HelperClass() {
		 
			WebDriverManager.chromedriver().setup();
	    	driver = new ChromeDriver();
	    	driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT));
	        driver.manage().window().maximize();

	 }      
	    	
    public static void openPage(String url) {
        driver.get(url);
    }
	
	public static WebDriver getDriver() {
		return driver;
				
	}
	
	public static void setUpDriver() {
		
		if (helperClass==null) {
			
			helperClass = new HelperClass();
		}
	}

	 public static void tearDown() {
		 
		 if(driver!=null) {
			 driver.close();
			 driver.quit();
		 }
		 
		 helperClass = null;

	 } 
	
}

Step 9 – Create the Step Definition class or Glue Code in src/test/java

It is recommended to create a definitions folder in src/test/java directory. The StepDefinition files should be created in this definitions directory. within the folder called definitions.

LoginPageDefinitions

import org.junit.Assert;
import com.example.junit.actions.ForgetPasswordPageActions;
import com.example.junit.actions.HomePageActions;
import com.example.junit.actions.LoginPageActions;
import com.example.junit.utils.HelperClass;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class LoginPageDefinitions{
	
	LoginPageActions objLogin = new LoginPageActions();
    HomePageActions objHomePage = new HomePageActions();
    ForgetPasswordPageActions objForgotPasswordPage = new ForgetPasswordPageActions();
		
 
    @Given("User is on HRMLogin page {string}")
    public void loginTest(String url) {
    	
    	HelperClass.openPage(url);
 
    }
 
    @When("User enters username as {string} and password as {string}")
    public void goToHomePage(String userName, String passWord) {
 
        // login to application
        objLogin.login(userName, passWord);
 
        // go the next page
        
    }
    
    @Then("User should be able to login successfully and new page open")
    public void verifyLogin() {
 
        // Verify home page
        Assert.assertTrue(objHomePage.getHomePageText().contains("Dashboard"));
 
    }
    
    @Then("User should be able to see error message {string}")
    public void verifyErrorMessage(String expectedErrorMessage) {
 
        // Verify home page
        Assert.assertEquals(objLogin.getErrorMessage(),expectedErrorMessage);
 
    }
     
}

Hooks

import com.example.junit.utils.HelperClass;
import io.cucumber.java.After;
import io.cucumber.java.Before;

public class Hooks {
	
	@Before
    public static void setUp() {

       HelperClass.setUpDriver();
    }
	
	@After
	public static void tearDown() {
	
		HelperClass.tearDown();
	}
}

Step 10 – Create a TestNG Cucumber Runner class in src/test/java

We need to create a class called Runner class to run the tests. This class will use the TestNG annotation @RunWith(), which tells TestNG what is the test runner class. TestRunner should be created under src/test/java within the folder called runner.

AbstractTestNGCucumberTests – Runs each cucumber scenario found in the features as a separate test.

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
 
@CucumberOptions(tags = "", features = "src/test/resources/features/LoginPage.feature", glue = "com.example.testng.definitions",
    plugin= {"pretty", "html:test-output","json:target/cucumber/cucumber.json", "html:target/cucumber-html-report"})
 
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {
 
}

Step 11 – Create testng.xml

TestNG.xml is used to run multiple tests in a single execution.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test name="Cucumber Reporting">
  
  <classes>
  <class name = "com.example.testng.runner.CucumberRunnerTests"/>
  </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Step 12 – Run the tests from Command Line

Use the below command to execute the tests.

mvn clean test

The output of the above program is

Step 13 – Cucumber Report Generation

Refresh your project and check inside \target\cucumber-html-reports that the report generated with name feature-overview.

There are different types of HTML reports gets generated as a part of the test execution cycle.

1. feature-overview – This HTML report gives an overall overview of test execution. Main HTML report which covers all different sections like Features, Tags, Steps, and Failures.

2. failures-overview – This HTML report gives an overview of all failed tests.

3. step-overview – This HTML report shows step statistics for the current cycle.

4. tag-overview – This HTML report shows passing and failing statistics for different tags used in test execution.

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

Cucumber Reports

HOME

Sharing Cucumber test results with your colleagues is not easy. To make things easier, the Cucumber team has created a free, cloud-based service for sharing reports across the organization. The Cucumber Reports service, which is currently in early beta, allows you to configure Cucumber (currently only in Ruby or Java flavours) to upload the results of a Cucumber run to the cloud. You can then access them through your browser, which will render them using the same HTML formatter as on the desktop.

Chapter 1 Cucumber Reports – HTML, XML, JSON
Chapter 2 Cucumber Report Service
Chapter 3 Implemention of ‘Masterthought’ Reports in Cucumber with TestNG
Chapter 4 Implemention of ‘Masterthought’ Reports in Cucumber with JUnit4

How to rerun failed tests in Cucumber

HOME

The previous tutorial explained the Integration of Cucumber with Selenium and TestNG. Sometimes, inconsistent test results are common as a result of an unstable environment such as network issue or Database down and soon. A few tests may fail for no apparent reason and then rerun successfully. We are sometimes required to run only failed test cases after bug fixes in order to validate fixes quickly. We will learn how to rerun failed test cases in the Cucumber with TestNG project in this post.

Cucumber provides a rerun plugin option in the Runner class that generates a file which contains the information about the failed tests.

The Cucumber Framework with Selenium and TestNG can be found here. Use this tutorial to setup the project.

Now, let us add rerun plugin to the Cucumber Runner class. Here, we are creating a failedrerun.txt file that contains the information about the failed test. This file will be created under target folder.

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
   
@CucumberOptions(tags = "", features = {"src/test/resources/features/LoginPage.feature"}, glue = {"com.example.definitions"},
                 plugin = {"rerun:target/failedrerun.txt"})
   
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {
   
}

Create Second Runner Class

The next step is to run failed test scenarios present in the text file. We need to create a class same as our runner class which will contain the location of the file which we want to execute to rerun our failed scenarios. In the ‘features’ variable, you need mention the failedrerun.txt file and don’t forget that you must mention ‘@’ symbol before the file path.

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
   
@CucumberOptions(tags = "", features = {"@target/failedrerun.txt"}, glue = {"com.example.definitions"},
                 plugin = {})
   
public class FailedRunnerTests extends AbstractTestNGCucumberTests {
   
}

Run the tests using the below-mentioned command

mvn clean test

After running the tests from the command line, first, all the tests will be executed. If any test fails, a failedrerun.txt file will be generated that contains the details about the failed tests.

In the below screenshot, we can see that a scenario starting at line 7 is failed.

Once the first round of execution ends, Cucumber Runner goes to the second runner and runs the failed tests that are mentioned in failedrerun.txt.

We can see that 2 separate reports are generated here.

The first Cucumber Report shows that out of 5 tests, 1 test is failed.

The second Cucumber Report shows that the one failed test is rerun again, and it again failed.

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

Step Definition in Cucumber

HOME

The previous tutorial explained the Feature File in Cucumber. This tutorial explains the step definition in the Cucumber.

To start with, please add the below dependencies to the POM.xml, in the case of the Maven project.

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

   <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-junit</artifactId>
      <version>6.11.0</version>
      <scope>test</scope>
    </dependency>
       
   <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>4.13.2</version>
       <scope>test</scope>
   </dependency>
    
</dependencies>

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

implementation 'io.cucumber:cucumber-java:6.11.0'
testImplementation 'io.cucumber:cucumber-junit:6.11.0'
testImplementation 'junit:junit:4.13.2'

What is Step Definition?

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.

Cucumber finds the Step Definition file with the help of the Glue code in Cucumber Options.

By storing state in instance variables, a step definition can transfer state to a subsequent step definition.

Step definitions are not associated with a specific feature file or scenario. The name of a step definition’s file, class, or package has no bearing on which Gherkin steps it will match. The formulation of the step definition is the only thing that matters, which means the step definition should only match Gherkin’s steps.

Imagine, we want to test a web application. One of the first steps is Login to the website and then check the various functionalities on the website. We can create a Gherkin step like “I login to the website” and the corresponding step definition of this Gherkin Step. This Gherkin step can be used in multiple feature files, and we don’t need to create the step definition of this Gherkin step for each feature file.

In the previous tutorial, we have seen that when the Feature file is executed without the Step Definition file, the runner shows the missing steps with the snippet in the console.

When Cucumber encounters a Gherkin step without a matching step definition, it will print a step definition snippet with a matching Cucumber Expression. You can use this as a starting point for new step definitions.

It is very easy to implement all the steps, all you need to do is to copy the complete text marked in the above box and paste it into the MyHolidayDefinitions class.

@Given, @When, and @Then are imported from packages:-

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

Feature File

Feature: Book flight ticket 

@BookOneWayFlight
Scenario: Book Flight for one way trip

Given I live in Dublin with 2 adults and 2 kids
And I want to book one way flight ticket from Dublin to London on 22 Jan 2020
When I search online
Then TripAdvisor should provide me options of flights on 22 Jan 2020
And Cost of my flight should not be more than 50 Euro per person
And Tickets should be refundable

Let me create the step definition for the above Feature file

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class MyHolidayDefinitions {

	@Given("I live in Dublin with {int} adults and {int} kids")
	public void liveInDublin(Integer int1, Integer int2) {

		System.out.println("I live in Dublin with 2 adults and 2 kids");
	}

	@Given("I want to book one way flight ticket from Dublin to London on {int} Jan {int}")
	public void bookFlightTicket(Integer int1, Integer int2) {

		System.out.println("I want to book one way flight ticket from Dublin to London on 22 Jan 2020");
	}

	@When("I search online")
	public void searchOnline() {

		System.out.println("I search online");
	}

	@Then("TripAdvisor should provide me options of flights on {int} Jan {int}")
	public void tripAdvisor(Integer int1, Integer int2) {

		System.out.println("TripAdvisor should provide me options of flights on 22 Jan 2020");
	}

	@Then("Cost of my flight should not be more than {int} Euro per person")
	public void costOfFlightLimit(Integer int1) {

		System.out.println("Cost of my flight should not be more than 50 Euro per person");
	}

	@Then("Tickets should be refundable")
	public void refundableTickets() {

		System.out.println("Tickets should be refundable");
	}

}

To run the scenarios present in the Feature File, we need TestRunner class. To know more about the TestRunner class, please refer to this tutorial –

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

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/Features/MyHoliday.feature", tags = "@BookOneWayFlight", glue = "com.cucumber.MyCucumberProject.definitions")

public class CucumberRunnerTest {

}

The output of the above program is

Congratulations. We have created the setup definition for the feature file successfully and are able to run it.

Refer to the next tutorials to know the integration of Cucumber with Selenium – Integration of Cucumber with Selenium and JUnit and JUnit4 and Integration of Cucumber with Selenium and TestNG

Happy Learning!!

How to install Cucumber Eclipse Plugin

HOME

The Cucumber plugin is an Eclipse plugin that allows eclipse to understand the Gherkin syntax. When we are working with cucumber we will write the feature files that contain Feature, Scenario, Given, When, Then, And, But, Tags, Scenario Outline, and Examples. By default, eclipse doesn’t understand these keywords, so it doesn’t show any syntax highlighter. Cucumber Eclipse Plugin highlights the keywords present in Feature File.

When we create a feature file in Eclipse it looks something like the below without Cucumber Eclipse Plugin installed.

It is easy to install Cucumber Eclipse Plugin, as it comes as a plugin for Eclipse IDE. A prerequisite for installing this plugin is your Internet connection should be up & running during the installation of this plugin and Eclipse IDE should be installed on your computer.

Steps to follow:

Step 1 – Launch the Eclipse IDE and, from the Help menu, click “Install New Software”.

Step 2 – You will see a dialog window, click the “Add” button.

Step 3 – Type the name as you wish, let’s take “Cucumber” and type “https://cucumber.github.io/cucumber-eclipse-update-site-snapshot” as the location. Click the OK button.

Step 4 – You come back to the previous window, but this time you must see the Cucumber Eclipse Plugin option in the available software list. Just check the box and press the “Next” button.

Step 5 – Click on the Next Button.

Step 6 – Click “I accept the terms of the license agreement” and then click the Finish button.

Step 7 – You may or may not encounter a Security warning, if in case you do just click the OK button.

Step 8 -You are all done now, just click the “Restart Now” button.

After restarting Eclipse, you can see the feature file is highlighted based on the keywords.

This means now Eclipse is able to understand the language we have written in the feature file as Gherkin language.

All the steps in the below scenario are highlighted in yellow colour, which indicates we don’t have any corresponding step definition for each step.

Now, in the below example, I have created the step definition for the Given statement. So, now, it is not highlighted in yellow colour.

If you press the Ctrl button and place the cursor on a Given Statement, it will take you to the corresponding step definition of that step. This is a very helpful feature. When we have multiple feature files with multiple steps, it helps us find the exact location of the step definition.

I hope this tutorial makes your learning a little easy. Thanks. Happy Learning!!

Dependency Injection in Cucumber using Pico-Container

HOME

In this tutorial, we will use the constructor injection technique to share web driver instances in multiple-step definitions using PicoContainer.

Why do we need Dependency Injection in Cucumber?

A new Framework is built that contains several Page Objects, Step Definitions, Feature files, and Helper Classes. Eventually, new Feature Files will be added that contain the steps that are already present in the existing Step Definition files. In this case, we will prefer to use the existing Step Definitions instead of creating new ones. But, Cucumber does not support Inheritance means it does not allow extending classes that contain Step Definitions or Hooks (@After, @Before, etc.). Now, Dependency Injection comes into the picture.

In Cucumber, if we want to share the state between multiple-step definition files, we will need to use dependency injection (DI). There are several options: PicoContainer, Spring, OpenEJB, etc. If you’re not already using DI, then it is recommended to use PicoContainer. Otherwise, use the one that’s already in use, because you should only have one.

To use PicoContainer, add the following dependency to the POM.xml

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>7.0.0</version>
    <scope>test</scope>
</dependency>

Let me explain this with the help of an example.

Imagine there are 2 feature files. These feature files are using the same browser initialization and website. Now, instead of creating the browser initialization twice for 2 feature files, why not create a Common Class and mention these details in that class and using DI, call this class in the main Step Definition classes.

Feature File 1 – HomePage.feature

Below is the example of feature file 1.

Feature: Home page validation
  
Background:
   Given User Navigates to HRM login page
   And User login with valid credentials
 
   @ValidQuickLaunch
   Scenario Outline: Login with valid credentials to check QuickLanuch options  
     
   When User is in Dashboard page
     Then there are valid QuickLaunch options '<options>'
         
    Examples: 
        | options                  |
        | Assign Leave             |
        | Leave List               |
        | Timesheets               |
 
     
    @ValidLegendOptions    
    Scenario Outline: Login with valid credentials to check Manu Options 
     
   When User is in Dashboard page
     Then there are valid Legend options '<legendOptions>'
         
    Examples: 
        | legendOptions               |
        | Not assigned to Subunits    |
        | Administration              |
        | Client Services             |

Feature File 2 – LoginPage.feature

Below is the example of feature file 2.

Feature: Login to HRM Application 
  
   @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 sucessfully

Next, create a new class that holds the common data. For example:

public class ApplicationHooks {

	private WebDriver driver;

	@Before
	public void setUp() {
		setDriver();
	}

	public void setDriver() {

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

	public WebDriver getDriver() {
		return driver;
	}

	@After
	public void tearDown() {
		getDriver().quit();
	}
}

Then, in each of your step definition files that you want to use this common data, you can add a constructor that takes Step Data as an argument. This is where the injection occurs. For example:

LoginDefinition

public class LoginDefinition {

	private ApplicationHooks hooks;

	public LoginDefinition(ApplicationHooks hooks) {

		this.hooks = hooks;
	}

	@Given("User is on Home page")
	public void userOnHomePage() {

		System.out.println("Home Page is opened");
	}

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

		System.out.println("Username Entered");
		hooks.getDriver().findElement(By.name("txtUsername")).sendKeys(userName);

	}

	@When("User enters password as {string}")
	public void entersPassword(String passWord) throws InterruptedException {

		System.out.println("Password Entered");
		hooks.getDriver().findElement(By.name("txtPassword")).sendKeys(passWord);

		hooks.getDriver().findElement(By.id("btnLogin")).submit();
	}

	@Then("User should be able to login sucessfully")
	public void sucessfullLogin() throws InterruptedException {

		String newPageText = hooks.getDriver().findElement(By.id("welcome")).getText();
		System.out.println("newPageText :" + newPageText);
		Assert.assertTrue(newPageText.contains("Welcome"));

	}
}

HomeDefinition

public class HomePageDefinition {

	ApplicationHooks hooks;

	public HomePageDefinition(ApplicationHooks hooks) {
		this.hooks = hooks;
	}

	@Given("User Navigates to HRM login page")
	public void userOnHomePage() {

		System.out.println("HRM login Page is opened");
	}

	@Given("User login with valid credentials")
	public void entersCredentials() throws InterruptedException {

		hooks.getDriver().findElement(By.name("txtUsername")).sendKeys("Admin");
	hooks.getDriver().findElement(By.name("txtPassword")).sendKeys("admin123");
		hooks.getDriver().findElement(By.id("btnLogin")).submit();

	}

	@When("User is in Dashboard page")
	public void verifyDashboardPage() {

		String dashboardTitle = hooks.getDriver().findElement(By.id("welcome")).getText();
		Assert.assertTrue(dashboardTitle.contains("Welcome"));

	}

	@Then("there are valid QuickLaunch options {string}")
	public void verifyQuickLinks(String options) throws InterruptedException {

		switch (options) {
		case "Assign Leave":
			String linkOne = hooks.getDriver()
					.findElement(By.xpath(
							"//*[@id='dashboard-quick-launch-panel-menu_holder']/table/tbody/tr/td[1]/div/a/span"))
					.getText();
			Assert.assertEquals(linkOne, options);

			break;
		case "Leave List ":
			String linkTwo = hooks.getDriver()
					.findElement(By.xpath(
							"//*[@id='dashboard-quick-launch-panel-menu_holder']/table/tbody/tr/td[2]/div/a/span"))
					.getText();
			Assert.assertEquals(linkTwo, options);
			Thread.sleep(1000);
			break;

		case "Timesheets":
			String linkThree = hooks.getDriver()
					.findElement(By.xpath(
							"//*[@id='dashboard-quick-launch-panel-menu_holder']/table/tbody/tr/td[3]/div/a/span"))
					.getText();
			Assert.assertEquals(linkThree, options);
			break;

		default:
			break;
		}

	}

	@Then("there are valid Legend options {string}")
	public void verifyMenuOptions(String options) throws InterruptedException {

		switch (options) {
		case "Not assigned to Subunits":
			String linkOne = hooks.getDriver()
					.findElement(
							By.xpath("//*[@id='div_legend_pim_employee_distribution_legend']/table/tbody/tr[1]/td[2]"))
					.getText();
			Assert.assertEquals(linkOne, options);
			break;

		case "Administration":
			String linkTwo = hooks.getDriver()
					.findElement(
							By.xpath("//*[@id='div_legend_pim_employee_distribution_legend']/table/tbody/tr[2]/td[2]"))
					.getText();
			Assert.assertEquals(linkTwo, options);
			break;

		case "Client Services":
			String linkThree = hooks.getDriver()
					.findElement(
							By.xpath("//*[@id='div_legend_pim_employee_distribution_legend']/table/tbody/tr[3]/td[2]"))
					.getText();
			Assert.assertEquals(linkThree, options);
			break;
		default:
			break;

		}
	}
}

Create a Test Runner Class to execute the tests.

import org.junit.runner.RunWith;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)

@CucumberOptions(features= {"src/test/resources"}, glue= {"com.cucumber"})
public class RunCucumberTest {

}

Execute the tests either through JUnit Runner or Command-Line using maven.

The test Report can be accessed from the link provided in the execution status:

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