Gradle Tutorials

Last Updated On

HOME

Gradle is an open-source build automation tool that is designed to be flexible enough to build almost any type of software.
Gradle runs on the JVM and you must have a Java Development Kit (JDK) installed to use it.
Several major IDEs allow you to import Gradle builds and interact with them: Android Studio, IntelliJ IDEA, Eclipse, and NetBeans.

Installation of Gradle

Chapter 1 How to install Gradle on Windows

Creation of Gradle project

Chapter 1 How to create Java Gradle project in Eclipse
Chapter 2 How to create a Java Gradle project using Command Line
Chapter 3 How to create Gradle project in IntelliJ
Chapter 4 How to create Gradle Java project in IntelliJ using Command Line

Importing of Gradle Project

Chapter 1 How to import Java Gradle project in Eclipse
Chapter 2 How to import Java Gradle project in IntelliJ

Gradle Project in Cucumber

Chapter 1 How To Create Gradle Project with Cucumber to test Rest API
Chapter 2 Run Gradle Cucumber Tests from Command Line
Chapter 3 Gradle Project with Cucumber, Selenium and TestNG
Chapter 4 Gradle Project with Cucumber, Selenium and JUnit4

Gradle Project in Serenity

Chapter 1 Serenity BDD with Gradle and Cucumber for Web Application
Chapter 2 Serenity BDD with Cucumber and Rest Assured in Gradle
Chapter 3 Serenity Emailable Report in Gradle

Gradle Project with Selenium

Chapter 1 How to create Gradle project with Selenium and TestNG
Chapter 2 How to create Gradle project with Selenium and JUnit4
Chapter 3 Gradle – Integration of Selenium and JUnit5

Gradle Project in Rest API

Chapter 1 Setup Basic REST Assured Gradle Project In Eclipse IDE

Allure Reports for Gradle Project

Chapter 1 Gradle – Allure Report for Selenium and TestNG
Chapter 2 Gradle – Allure Report for Selenium and JUnit4
Chapter 3 Gradle – Allure Report for Cucumber, Selenium and TestNG

Extent Reports for Gradle Project

Chapter 1 Gradle – Extent Report Version 5 for Cucumber, Selenium, and TestNG

Gradle with Jenkins

Chapter 1 Integrate Gradle project with Jenkins
Chapter 2 How to create Jenkins pipeline for Gradle project

Extent Reports Version 5 for Cucumber7 and JUnit5

HOME

The previous tutorial explained the steps to generate ExtentReports Version for Cucumber7 with TestNG. This tutorial explains the steps needed to be followed to generate an ExtentReports Version5 for Cucumber 7 with JUnit5.

Prerequisite:

  • Java 17
  • Maven or Gradle
  • JAVA IDE (like Eclipse, IntelliJ, or so on)
  • Cucumber Eclipse plugin (in case using Eclipse)

Project Structure

There is a tutorial that explains the steps to integrate Cucumber 7 with JUnit5. Please refer to this tutorial – Integration of Cucumber7 with Selenium and JUnit5.

Now, let us add the extra steps needed to generate the ExtentRport Version5.

New Features in ExtentReports Version 5

Report Attachments 

To add attachments, like screen images, two settings need to be added to the extent.properties. Firstly property, named screenshot.dir, is the directory where the attachments are stored. Secondly is screenshot.rel.path, which is the relative path from the report file to the screenshot directory.

extent.reporter.spark.out=Reports/Spark.html
 
screenshot.dir=/Screenshots/
screenshot.rel.path=../Screenshots/

Extent PDF Reporter

The PDF reporter summarizes the test run results in a dashboard and other sections with the feature, scenario, and, step details. The PDF report needs to be enabled in the extent.properties file.

#PDF Report
extent.reporter.pdf.start=true
extent.reporter.pdf.out=PdfReport/ExtentPdf.pdf 

Ported HTML Reporter

The original HTML Extent Reporter was deprecated in 4.1.3 and removed in 5.0.0. The HTML report available in the adapter is based on the same code base and is similar in appearance. The major changes are in the Freemarker template code which has been modified to work with the Extent Reports version 5. The HTML report needs to be enabled in the extent.properties file.

#HTML Report
extent.reporter.html.start=true
extent.reporter.html.out=HtmlReport/ExtentHtml.html

Customized Report Folder Name

To enable the report folder name with date and\or time details, two settings need to be added to the extent.properties. These are basefolder.name and basefolder.datetimepattern. These will be merged to create the base folder name, inside which the reports will be generated.

#FolderName
basefolder.name=ExtentReports/SparkReport_
basefolder.datetimepattern=d_MMM_YY HH_mm_ss

Attach Image as Base64 String

This feature can be used to attach images to the Spark report by setting the src attribute of the img tag to a Base64 encoded string of the image. When this feature is used, no physical file is created. There is no need to modify any step definition code to use this. To enable this, use the below settings in extent.properties, which is false by default.

extent.reporter.spark.base64imagesrc=true

Environment or System Info Properties

 It is now possible to add environment or system info properties in the extent.properties or pass them in the maven command line. 

#System Info
systeminfo.os=windows
systeminfo.version=10

Step 1 – Add Maven dependencies to the POM

Add ExtentReport dependency

<dependency>
    <groupId>com.aventstack</groupId>
    <artifactId>extentreports</artifactId>
    <version>5.1.1</version>
</dependency>

Add tech grasshopper maven dependency for Cucumber.

<dependency>
    <groupId>tech.grasshopper</groupId>
    <artifactId>extentreports-cucumber7-adapter</artifactId>
    <version>1.14.0</version>
</dependency>

The complete POM.xml will look like as shown below with other Selenium and JUnit5 dependencies.

<?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>ExtentReports5CucumberJUnit5</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>ExtentReports5CucumberJUnit5</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</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.jupiter.version>5.10.1</junit.jupiter.version>
        <extentreports.cucumber7.adapter.version>1.14.0</extentreports.cucumber7.adapter.version>
        <extentreports.version>5.1.1</extentreports.version>
        <maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
        <maven.surefire.plugin.version>3.2.1</maven.surefire.plugin.version>
        <maven.compiler.source.version>17</maven.compiler.source.version>
        <maven.compiler.target.version>17</maven.compiler.target.version>
    </properties>
 
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.cucumber</groupId>
                <artifactId>cucumber-bom</artifactId>
                <version>${cucumber.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.junit</groupId>
                <artifactId>junit-bom</artifactId>
                <version>${junit.jupiter.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
    <dependencies>
 
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <scope>test</scope>
        </dependency>
 
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit-platform-engine</artifactId>
            <scope>test</scope>
        </dependency>
 
        <!-- JUnit Platform -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <scope>test</scope>
        </dependency>
 
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <scope>test</scope>
        </dependency>
 
        <!-- Selenium -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        
          <!-- Cucumber ExtentReport Adapter -->
        <dependency>
            <groupId>tech.grasshopper</groupId>
            <artifactId>extentreports-cucumber7-adapter</artifactId>
            <version>${extentreports.cucumber7.adapter.version}</version>
        </dependency>
 
        <!-- Extent Report -->
        <dependency>
            <groupId>com.aventstack</groupId>
            <artifactId>extentreports</artifactId>
            <version>${extentreports.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>
                <dependencies>
                    <dependency>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <version>${junit.jupiter.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
 
        </plugins>
    </build>
</project>

Step 2 – Create extent.properties file in src/test/resources

We need to create the extent.properties file in the src/test/resources folder for the grasshopper extent report adapter to recognize it. Using a property file for reporting is quite helpful if you want to define several different properties.

#Extent Report
extent.reporter.spark.start=true
extent.reporter.spark.out=Reports/Spark.html
 
#PDF Report
extent.reporter.pdf.start=true
extent.reporter.pdf.out=PdfReport/ExtentPdf.pdf
 
#HTML Report
extent.reporter.html.start=true
extent.reporter.html.out=HtmlReport/ExtentHtml.html
 
#FolderName
basefolder.name=ExtentReports/SparkReport_
basefolder.datetimepattern=d_MMM_YY HH_mm_ss
 
#Screenshot
screenshot.dir=/Screenshots/
screenshot.rel.path=../Screenshots/
 
#Base64
extent.reporter.spark.base64imagesrc=true
 
#System Info
systeminfo.os=windows
systeminfo.version=10

Step 3 – Create a Cucumber Test Runner class in src/test/java

Add the extent report cucumber adapter to the runner class.

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")
@SelectClasspathResource("com.example")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:") 
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example")
 
public class CucumberRunnerTests  {
 
}

Step 4 – Execute the code

To execute the code, run the tests from the command line by using the below command

mvn clean test

Step 5 – View ExtentReport

Refresh the project and will see a new folder – SparkReport_ which further contains 4 folders – HtmlReport, PdfReport, Reports, and Screenshots.

The ExtentReport will be present in the Reports folder with the name Spark.html. PDF Report is present in the PdfReport folder and HTML Report is present in the HtmlReport folder. We can see that the Screenshots folder is empty because we have used the base64imagesrc feature which resulted in no physical screenshots. The screenshots are embedded in the reports.

Right-click and open the ExtentHtml.html report with Web Browser. The report also has a summary section that displays the summary of the execution. The summary includes the overview of the pass/fail using a pictogram, start time, end time, and pass/fail details of features as shown in the image below.

ExtentHtml

This is the image of the Dashboard of the ExtentReport.

The failed test has a screenshot embedded in it. Double-click on base64 image and it will open the screenshot in full screen.

PDF Report

Spark Report

Right-click and open the Spark.html report with Web Browser.

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

TestNG Tutorials

HOME

Chapter 1 Introduction to TestNG
Chapter 2 How to download and install TestNG in Eclipse
Chapter 3 TestNG Annotations
Chapter 4 Assertions in TestNG
Chapter 5 Hard Assert and Soft Assert
Chapter 6 How to create and run TestNG.xml of a TestNG class
Chapter 7 Run TestNG tests from Command Line
Chapter 8 Execute Testng.xml using batch file
Chapter 9 How to pass Parameters in TestNG
Chapter 10 Prioritizing Test Cases in TestNG: Complete Guide
Chapter 11 How to disable Selenium Test Cases using TestNG Feature – @Ignore
Chapter 12 How to Use dependsOnMethods() in TestNG for Selenium Test Case Dependency
Chapter 13 How to group Tests in Selenium
Chapter 14 InvocationCount in TestNG
Chapter 14 How to run Parallel Tests in Selenium with TestNG
Chapter 15 Cross Browser Testing using Selenium and TestNG
Chapter 16 Screenshot of Failed Test Cases in Selenium WebDriver
Chapter 17 TestNG Listeners in Selenium
Chapter 18 How to Retry failed tests in TestNG – IRetryAnalyzer
Chapter 19 DataProviders in TestNG
Chapter 20 DataProvider in TestNG using Excel
Chapter 21 Parallel testing of DataProviders in TestNG
Chapter 22 TestNG Interview Questions

Test Framework (Maven)

Chapter 1 Integration of REST Assured with TestNG
Chapter 2 Integration of Cucumber with Selenium and TestNG
Chapter 3 Integration Testing of Springboot with Cucumber and TestNG

Test Framework (Gradle)

Chapter 1 How to create Gradle project with Selenium and TestNG
Chapter 2 Gradle Project with Cucumber, Selenium and TestNG

Allure Report with TestNG

Chapter 1 Gradle – Allure Report for Selenium and TestNG
Chapter 2 Gradle – Allure Report for Cucumber, Selenium and TestNG
Chapter 3 Integration of Allure Report with Rest Assured and TestNG
Chapter 4 Gradle – Allure Report for Selenium and TestNG

ExtentReports with TestNG

Chapter 1 ExtentReports Version 5 for Cucumber 6 and TestNG
Chapter 2 PDF ExtentReport for Cucumber and TestNG
Chapter 3 ExtentReports Version 5 for Cucumber 7 and TestNG

Jenkins Tutorial

HOME

Jenkins is a self-contained, open-source automation server that can be used to automate all sorts of tasks related to building, testing, and delivering or deploying software.

Jenkins can be installed through native system packages, Docker, or even run standalone by any machine with a Java Runtime Environment (JRE) installed.

Chapter 1 What is Jenkins?
Chapter 2 How to install Jenkins on Windows 10
Chapter 3 How to configure Java and Maven in Jenkins
Chapter 4 Integration Of Jenkins With Selenium WebDriver
Chapter 5 How to install Maven Plugin in Jenkins
Chapter 6 How to install Plugins from Jenkins CLI?
Chapter 7 Integrate Gradle project with Jenkins
Chapter 8 How to install Plugins in Jenkins
Chapter 9 How to Schedule a Jenkins Job
Chapter 10 Build History Metrics in Jenkins
Chapter 11 How to install the trends-related plugin in Jenkins?
Chapter 12 How to run parameterized Selenium tests in Jenkins

Reports in Jenkins

Chapter 1 How to generate TestNG Report in Jenkins
Chapter 2 How to create JUnit Report in Jenkins
Chapter 3 Integration of Allure Report with Jenkins
Chapter 4 How to generate HTML Reports in Jenkins
Chapter 5 Integration of Cucumber Report with TestNG in Jenkins
Chapter 6 Serenity with Jenkins
Chapter 7 How to publish ExtentReport using Jenkins

Jenkins Pipeline

Chapter 1 Jenkins Pipeline
Chapter 2 How to create Jenkins pipeline for Selenium tests
Chapter 3 How to create Jenkins pipeline for Serenity tests
Chapter 4 How to create Jenkins pipeline for Cucumber tests
Chapter 5 How to create Jenkins pipeline for Extent Report
Chapter 6 How to create Jenkins pipeline for Gradle project

CI/CD

Chapter 1 Integration of GitHub with Jenkins
Chapter 2 Jenkins GitLab Integration

Cucumber Tutorials

 HOME

Cucumber Introduction, Installation, and Configuration

Chapter 1  Introduction of Cucumber Testing Tool (BDD Tool)
Chapter 2 How to install Cucumber Eclipse Plugin
Chapter 3 How to setup Cucumber with Eclipse
Chapter 4 Cucumber – What is Gherkin

Cucumber Scenario, Features & Step Definition

Chapter 1 Cucumber – What is Feature File in Cucumber
Chapter 2 Step Definition in Cucumber
Chapter 3 Cucumber – JUnit Test Runner Class

Cucumber – Hooks & Tags

Chapter 1 Hooks in Cucumber
Chapter 2 Tags in Cucumber
Chapter 3 Conditional Hooks in Cucumber
Chapter 4 Background in Cucumber
Chapter 5 Monochrome in Cucumber

Cucumber – Data Driven Testing

Chapter 1 Data Driven Testing using Scenario Outline in Cucumber
Chapter 2 DataTables in Cucumber

Cucumber Integration with Selenium

Chapter 1 Integration of Cucumber with Selenium and JUnit4
Chapter 2 Integration of Cucumber with Selenium and TestNG
Chapter 3 Page Object Model with Selenium, Cucumber and JUnit
Chapter 4 Page Object Model with Selenium, Cucumber, and TestNG
Chapter 5 Integration of Cucumber7 with Selenium and JUnit5
Chapter 6 Run Cucumber7 with JUnit5 Tests from Maven Command Line
Chapter 7 How to rerun failed tests in Cucumber
Chapter 8 Gradle Project with Cucumber, Selenium and TestNG
Chapter 9 Gradle Project with Cucumber, Selenium and JUnit4

Cucumber – Command Line Execution

Chapter 1 Run Cucumber Test from Command Line
Chapter 2 Run Gradle Cucumber Tests from Command Line

Cucumber Integration with Rest API

Chapter 1 Rest API Test in Cucumber BDD
Chapter 2 How To Create Gradle Project with Cucumber to test Rest API

Cucumber Integration with SpringBoot

Chapter 1 Integration Testing of Springboot with Cucumber and JUnit4
Chapter 2 Integration Testing of Springboot with Cucumber and TestNG

Cucumber – Reporting

Chapter 1 Cucumber Tutorial – Cucumber Reports
Chapter 2 Cucumber Report Service
Chapter 3 Implemention of ‘Masterthought’ Reports in Cucumber
Chapter 4 Implemention of ‘Masterthought’ Reports in Cucumber with JUnit4

Cucumber Integration with Allure Reports

Chapter 1 Allure Report with Cucumber5, Selenium and JUnit4
Chapter 2 Allure Report with Cucumber5, Selenium and TestNG
Chapter 3 Integration of Allure Report with Rest Assured and JUnit4
Chapter 4 Integration of Allure Report with Rest Assured and TestNG
Chapter 5 Gradle – Allure Report for Selenium and TestNG

Cucumber Integration with Extent Reports

Chapter 1 ExtentReports Version 5 for Cucumber 6 and TestNG
Chapter 2 How to add Screenshot to Cucumber ExtentReports
Chapter 3 ExtentReports Version 5 for Cucumber 6 and JUnit4
Chapter 4 PDF ExtentReport for Cucumber and TestNG
Chapter 5 ExtentReports Version 5 for Cucumber 7 and TestNG
Chapter 6 Extent Reports Version 5 for Cucumber7 and JUnit5

Cucumber – Parallel Execution

Chapter 1 Parallel Testing in Cucumber with JUnit
Chapter 2 Parallel Testing in Cucumber with TestNG
Chapter 3 Dependency Injection in Cucumber using Pico-Container

ExtentReports Version 5 for Cucumber 7 and TestNG

HOME

The previous tutorial explained the steps to generate ExtentReports Version for Cucumber6 with TestNG. This tutorial explains the steps needed to be followed to generate an ExtentReports Version5 for Cucumber 7.

New Features in ExtentReports Version 5

Report Attachments 

To add attachments, like screen images, two settings need to be added to the extent.properties. Firstly property, named screenshot.dir, is the directory where the attachments are stored. Secondly is screenshot.rel.path, which is the relative path from the report file to the screenshot directory.

extent.reporter.spark.out=Reports/Spark.html

screenshot.dir=/Screenshots/
screenshot.rel.path=../Screenshots/

Extent PDF Reporter

The PDF reporter summarizes the test run results in a dashboard and other sections with feature, scenario, and, step details. The PDF report needs to be enabled in the extent.properties file.

#PDF Report
extent.reporter.pdf.start=true
extent.reporter.pdf.out=PdfReport/ExtentPdf.pdf

Ported HTML Reporter

The original HTML Extent Reporter was deprecated in 4.1.3 and removed in 5.0.0. The HTML report available in the adapter is based on the same code base and is similar in appearance. The major changes are in the Freemarker template code which has been modified to work with the Extent Reports version 5. The HTML report needs to be enabled in the extent.properties file.

#HTML Report
extent.reporter.html.start=true
extent.reporter.html.out=HtmlReport/ExtentHtml.html

Customized Report Folder Name

To enable the report folder name with date and\or time details, two settings need to be added to the extent.properties. These are basefolder.name and basefolder.datetimepattern. These will be merged to create the base folder name, inside which the reports will be generated.

#FolderName
basefolder.name=ExtentReports/SparkReport_
basefolder.datetimepattern=d_MMM_YY HH_mm_ss

Attach Image as Base64 String

This feature can be used to attach images to the Spark report by setting the src attribute of the img tag to a Base64 encoded string of the image. When this feature is used, no physical file is created. There is no need to modify any step definition code to use this. To enable this, use the below settings in extent.properties, which is false by default.

extent.reporter.spark.base64imagesrc=true

Environment or System Info Properties

 It is now possible to add environment or system info properties in the extent.properties or pass them in the maven command line. 

#System Info
systeminfo.os=windows
systeminfo.version=10

Prerequisite:

  1. Java 8 or higher is needed for ExtentReport5
  2. Maven or Gradle
  3. JAVA IDE (like Eclipse, IntelliJ, or soon)
  4. TestNG installed
  5. Cucumber Eclipse plugin (in case using Eclipse)

Project Structure

Step 1: Add Maven dependencies to the POM

Add ExtentReport dependency

<dependency>
    <groupId>com.aventstack</groupId>
    <artifactId>extentreports</artifactId>
    <version>5.1.1</version>
</dependency>

Add tech grasshopper maven dependency for Cucumber

<dependency>
    <groupId>tech.grasshopper</groupId>
    <artifactId>extentreports-cucumber7-adapter</artifactId>
    <version>1.14.0</version>
</dependency>

The complete POM.xml will look like as shown below with other Selenium and TestNG dependencies.

<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>ExtentReports5Cucumber7TestNG</artifactId>
  <version>0.0.1-SNAPSHOT</version>


<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <cucumber.version>7.14.0</cucumber.version>
        <extentreports.cucumber7.adapter.version>1.14.0</extentreports.cucumber7.adapter.version>
        <extentreports.version>5.1.1</extentreports.version>
        <selenium.version>4.15.0</selenium.version>
        <testng.version>7.8.0</testng.version>   
        <maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
        <maven.surefire.plugin.version>3.2.1</maven.surefire.plugin.version>
        <maven.compiler.source.version>17</maven.compiler.source.version>
        <maven.compiler.target.version>17</maven.compiler.target.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>
 
        <!-- Cucumber ExtentReport Adapter -->
        <dependency>
            <groupId>tech.grasshopper</groupId>
            <artifactId>extentreports-cucumber7-adapter</artifactId>
            <version>${extentreports.cucumber7.adapter.version}</version>
        </dependency>
 
        <!-- Extent Report -->
        <dependency>
            <groupId>com.aventstack</groupId>
            <artifactId>extentreports</artifactId>
            <version>${extentreports.version}</version>
        </dependency>
         
        <!-- Selenium -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
 
 
        <!-- TestNG -->
        <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>
                    <suiteXmlFiles>
                        <suiteXmlFile>testng.xml</suiteXmlFile>
                    </suiteXmlFiles>
                </configuration>
            </plugin>
        </plugins>
    </build>
    </project>

Step 2: Create a feature file in src/test/resources

Below is a sample feature file. I have also added a failed scenario in @FaceBookLink.

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                      |
   | Admin      | admin12$$ | Invalid credentials               |
   | admin$$    | admin123  | Invalid credentials               |
   | abc123     | xyz$$     | Invalid credentials               |
  
  
   @MissingUsername
   Scenario Outline: 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
      
   @FaceBookLink @FailedTest
   Scenario: Verify FaceBook Icon on Login Page
     
    Then User should be able to see FaceBook Icon
    
   @LinkedInLink
   Scenario: Verify LinkedIn Icon on Login Page
     
    Then User should be able to see LinkedIn Icon  
    
   @ForgetPasswordLink
   Scenario: Verify ForgetPassword link on Login Page
     
    When User clicks on Forgot your Password Link
    Then User should navigate to a new page

Step 3: Create extent.properties file in src/test/resources

We need to create the extent.properties file in the src/test/resources folder for the grasshopper extent report adapter to recognize it. Using a property file for reporting is quite helpful if you want to define several different properties.

extent.reporter.spark.start=true
extent.reporter.spark.out=Reports/Spark.html

#PDF Report
extent.reporter.pdf.start=true
extent.reporter.pdf.out=PdfReport/ExtentPdf.pdf

#HTML Report
extent.reporter.html.start=true
extent.reporter.html.out=HtmlReport/ExtentHtml.html

#FolderName
basefolder.name=ExtentReports/SparkReport_
basefolder.datetimepattern=d_MMM_YY HH_mm_ss

#Screenshot
screenshot.dir=/Screenshots/
screenshot.rel.path=../Screenshots/

#Base64
extent.reporter.spark.base64imagesrc=true

#System Info
systeminfo.os=windows
systeminfo.version=10

Step 4: Create a Helper class in src/main/java

We have used the Page Object Model with Cucumber and TestNG. 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 org.openqa.selenium.support.ui.WebDriverWait;
import io.github.bonigarcia.wdm.WebDriverManager;
 
public class HelperClass {
     
    private static HelperClass helperClass;
     
    private static WebDriver driver;
    private static WebDriverWait wait;
    public final static int TIMEOUT = 10;
     
     private HelperClass() {
	              
	    	 ChromeOptions options = new ChromeOptions();
	         options.addArguments("--start-maximized");
	         driver = new ChromeDriver(options);
	         driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT));
	     }    
             
    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 5: Create Locator classes in src/main/java

Create a locator class for each page that contains the details of the locators of all the web elements. Here, I’m creating 2 locator classes – LoginPageLocators and HomePageLocators.

LoginPageLocators

package com.example.locators;

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[1]/div/span")
    public WebElement missingUsernameErrorMessage;
    
    @FindBy(xpath = "//*[@id='app']/div[1]/div/div[1]/div/div[2]/div[2]/form/div[1]/div/span")
    public WebElement missingPasswordErrorMessage;
 
    @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.linkedin.com/company/orangehrm/mycompany/']")
    public  WebElement linkedInIcon;
    
    @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[4]/p")
    public  WebElement ForgotYourPasswordLink;
    
}

HomePageLocators

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

public class HomePageLocators {

	 @FindBy(xpath = "//*[@class='oxd-topbar-header-breadcrumb']/h6")
	public  WebElement homePageUserName;
 
}
package com.example.locators;

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

public class ForgotPasswordLocators {

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

}

Step 6: Create Action classes in src/main/java

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 – LoginPageActions and HomePageActions.

LoginPageActions

In this class, the very first thing will do is to create the object of LoginPageLocators class so that we should be able to access all the PageFactory elements. Secondly, create a public constructor of LoginPageActions class

package com.example.actions;

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);
	}
 
	// Set user name in textbox
    public void setUserName(String strUserName) {
    	loginPageLocators.userName.sendKeys(strUserName);
    }
 
    // Set password in password textbox
    public void setPassword(String strPassword) {
    	loginPageLocators.password.sendKeys(strPassword);
    }
 
    // Click on login button
    public void clickLogin() {
    	loginPageLocators.login.click();
    }
 
    // Get the title of Login Page
    public String getLoginTitle() {
        return loginPageLocators.titleText.getText();
    }
    
   // Get the error message when username is blank
    public String getMissingUsernameText() {
        return loginPageLocators.missingUsernameErrorMessage.getText();
    }
    
   // Get the error message when password is blank
    public String getMissingPasswordText() {
        return loginPageLocators.missingPasswordErrorMessage.getText();
    }
    
    
    // Get the Error Message
    public String getErrorMessage() {
        return loginPageLocators.errorMessage.getText();
    }
    
    // LinkedIn Icon is displayed
    public Boolean getLinkedInIcon() {
   
        return loginPageLocators.linkedInIcon.isDisplayed();
    }
    
    // FaceBook Icon is displayed
    public Boolean getFaceBookIcon() {
   
        return loginPageLocators.faceBookIcon.isDisplayed();
    }
    
    // Click on Forget Your Password link
    public void clickOnForgetYourPasswordLink() {
    	
    	loginPageLocators.ForgotYourPasswordLink.click();
    }
 
    public void login(String strUserName, String strPassword) {
 
        // Fill user name
        this.setUserName(strUserName);
 
        // Fill password
        this.setPassword(strPassword);
 
        // Click Login button
        this.clickLogin();
 
    }
}

HomePageActions

package com.example.actions;

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();
    }
  
}

package com.example.actions;

import org.openqa.selenium.support.PageFactory;

import com.example.locators.ForgotPasswordLocators;
import com.example.utils.HelperClass;

public class ForgotPasswordActions {

	ForgotPasswordLocators forgotPasswordLocators = null;
	   
	public ForgotPasswordActions() {
    	
		this.forgotPasswordLocators = new ForgotPasswordLocators();

		PageFactory.initElements(HelperClass.getDriver(),forgotPasswordLocators);
    }
 
    // Get the Heading of Forgot Password page
    public String getForgotPasswordPageText() {
        return forgotPasswordLocators.ForgotPasswordHeading.getText();
    }
}

Step 7: Create a Step Definition file in src/test/java

Create the corresponding Step Definition file of the feature file.

LoginPageDefinitions

package com.example.definitions;


import org.testng.Assert;
import com.example.actions.ForgotPasswordActions;
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();
    ForgotPasswordActions objForgotPasswordPage = new ForgotPasswordActions();
 
    @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
        
    }
    
    @When("User clicks on Forgot your Password Link")
    public void goToForgotYourPasswordPage() {
    	
    	objLogin.clickOnForgetYourPasswordLink();
    	
    }
 
    @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);
    }
    
    @Then("User should be able to see LinkedIn Icon")
    public void verifyLinkedInIcon( ) {
    	
    	Assert.assertTrue(objLogin.getLinkedInIcon());
    }
    
    @Then("User should be able to see FaceBook Icon")
    public void verifyFaceBookIcon( ) {
    	
    	Assert.assertTrue(objLogin.getFaceBookIcon());
    }
    
    @Then("User should navigate to a new page")
    public void verfiyForgetYourPasswordPage() {
    	
    	Assert.assertEquals(objForgotPasswordPage.getForgotPasswordPageText(), "Reset Password");
    }
      
}

Step 8: Create Hook class in src/test/java

Create the hook class that contains the Before and After hook. @Before hook contains the method to call the setup driver which will initialize the chrome driver. This will be run before any test.

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 9: Create a Cucumber Test Runner class in src/test/java

Add the extent report cucumber adapter to the runner class’s CucumberOption annotation.

plugin = {"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"})

The updated Cucumber Runner class looks like as shown below:

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

Step 10: Create the testng.xml for the project

Right-click on the project and select TestNG -> convert to TestNG.

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

Step 11: Execute the code

Right-click on the Runner class and select Run As -> TestNG Test.

Below is the screenshot of the Console. As expected, 4 tests, out of 5 are passed and 1 failed.

Step 12: View ExtentReport

Refresh the project and will see a new folder – SparkReport_ which further contains 4 folders – HtmlReport, PdfReport, Reports, and Screenshots.

The ExtentReport will be present in the Reports folder with the name Spark.html. PDF Report is present in PdfReport folder and the HTML Report is present in HtmlReport folder. We can see that the Screenshots folder is empty because we have used the base64imagesrc feature which results in no physical screenshots. The screenshots are embedded in the reports.

Right-click and open the ExtentHtml.html report with Web Browser. The report also has a summary section that displays the summary of the execution. The summary includes the overview of the pass/fail using a pictogram, start time, end time, and pass/fail details of features as shown in the image below.

ExtentHtml.html

The failed test has a screenshot embedded in it. Double-click on mase64image and it will open the screenshot in full screen.

Screenshot of failed Test Case

PDF Report

Spark Report

Right-click and open the Spark.html report with Web Browser.

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

How to add Screenshot to Cucumber ExtentReports
PDF ExtentReport for Cucumber and TestNG
ExtentReports Version 5 for Cucumber 7 and TestNG
Extent Reports Version 5 for Cucumber7 and JUnit5
Gradle – Extent Report Version 5 for Cucumber, Selenium, and TestNG

How To Publish ExtentReport Using Jenkins

Last Updated On

HOME

In the previous tutorial, we have seen the Integration of Allure Report with Jenkins. In this tutorial, we show you how to generate Extent Report Using Jenkins. 

Table of Contents

  1. Prerequisite
  2. Implementation Steps
    1. Create a new Maven project
    2. Build Management
    3. Select a custom workspace
    4. Select “Publish HTML reports” from “Post Build Actions”
    5. Execute the tests
    6. View the Extent Report

Prerequisite

Jenkin’s installed and started on the computer. The current Jenkins version is – 2.361.2

To generate HTML Report in Jenkins, we need to download HTML Publisher Plugin. Please refer to this tutorial to install the plugin – How to install Plugins in Jenkins.

Implementation Steps

Step 1: Create a new Maven project

  1. Give the Name of the projectExtentReport_Demo
  2. Click on the Maven project. 
  3. Click on the OK button.

In the General section, enter the project description in the Description box.

Select Source Code Management as None if the project is locally present on the machine.

Step 2: Build Management

Go to the Build section of the new job.

  1. In the Root POM textbox, enter the full path to pom.xml
  2. In the Goals and options section, enter “clean test site”

Here, I have used the Selenium project with JUnit, so to see the complete project, please refer to this tutorial –  How to generate JUnit4 Report.

Click on the Advanced button.

Step 3: Select a custom workspace

Mention the full path of the project in the directory.

Step 4: Select “Publish HTML reports” from “Post Build Actions”

Scroll down to “Post Build Actions” and click on the “Add Post Build Actions” drop-down list. Select “Publish HTML reports“. 

If you want to see where the report is saved in Jenkins, go to the Dashboard ->ExtentReport_Demo project -> Workspace ->target -> Reports -> Spark.html.

Enter the HTML directory to archive – Reports, Index page[s] – Spark.html, and Report title – Extent Report.

Click on the Apply and Save buttons.

We have created a new Maven project “ExtentReport_Demo” with the configuration to run the Cucumber, and Selenium with TestNG Tests and also to generate HTML Report after execution using Jenkins.

Step 5: Execute the tests

Let’s execute it now by clicking on the “Build Now” button.

Right-click on Build Number (here in my case it is #4).

Click on Console Output to see the result.

Step 6: View the Extent Report

Once the execution is completed, click on go “Back to Project“, and we can see a link to view the “Extent Report“.

We can see here that the Extent Report link is displayed in the Console.

Below is the Extent Report generated in Jenkins.

Tip: If you don’t see the Report UI intact, then you need to configure a simple Groovy script. For that, go to Dashboard–>Manage Jenkins–>Script Console and add the script as:

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","")

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

Additional Tutorials

Serenity with Jenkins
Integration of Allure Report with Jenkins
How to generate HTML Reports in Jenkins
How to create Jenkins pipeline for Serenity tests
How to create Jenkins pipeline for Cucumber tests

How to create Jenkins pipeline for Extent Report

Last Updated On

HOME

In the previous tutorial, I discussed the Jenkins pipeline. This tutorial will discuss the steps to create the Jenkins pipeline for ExtentReport.

Table of Contents

  1. Prerequisite
  2. Implementation Steps
    1. Create a new pipeline project
    2. Scroll down to Pipeline
    3. Create Jenkinsfile
    4. Specify branches to build a section under Repositories
    5. Execute the tests
    6. Pipeline Steps
    7. View the Report

Prerequisite

Jenkins was installed and started on the computer.

Implementation Steps

Step 1: Create a new pipeline project.

  1. Give the Name of the projectExtentReport_PipelineDemo
  2. Click on the pipeline project. 
  3. Click on the OK button.

In the General section, enter the project description in the Description box.

Step 2: Scroll down to Pipeline

From the Definition field, choose the “Pipeline script from SCM” option. This option instructs Jenkins to obtain your Pipeline from Source Control Management (SCM), which will be your locally cloned Git repository.

From the SCM field, choose Git.

The Repositories section contains the Repository URL and Credentials.

In the Repository URL field, specify the directory path of the GitLab/GitHub project.

In the Credentials field, specify the username and password needed to log in to GitLab/GitHub.

In this case, I have the project is present in GitLab and using it.

Step 3: Create Jenkinsfile

Create and save a new text file with the name Jenkinsfile at the root of the project in the GitLab repository. Here, we are using the Selenium project with TestNG. To know more about the Integration of Selenium with TestNG, please refer to this tutorial –

For this tutorial, we are using Declarative syntax. The sample example is given below:

pipeline {
    agent any
 
    stages {
        stage('Test') {
            steps {
                bat "mvn -D clean test"
            }
 
            post {                
                
				// If Maven was able to run the tests, even if some of the test
                // failed, record the test results and archive the jar file.               
				success {
                  publishHTML([
				              allowMissing: false, 
				              alwaysLinkToLastBuild: false, 
							  keepAll: false, 
							  reportDir: 'Reports', 
							  reportFiles: 'Spark.html', 
							  reportName: 'ExtentReport', 
							  reportTitles: '', 
							  useWrapperFileDirectly: true])
				}
            }
        }
    }
}

Step 4: Specify branches to build a section under Repositories

  1. Branch Specifier – */master (This is my main branch)
  2. ScriptPath – Jenkinsfile

Click on the Apply and Save buttons.

We have created a new Maven project ExtentReport_PipelineDemo” with the configuration to run the Selenium Test with TestNG.

Step 5: Execute the tests

Let’s execute it now by clicking on the “Build Now” button. 

Right-click on Build Number (here in my case it is #1) and click on Console Output to see the result.

Below is the test execution summary.

Step 6: Pipeline Steps

Once the execution is completed, and we want to see the Pipeline Steps, click on the Pipeline Steps mentioned on the left side of the page.

Step 7: View the Report

Once the execution is completed, go back to ExtentReport_PipelineDemo. We can see below that the ExtentReport is generated.

We could see a link to view “ExtentReport“. Click on the ExtentReport. It displays the Spark.html Report.

Tip: If you don’t see the Report UI intact, then you need to configure a simple groovy script. For that, go to Dashboard–>Manage Jenkins–>Script Console and add the script as:

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","")

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

Additional Tutorials

How to install Plugins from Jenkins CLI?
Jenkins GitLab Integration
How to create Jenkins pipeline for Selenium tests
How to create Jenkins pipeline for Serenity tests
How to create Jenkins pipeline for Cucumber tests
How to run parameterized Selenium tests in Jenkins

Extent Reports

HOME

We can create beautiful, interactive, and detailed reports for your tests using the Extent Reports library. Add events, screenshots, tags, devices, authors, or any other relevant information you deem necessary to create a descriptive and visually appealing report that you have complete control over.

Chapter 1  ExtentReports Version 4 with Selenium and TestNG
Chapter 2  ExtentReports Version 4 for Cucumber 5, Selenium, and TestNG
Chapter 3  ExtentReports Version 5 for Cucumber 6 and TestNG
Chapter 4  How to add Screenshot to Cucumber ExtentReports
Chapter 5  ExtentReports Version 5 for Cucumber 6 and JUnit4
Chapter 6  PDF ExtentReport for Cucumber and TestNG
Chapter 7  ExtentReports Version 5 for Cucumber 7 and TestNG
Chapter 8  Extent Reports Version 5 for Cucumber7 and JUnit5
Chapter 9  Gradle – Extent Report Version 5 for Cucumber, Selenium, and TestNG
Chapter 10  Gradle – ExtentReports Version 5 for Cucumber, Selenium and JUnit4
Chapter 11 How to host Extent Report on GitHub Pages with Github Actions – NEW

ExtentReports Version 4 for Cucumber 5, Selenium, and TestNG

HOME

The previous tutorial explained the generation of Allure Report with Cucumber5, Selenium and TestNG in a Maven project. In this tutorial, I will explain the steps to create an Extent Report4 with Cucumber5, Selenium, and TestNG in a Maven project.

Pre-Requisite:

  1. Java 8 or higher is needed for ExtentReport5
  2. Maven
  3. JAVA IDE (like Eclipse, IntelliJ, or so on)
  4. TestNG installed
  5. Cucumber Eclipse plugin (in case using Eclipse)

Project Structure

Step 1 – Add Maven dependencies to the POM

Add ExtentReport dependency.

<!-- Extent Report -->
<dependency>
	<groupId>com.aventstack</groupId>
	<artifactId>extentreports</artifactId>
	<version>${extentreports.version}</version>
</dependency>

Add tech grasshopper maven dependency for Cucumber. The below version of extentreports-cucumber5-adapter dependency needs to be added to the POM, to work with ExtentReports version 4.

<!-- Cucumber ExtentReport Adapter -->
<dependency>
	<groupId>tech.grasshopper</groupId>
	<artifactId>extentreports-cucumber5-adapter</artifactId>
	<version>1.51</version>
</dependency>

If you want to use ExtentReport Version5, then use version – 2.13.0.

The complete POM.xml will look as shown below with other Selenium and TestNG dependencies.

<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<cucumber.version>5.7.0</cucumber.version>
		<extentreports.cucumber5.adapter.version>1.5.1</extentreports.cucumber5.adapter.version>
		<extentreports.version>4.1.7</extentreports.version>
		<selenium.version>3.141.59</selenium.version>
		<webdrivermanager.version>5.2.1</webdrivermanager.version>
		<testng.version>6.14.3</testng.version>
		<apache.common.version>2.4</apache.common.version>		
		<maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
		<maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
		<maven.compiler.source.version>11</maven.compiler.source.version>
		<maven.compiler.target.version>11</maven.compiler.target.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>

		<!-- Cucumber ExtentReport Adapter -->
		<dependency>
			<groupId>tech.grasshopper</groupId>
			<artifactId>extentreports-cucumber5-adapter</artifactId>
			<version>${extentreports.cucumber5.adapter.version}</version>
		</dependency>

		<!-- Extent Report -->
		<dependency>
			<groupId>com.aventstack</groupId>
			<artifactId>extentreports</artifactId>
			<version>${extentreports.version}</version>
		</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>

	</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>
					<suiteXmlFiles>
						<suiteXmlFile>testng.xml</suiteXmlFile>
					</suiteXmlFiles>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Step 2: Create a feature file in src/test/resources

Below is a sample feature file. I have added 2 failed scenarios – @FaceBookLink(Invalid XPath) and @MissingUsername (Incorrect Verification).

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 opens
    
   @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               |
   | admin123   | Admin     | Invalid credentials               |
   | $$$$$$$    | &&&&&&&&  | Invalid credentials               |
      
  @FaceBookLink
  Scenario: Verfy FaceBook Icon on Login Page
     
    Then User should be able to see FaceBook Icon
    
  @MissingUsername
  Scenario: Verify error message when username is missing
     
    When User enters username as "" and password as "admin123"
    Then User should be able to see error message for empty username as "Empty Username"
   

Step 3: Create extent.properties file in src/test/resources

We need to create the extent.properties file in the src/test/resources folder for the grasshopper extent report adapter to recognize it. Using a property file for reporting is quite helpful if you want to define several different properties.

Let’s enable spark report in an extent properties file:

extent.reporter.avent.start=false
extent.reporter.bdd.start=false
extent.reporter.cards.start=false
extent.reporter.email.start=false
extent.reporter.html.start=true
extent.reporter.klov.start=false
extent.reporter.logger.start=true
extent.reporter.tabular.start=false

extent.reporter.avent.config=
extent.reporter.bdd.config=
extent.reporter.cards.config=
extent.reporter.email.config=
extent.reporter.html.config=
extent.reporter.klov.config=
extent.reporter.logger.config=
extent.reporter.tabular.config=

extent.reporter.avent.out=Reports/AventReport/
extent.reporter.bdd.out=Reports/BddReport/
extent.reporter.cards.out=Reports/CardsReport/
extent.reporter.email.out=Reports/EmailReport/ExtentEmail.html
extent.reporter.html.out=Reports/HtmlReport/ExtentHtml.html
extent.reporter.logger.out=Reports/LoggerReport/
extent.reporter.tabular.out=Reports/TabularReport/

#Screenshot
screenshot.dir=Reports/Screenshots/
screenshot.rel.path=../Screenshots/

Step 4: Create a Helper class in src/main/java

We have used Page Object Model with Cucumber and TestNG.

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. We are using a setter and getter method to get the object of Chromedriver with the help of a private constructor itself within the same class.

HelperClass

import java.util.concurrent.TimeUnit;
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(TIMEOUT,TimeUnit.SECONDS);
	        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 5: Create Locator classes in src/main/java

Create a locator class for each page that contains the detail of the locators of all the web elements. Here, I’m creating 2 locator classes – LoginPageLocators and HomePageLocators.

LoginPageLocators

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

public class LoginPageLocators {

	@FindBy(name = "txtUsername")
    public WebElement userName;
 
    @FindBy(name = "txtPassword")
    public WebElement password;
 
    @FindBy(id = "logInPanelHeading")
    public WebElement titleText;
 
    @FindBy(id = "btnLogin")
    public WebElement login;
 
    @FindBy(id = "spanMessage")
    public  WebElement errorMessage;
    
    @FindBy(xpath = "//*[@id='social-icons']/a[1]/img")
    public  WebElement linkedInIcon;
    
    @FindBy(xpath = "//*[@id='social-icons']/a[6]/img")  //Invalid Xpath
    public  WebElement faceBookIcon;
     
}

HomePageLocators

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

public class HomePageLocators {

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

Step 6: Create Action classes in src/main/java

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 – LoginPageActions and HomePageActions

LoginPageActions

In this class, the very first thing will do is to create the object of the LoginPageLocators class so that we should be able to access all the PageFactory elements. Secondly, create a public constructor of LoginPageActions class.

package com.example.testng.actions;

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();
    }
    
    // FaceBook Icon is displayed
    public Boolean getFaceBookIcon() {
   
        return loginPageLocators.faceBookIcon.isDisplayed();
    }
    
    // Get the error message when username is blank
    public String getMissingUsernameText() {
         return loginPageLocators.missingUsernameErrorMessage.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();
    }

}

Step 7: Create a Step Definition file in src/test/java

Create the corresponding Step Definition file of the feature file.

LoginPageDefinitions

import org.testng.Assert;
import com.example.testng.actions.HomePageActions;
import com.example.testng.actions.LoginPageActions;
import com.example.testng.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 sucessfully and new page opens")
    public void verifyLogin() {
 
        // Verify home page
       Assert.assertTrue(objHomePage.getHomePageText().contains("Employee Information"));
 
    }
    
    @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 FaceBook Icon")
    public void verifyFaceBookIcon( ) {
    	
    	Assert.assertTrue(objLogin.getFaceBookIcon());
    }     

    @Then("User should be able to see error message for empty username as {string}")
    public void verifyErrorMessageForEmptyUsername(String expectedErrorMessage) {
    	 
    	Assert.assertEquals(objLogin.getMissingUsernameText(),expectedErrorMessage);
 
    }      
}

Step 8: Create Hook class in src/test/java

Create the hook class that contains the Before and After hooks. @Before hook contains the method to call the setup driver which will initialize the chrome driver. This will be run before any test.

After Hook – Here will call the tearDown method.

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import com.example.testng.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 9: Create a Cucumber Test Runner class in src/test/java

Add the extent report cucumber adapter to the runner class’s CucumberOption annotation. 

 plugin = {"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"}

This is how your runner class should look after being added to our project. Moreover, be sure to keep the colon “:” at the end.

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 = {"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"})
 
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {
 
}

Step 10: Create the testng.xml for the project

Right-click on the project and select TestNG -> convert to TestNG.

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

Step 11: Execute the code

Right Click on the Runner class and select Run As -> TestNG Test.

Below is the screenshot of the Console. As expected, 5 tests, out of 7 are passed and 2 failed.

Step 12: View ExtentReport

Refresh the project and will see a new folder – Report. The ExtentReport will be present in that folder with the name Spark.html.

Right-click and select Open with Web Browser.

The report also has a summary section that displays the summary of the execution. The summary includes the overview of the pass/fail using a pictogram, start time, end time, and pass/fail details of features as shown in the image below.

Click on the Dashboard icon present on the left side of the report. To view the details about the steps, click on the scenarios. Clicking on the scenario will expand, showing off the details of the steps of each scenario.

The icon present at the end of the failed scenario is highlighted, click on that icon. It is the screenshot of the failed test.

Logger Report

This is the Dashboard Report.

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