Cucumber-JVM 7 Report generation using ExtentReports Adapter plugin

NEW Posts – Generating Spark and Pdf Extent Report for “Rest Assured with Maven plugin” and “Rest Assured and Cucumber with Maven plugin”

Introduction

This article deals with generating Extent reports for Cucumber-JVM version 7 using the ExtentReports Cucumber Adapter Plugin. The article details out the procedure to create Spark, Logger, Json and PDF reports. The adapter plugin is available in the tech.grasshopper groupid in Maven repository. This is based on the existing adapter for version 5 and 6 with changes made to work with version 7.

IMPORTANT – ExtentReports has been updated to version 5, which has resulted in multiple reporters getting deprecated. Currently this only supports the Spark, Json and Klov reports. The adapter generates only these three reports, along with the custom PDF and HTML reports.

The various steps required for this are to add the adapter dependency to the POM, configure plugin in the runnerenable report generation and modify report settings.

The adapter also generates the new PDF report. Among other new features are the ability to have customized report folder names with timestamps, adding base64 string images and setting the display order of Spark report. Also a technique for merging reports obtained in rerun executions is mentioned. Detailed explanation of these features are available in the separate sections.

An article for creating Extent Report using a Cucumber-JVM 6 adapter can be found here and for Cucumber-JVM 5 adapter can be found here and for Cucumber-JVM 4 adapter can be found here.

To create Extent Report using a Maven plugin, which uses the Cucumber JSON report and runs in the post-integration-test phase, refer to this article. This plugin is independent of Cucumber version and works for JSON report generated with Cucumber versions 4.3.0 and above.

Source

The source code for the article is located here. The source code for extentreports-cucumber7-adapter plugin is located here. The artifact can be found in Maven at this location.

POM Dependencies

The latest version of extentreports-cucumber7-adapter dependency needs to be added to the POM, to work with ExtentReports version 5.

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

The POM for this configuration is located here.

Plugin Configuration

The extentreports-cucumber7-adapter plugin needs to be added to the CucumberOptions annotation of the runner.

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

Add the colon ‘:’ at the end of the plugin argument, else below exception is thrown.

cucumber.runtime.CucumberException: You must supply an output argument to com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.

Report Activation

First method of activating the report generation is to place extent.properties file in the src/test/resources folder or in the src/test/resources/com/avenstack/adapter folder to be picked up by the adapter. This is ideal for setting up large number of properties. The complete settings for logger and html can be found here. Below examples show the case of the spark report.

extent.reporter.spark.start=true
extent.reporter.spark.out=test-output/SparkReport/Spark.html

Second way is to add the required key and value pairs to the System properties. There are again two ways of achieving it.

One way is to add the properties to the configuration section of the Maven Surefire or Failsafe plugin. This is also ideal for setting up large number of properties

<configuration>
    <systemPropertyVariables>
        <extent.reporter.spark.start>true</extent.reporter.spark.start>
        <extent.reporter.spark.out>test-output/SparkReport/Spark.html</extent.reporter.spark.out>
    </systemPropertyVariables>
</configuration>

Other way is to pass the property key-values in the Maven command. This is useful for small number of properties.

mvn clean install -DargLine="-Dextent.reporter.spark.start=true -Dextent.reporter.spark.out=test-output/SparkReport/Spark.html"

Report Settings

The configurations like report activation and location can be mentioned in the extent.properties or using maven settings as shown in the section above. To change settings like theme, title, encoding etc, a separate xml file eg. spark-config.xml is required. The location for this file eg. html report needs to be mentioned as value for the key extent.reporter.html.config.

extent.reporter.spark.config=src/test/resources/spark-config.xml

This xml location key-value pair can also be set using Maven plugin configuration or command line as in the section above. The complete settings for logger and html can be found here.

All that is left to execute the POM and check the reports.

Report Attachments

To add attachments, like screen images, two settings need to be added to the extent.properties. First property, named screenshot.dir, is the directory where the attachments are stored. Second is screenshot.rel.path, which is the relative path from the report file to the screenshot directory. In the below setting, the Spark report (named index.html by default) will navigate to the saved attachments by using the relative path setting.

extent.reporter.spark.out=test-output/SparkReport/

screenshot.dir=test-output/
screenshot.rel.path=../

A more expanded scenario could be storing the images in a folder named ‘screenshots’ and the reports generated in the ‘test-output’ folder. The ‘screenshots‘ and the ‘test-output‘ folders are at the same level. The report will need to step down two folder levels and then move to the required directory.

extent.reporter.spark.out=test-output/SparkReport/

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

If the reports and screenshot are configured to be located in the same folder, then set the screenshot.rel.path value to “./”.

The HTML report also uses the same logic for displaying attachments.

Excel Extent Report [New Feature]

The Excel reporter summarizes the test run results in a dashboard worksheet and other worksheets with feature, scenario, exception, tags, authors and devices details. The dashboard and exception sheets are non-editable.

This report needs to be enabled in the extent.properties file.

extent.reporter.excel.start=true
extent.reporter.excel.out=test output/ExcelReport/ExtentExcel.xlsx

An image of the dashboard worksheet is displayed on the right. A sample report can be found here.

This report gives a high level overview of the test execution. This does not provide step level details such as step text, logs, screenshots etc.

Do not use this report if the setup contains multiple runners as concurrent modification of the same excel file will result in errors.

An article dedicated for this feature will be created soon.

PDF Extent Report [New Feature]

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

extent.reporter.pdf.start=true
extent.reporter.pdf.out=test output/PdfReport/ExtentPdf.pdf

A sample report can be found here.

The default color settings can be modified by using a YAML config file, named pdf-config.yaml in the project src/test/resource folder. There are configuration changes in the latest version.

Do not use this report if the setup contains multiple runners as concurrent modification of the same PDF will result in errors. Better solution would be use a Maven plugin for creating just the PDF report or the complete ExtentReport suite.

The detailed documentation for this feature is available in this article.

Device & Author Tags [New Feature]

The device and author information can be added to the feature files as tags for the feature, scenario, scenario outline and examples keyword. This feature needs to be enabled in the extent.properties file. These tags need to be a prefixed with a predefined character sequence and these will be treated separately from the categories tags. This will display the device and author details in respective tabs of the Spark report. Also the scenario counts will be displayed in the dashboard for both.

The extent.reporter.spark.enable.device and extent.reporter.spark.enable.author settings need to be set to true, for the device and author information to be displayed. Both or one of them can be enabled.

extent.reporter.spark.enable.device=true
extent.reporter.spark.enable.author=true

The default prefix for the device tag is ‘@dev_‘ and for the author it is ‘@aut_‘. The case is ignored. For example the device tag will be ‘@dev_iphone’ and author will be ‘@aut_bloch’. These default values can be changed by using the extent.reporter.spark.prefix.device and extent.reporter.spark.prefix.author settings.

extent.reporter.spark.prefix.device=@device_
extent.reporter.spark.prefix.author=@author_

This feature is available from version 1.8.0 and higher. This currently works only for the Spark and HTML reports.

Spark & PDF Report Status Filter [New Feature]

The Spark and PDF report can be filtered by status, with the help of extent.reporter.statusfilter setting in the extent.properties. This takes a comma delmited case insensitive value of statuses. This corresponds to the ExtentReport status. The filter is applied at the feature level.

The valid values are pass, fail, skip, info and warning. The first three statuses will be most relevant. If an invalid status is provided then this will fail silently and this setting will be ignored.

#Failed and skipped
extent.reporter.statusfilter=fail,skip

#Only passed
extent.reporter.statusfilter=pass

This feature is available from version 1.8.4 and higher. This currently works only for the Spark and PDF reports.

Ported HTML Extent Report [New Feature]

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 have been modified to work with the Extent Reports version 5. The report code can be found at this location.

The HTML report needs to be enabled in the extent.properties file.

extent.reporter.html.start=true
extent.reporter.html.out=test-output/HtmlReport/ExtentHtml.html

To change settings like theme, title, encoding, offlineMode etc, a separate xml file eg. html-config.xml is required. The location for this file eg. html report needs to be mentioned as value for the key extent.reporter.html.config.

extent.reporter.html.config=src/test/resources/html-config.xml

Customized Report Folder Name [New Feature]

To enable 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. The basefolder.datetimepattern value should be a valid date time formatter pattern.

extent.reporter.spark.out=test-output/SparkReport/

screenshot.dir=test-output/
screenshot.rel.path=../

basefolder.name=reports
basefolder.datetimepattern=d-MMM-YY HH-mm-ss

With the above settings, a base folder with the name reports 10-Aug-20 10-25-50 will contain the reports. Screenshots if any, will be located inside the reports 10-Aug-20 10-25-50/test-output folder structure. Similarly the report will be created in the reports 10-Aug-20 10-25-50/test-output/SparkReport folder structure. The point to remember is that the generated folder name should be valid for the underlying file system.

The delimiter between the name and date time pattern can be controlled by using the basefolder.enable.delimiter setting. The default value is true. When this is set to false, there is no space between the name and pattern. The delimiter value can customized by using the basefolder.delimiter setting. The default value is space.

#default is true
basefolder.enable.delimiter=true

#default is space. Custom delimiter
basefolder.delimiter=_

When the basefolder settings are not provided, the reports and related files are generated without any additional folder. Example of the settings can be found in the sample extent.properties file.

Spark Report View Order [New Feature]

The default tab view order of the Spark reporter is – test, exception, category, device, author, log, dashboard tabs. Currently this order is fixed and cannot be changed. This new feature allows the order to be changed by adding the extent.reporter.spark.vieworder in the extent.properties files. The below value will display the report with the dashboard tab as default.

extent.reporter.spark.vieworder=dashboard,test,category,exception,author,device,log

The value needs to be a comma delimited text without any spaces. Any error in parsing will silently use the default view order. To restrict the number of tabs, just mention the name of the required tabs. For example, if only the test and dashboard views are needed use the below setting

extent.reporter.spark.vieworder=dashboard,test

An example of a complete file can be found here.

Attach Image as Base64 String [New Feature]

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

The Spark report file size will be pretty large and there could be memory issues if a substantial number of images are present. A generic thumbnail is created and on clicking the image is displayed. To include an image thumbnail, add the following configuration to the Spark configuration file.

<thumbnailForBase64>true</thumbnailForBase64>

Merging Rerun Reports [New Feature]

This feature is not part of the adapter but Spark rerun reports can be merged by using the artifact mentioned in this article. This will require the generation of JSON Extent report in the Cucumber execution.

Below is the setting for JSON report generation.

extent.reporter.json.start=true
extent.reporter.json.out=test-output/JsonReport/Json.json

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. These key value pairs are displayed in the ‘Environment’ section of the dashboard page. The key string should begin with the prefix – ‘systeminfo.‘. Be careful of the dot at the end.

These can be added to the extent.properties as following – ‘systeminfo.os=windows‘. For passing the values in maven command use as following – ‘-Dsysteminfo.core=16‘. Both methods can be used simultaneously, the report will display all the values.

Parallel And\Or Multiple Runner Execution

There is no additional configuration settings required for parallel execution with a single or multiple runners. This is also true for single threaded multiple runner execution.

For parallel execution using JUnit refer here and for TestNG refer here.

160 thoughts on “Cucumber-JVM 7 Report generation using ExtentReports Adapter plugin”

  1. Hi mounish,

    I wanted to check with you if there is a way to access the path of the generated report ( im using properties to generate a report folder based on execution date) to upload them to ci cd piepline or test management tool as an attachment , since we use a base64image i want the html report to be attached

    Let me know if there is any way to do so

  2. Hi Mounish,
    I’m using Scenario Outline. Is it possible to list individual example as a test rather grouping it under scenario outline on extent spark report?
    I’m using Adaptor 7 (1.14.0), Java 11 and Cucumber (7.2.3).
    Ex:
    Scenario Outline : Sample test to run
    Given user is on login screen
    And user enters
    And user enters
    When user clicks on submit button
    Then user should be logged in
    Examples:
    | userId | password |
    | testUser1 | testPassword1 |
    | testUser2 | testPassword2 |

    Now on report these 2 examples gets grouped under scenario outline. is it possible to list 2 examples as 2 separate test cases?

  3. Hi Mounish,

    I used this same set up to create the screenshots but there are no screenshots in the test-output directory.
    extent.reporter.spark.out=test-output/SparkReport/

    screenshot.dir=test-output/
    screenshot.rel.path=../

    Any idea why it is ? The report is getting generated but no screenshots. I am using the below way to attach the screenshot.

    TakesScreenshot ts = (TakesScreenshot) driver;
    byte[] screenshot = ts.getScreenshotAs(OutputType.BYTES);
    scenario.attach(screenshot, “image/png”, “testcase 1”);

  4. Hi Mounish,

    I had asked a question earlier about the reports not having css or js. When I checked the html source code , I see that the css and js links are not local and so it is blocked inside my company. Is there any way to over come this?

    Thank You
    Ak

  5. Hi Mounish,

    My reports are getting generated but there is no css. Any idea what could be the reason?

    Thank You
    Ak

  6. I want to pass Environment or System Info Properties at runtime like I am using one the VM arguments as ‘EnvironmentName’ on which my tests get executed. is it possible to pass this VM argument ”EnvironmentName’ to ‘systeminfo.environment’ property in the extent.properties file at run time. So that my environment name will get printed in the extent report System info section. I tried hardcoding it in the extent.properties file and it works, but I want to pass at runtime.

  7. I am trying to generate a report using testng and above configuration but there is a error
    java.lang.NoSuchMethodError: ‘boolean com.aventstack.extentreports.service.ExtentService.isDeviceEnabled()’

    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.lambda$updateCategoryAndDeviceAndAuthor$3(ExtentCucumberAdapter.java:448)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.updateCategoryAndDeviceAndAuthor(ExtentCucumberAdapter.java:447)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.createTestCase(ExtentCucumberAdapter.java:430)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.handleTestCaseStarted(ExtentCucumberAdapter.java:163)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.access$100(ExtentCucumberAdapter.java:63)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$3.receive(ExtentCucumberAdapter.java:107)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$3.receive(ExtentCucumberAdapter.java:104)
    at io.cucumber.core.eventbus.AbstractEventPublisher.send(AbstractEventPublisher.java:51)
    at io.cucumber.core.eventbus.AbstractEventBus.send(AbstractEventBus.java:12)
    at io.cucumber.core.runtime.SynchronizedEventBus.send(SynchronizedEventBus.java:47)
    at io.cucumber.core.runtime.ThreadLocalRunnerSupplier$LocalEventBus.send(ThreadLocalRunnerSupplier.java:62)
    at io.cucumber.core.runner.TestCase.emitTestCaseStarted(TestCase.java:206)
    at io.cucumber.core.runner.TestCase.run(TestCase.java:72)
    at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
    at io.cucumber.testng.TestNGCucumberRunner.lambda$runScenario$1(TestNGCucumberRunner.java:132)
    at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$5(CucumberExecutionContext.java:136)
    at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
    at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:136)
    at io.cucumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:129)
    at io.cucumber.testng.AbstractTestNGCucumberTests.runScenario(AbstractTestNGCucumberTests.java:35)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
    at org.testng.TestRunner.privateRun(TestRunner.java:774)
    at org.testng.TestRunner.run(TestRunner.java:624)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
    at org.testng.SuiteRunner.run(SuiteRunner.java:261)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1215)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
    at org.testng.TestNG.run(TestNG.java:1048)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)

  8. Hello all
    By using extent.properties can we generate html report name with time stamp
    as i read the article in that it create the folder with time stamp and also how to get chrome name and os name dynamically in systeminfo section instead of writing hard code value . if possible please explain how and send reference.

  9. Hi Mounish
    Thank you for the Content, Appreciated.
    Can you please help me with the below query.
    I have executed one test case and got the screenshots for each Steps in Screenshot Folder. However, how to give the name of each screenshot based on the Test step that has been executed. Currently, I am getting screenshot names as below.
    Actual: Embedded1.png
    Expected: Given User has navigated to the Login page. (Test step).

    Kindly assist.

  10. io.cucumber.core.exception.CucumberException: java.lang.NoClassDefFoundError: com/aventstack/extentreports/reporter/ReporterFilterable getting this error

  11. Hi Team,

    Getting one scenario examples attached to another scenario in the extent report. I tried with Scenario Template and Scenario Outline, but i got same for both. I ran the code in parallel. My issue just example is not attached to respective scenario. Can you please help me out.

    io.cucumber
    cucumber-java
    7.15.0

    io.cucumber
    cucumber-testng
    7.15.0

    tech.grasshopper
    extentreports-cucumber7-adapter
    1.14.0

    com.aventstack
    extentreports
    5.1.1

    Thanks

  12. Hello,
    I’m running my test through maven-failsafe-plugin with the path to the test report in a system property variable like so
    target/tmp.html
    I am also including multiple runners in my plugin like so

    **/BDDTest*.java

    and in each of my runners i have an @AfterClass that moves the report to the correct place to keep trace of my different runs
    Files.move(source, destination)

    The issue that i have is that 1st test report is ok, but then all the other ones are containing all previous reports (so report 2 contains 1 & 2, report 3 contains 1,2 & 3, etc)

    Any idea how to solve this ?

  13. I have created two types of execution reports: one for the web application and one for the mobile application. When I select my execution type as mobile, the execution starts on the mobile application, and it should generate the mobile extent report. Vice versa, for the web application.

    and i handled execution type below Pom.xml

    org.apache.maven.plugins
    maven-compiler-plugin
    3.11.0

    org.apache.maven.plugins
    maven-surefire-plugin
    3.1.2

    true

    web_UI

    ${suiteXMLFile}

  14. Thanks for the Article appreciate your work. Is there anyway we can not save screenshots in extent reports. I am seeing the screenshots are getting saved in ‘test-output’ folder eventhough i have commented below line in my extent properties file.
    screenshot.dir=test-output/
    screenshot.rel.path=../

    1. If your test code generates screenshots then it will be saved to disk unless you have chosen the base64 screenshot option. The report uses relative path to display the images.

  15. Hi Mounish,
    Is there any possibility that under tags table by default we are getting below mentioned columns:
    Name Passed Failed Skipped Others Passed %.
    Can I add 1 more column(Fail%) in the same table and if possible then how can I achieve this.
    Thanks

    1. Hi, This is not possible to add columns out of the box. You will need to modify the code and maintain it.
      BTW, which report are you referring to?

    1. You cannot add markup code. For text block you can use the scenario.log() method of cucumber. The adapter will output this as simple text.

  16. I am trying to add logger message into the report but it is not inserting.I am using below dependencies and files. Getting below Error in starting of execution :
    2023-05-28 04:13:26,840 main ERROR Appenders contains an invalid element or attribute “ExtentReportAppender”
    2023-05-28 04:13:26,875 main ERROR Unable to locate appender “ExtentReportAppender” for logger config “root”
    Log4j2:

    org.apache.logging.log4j
    log4j-core
    2.14.1

    org.apache.logging.log4j
    log4j-api
    2.14.1

    Report:

    tech.grasshopper
    extentreports-cucumber7-adapter
    1.10.1

    Log4j2.xml:

    extent-config.xml:



    dark


    UTF-8


    http

    Extent

    Grasshopper Report


    bottom

    extent.properties:
    extent.reporter.html.start=true
    extent.reporter.logger.start=true
    extent.reporter.pdf.start=true

    extent.reporter.html.config=src/main/resources/extent-config.xml
    extent.reporter.logger.config=src/main/resources/extent-config.xml

    extent.reporter.html.out=test-output/HtmlReport/API-Test-Execution-Report.html
    extent.reporter.logger.out=test-output/Logger
    extent.reporter.pdf.out=test-output/PdfReport/API-Test-Execution-Report.pdf
    ExtentReportAppender.java:
    package utils;

    import com.aventstack.extentreports.ExtentReports;
    import com.aventstack.extentreports.ExtentTest;
    import com.aventstack.extentreports.Status;

    import org.apache.logging.log4j.Level;
    import org.apache.logging.log4j.core.Layout;
    import org.apache.logging.log4j.core.LogEvent;
    import org.apache.logging.log4j.core.appender.AbstractAppender;
    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
    import org.apache.logging.log4j.core.layout.PatternLayout;

    public class ExtentReportAppender extends AbstractAppender {
    private ExtentTest test;
    @SuppressWarnings(“unused”)
    private static ExtentReports extentReports;

    @SuppressWarnings(“deprecation”)
    public ExtentReportAppender(String name, Layout layout) {
    super(name, null, layout);
    }

    public void setTest(ExtentTest test) {
    this.test = test;
    }

    @PluginFactory
    public static ExtentReportAppender createAppender() {
    Layout layout = PatternLayout.createDefaultLayout();
    return new ExtentReportAppender(“ExtentReportAppender”, layout);
    }

    // Setter method for extentReports
    public static void setExtentReports(ExtentReports reports) {
    extentReports = reports;
    }

    @Override
    public void append(LogEvent event) {
    String logMessage = event.getMessage().getFormattedMessage();
    Level logLevel = event.getLevel();

    // Map Log4j2 log levels to Extent Report log levels
    Status extentStatus;
    if (logLevel.equals(Level.ERROR)) {
    extentStatus = Status.FAIL;
    } else if (logLevel.equals(Level.WARN)) {
    extentStatus = Status.WARNING;
    } else if (logLevel.equals(Level.INFO)) {
    extentStatus = Status.INFO;
    } else {
    extentStatus = Status.WARNING;
    }

    // Add log message to the Extent Report
    test.log(extentStatus, logMessage);
    }
    }

    1. Basically, I have to upload my logs to the PDF report and Excel report. Can someone help me on that how can I achieve this?

      1. Excel report does not display any logs. For the PDF report why not use the scenario.log() method instead?

        1. Every time do i need to use Scenario.log() like Currently, I am using Logger.info(“Some Message”) to print in console. How can we achieve this using ExtentAppender.

          1. log() method is the simplest way to this and supported by the adapter. No idea how to use the Appender.

  17. Reports are not getting generated .where can i put my GIT hub repo for details.
    Although my scenarios are getting passed & no errors.
    Plus the cucumber.html report is getting generated

  18. Hi
    I’ve created the TestRunner file(having @CucumberOptions(plugin = {“com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:”}).
    To trigger this test runner file, I’m using another containing class containig JunitCore.runClasses(TestRunner.class). Now once the extent report is getting generated, I want to print the absolute path as well where the extent report has been generated. How can it be done

    1. You can get the path to any file on the project root – Paths.get(“file name”).toAbsolutePath().normalize – inside the triggering class.
      U can either append the value of (extent.reporter.spark.out or extent.reporter.pdf.out or which ever report) to the path. U could even access the extent.properties and get the path from there. U can print out the path(s) to the console.
      I am assuming all the code is in one project.

      1. Hi Mounish
        Can you please provide me with the code of maven surefire and maven failsafe plugin that needs to be added inside the pom.xml. Such that I just need to make changes in “extent.reporter.spark.out” property.
        And one more thing in case the plugin doesn’t work.
        A jar is containing the testrunner file. And I’m running the jar by using the spark-submit command as follows
        spark-submit –master local –conf spark.driver.extraJavaOptions=’-Dcucumber.plugin=com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:’ –queue root.capture –class cucumberOptions.TestRunnerMain myjar1.0.jar.
        In the above command, how should make the tweaks to include the maven’s -DargLine=”-Dextent.reporter.spark.start=true -Dextent.reporter.spark.out=test-output/SparkReport/Spark.html” to my spark-submit command to generate the report?

        Thanks 🙂

  19. Hi Mounish!

    I have question about Spark html report
    if I specify extent.reporter.statusfilter=pass in extent.properties
    it will show only Passed scenarios in the report, but on rerunning failed scenarios I want to have extent.reporter.statusfilter=fails,
    so it will include failed results after rerun.
    how I can achieve it?
    Thanks and Best Regards!

    1. If both the runners are run in the same POM execution then this is not possible.
      If you can separate the two executions, for the rerun case you can pass the extent.reporter.statusfilter through the Maven system parameters. This should overwrite the one in the properties file. Maybe execute 2 commands from a batch file.

      1. Thanks for a fast reply.
        I am having a problem, when I enable: extent.reporter.statusfilter=pass
        html report is missing:
        1) test-detail column in Dashboard
        2) System/Environment in Table
        3) And little other texts and icons
        vs when is completely removed extent.reporter.statusfilter=pass

          1. I just sent a screenshots for a spark reports. It happens when I have this line in extent.properties file: extent.reporter.statusfilter=pass and scenario is failed.

  20. Hi Mounish,
    The html report looks really good to me compared to spark report.
    Is it possible to change the html report to make the scenario collapsible like spark report?
    I usually have a lot of scenarios under one tag which creates a very long html report.

  21. Hi,
    Where do I add my code to send the extent report over email ? as the reports are generated very late in the build. I tried it adding in the @after hook method but the reports are not generated for the hook method to find it.
    I also tried using the maven exec plugin but if any tests fail the build fails and the exec plugin is not triggered. I do not want to use the “maven.test.failure.ignore” as true as it always marks my build as success.

    1. You can execute the exec-maven-plugin in the post-integration-test phase with the custom email code. The report will be available by then. Also there is a maven-postman-plugin which you can configure in the post-integration-test.
      Even the CI environment will be providing the email after build functionality

      1. Hi Mounish,

        Yes, I have tried using the “exec-maven-plugin” but if any tests fail the build fails and the code that needs to be run via exec-maven-plugin is not triggered.

        I do not want to use the property “maven.test.failure.ignore” as true as it always marks my build as success.

        I will give maven-postman-plugin a try.

          1. I am using maven sure fire plugin to run my tests and not maven failsafe. So the post integration test phase does not run. If I try using maven failsafe plugin it says no tests to run.

    1. Are you referring to the Spark or HTML report? Does not matter because there is no out of the box setting which will allow this.

      You will have to use javascript statement in the spark-config.xml (or .json) to change the css style(background-image) of the image. This needs to be placed inside the ‘js’ tag in the config file. The image is contained in a ‘div’ element with class value of ‘logo’.

  22. Hi Mounish,

    Is there any way by which I can set the system info dynamically? I do not wish to set it in the properties file or send it via the maven command. I want it to be set by the code.

    1. You have to get hold of the ExtentReport instance by using ExtentService.getInstance(). Then you can set the system info by using setSystemInfo(….)

      1. Thanks Mounish for the quick response. I will try this.

        Also, I am trying to flush the extent report after every step or after every scenario using below command. Have tried calling below command in methods having @AfterStep hook and @After hook (Cucumber-TestNG framework)
        ExtentCucumberAdapter.getCurrentScenario().getExtent().flush();

        Spark report is generated correctly but for pdf report I see below error and the pdf report is generated in corrupted format which I cannot open.
        Below is the error:
        Jan 03, 2023 11:48:53 AM tech.grasshopper.pdf.PDFCucumberReport createReport
        SEVERE: An exception occurred
        java.io.IOException: The TrueType font null does not contain a ‘cmap’ table
        at org.apache.fontbox.ttf.TrueTypeFont.getUnicodeCmapImpl(TrueTypeFont.java:562)
        at org.apache.fontbox.ttf.TrueTypeFont.getUnicodeCmapLookup(TrueTypeFont.java:542)
        at org.apache.fontbox.ttf.TrueTypeFont.getUnicodeCmapLookup(TrueTypeFont.java:528)
        at org.apache.fontbox.ttf.TTFSubsetter.(TTFSubsetter.java:90)
        at org.apache.pdfbox.pdmodel.font.TrueTypeEmbedder.subset(TrueTypeEmbedder.java:347)
        at org.apache.pdfbox.pdmodel.font.PDType0Font.subset(PDType0Font.java:263)
        at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1369)
        at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1344)
        at tech.grasshopper.pdf.PDFCucumberReport.createReport(PDFCucumberReport.java:125)
        at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter.flush(ExtentPDFCucumberReporter.java:95)
        at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter.access$100(ExtentPDFCucumberReporter.java:23)
        at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter$1.onNext(ExtentPDFCucumberReporter.java:69)
        at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter$1.onNext(ExtentPDFCucumberReporter.java:62)
        at io.reactivex.rxjava3.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:310)
        at io.reactivex.rxjava3.subjects.PublishSubject.onNext(PublishSubject.java:226)
        at com.aventstack.extentreports.ReactiveSubject.onFlush(ReactiveSubject.java:83)
        at com.aventstack.extentreports.AbstractProcessor.onFlush(AbstractProcessor.java:85)
        at com.aventstack.extentreports.ExtentReports.flush(ExtentReports.java:279)

        1. Please do not do this. This is not a good use of processing time and resources as the code will repeatedly create and delete the report file. Multiple instances of the same PDF report file does not work.

          What is the reason for this multiple calls to flush?

          1. When a big suite is triggered for execution and due to some or the other issues the execution gets stuck in the middle. At such times we do not see the report being generated. Hence, I wanted to flush the report at regular intervals to generate the report for tests that were already executed before the execution gets stuck.
            In cases where the execution is stuck, as of now I can only see the status in the IDE but there is no report generated.

            1. Cucumber steps used to have a timeout option but was deprecated. You could replicate the same functionality using tools like awaitility https://github.com/awaitility/awaitility or guava https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/TimeLimiter.java.

              If you want to go down this route, I would create a JSON report only instead of Spark and PDF. Then you can use the JSON report to generate the Spark and PDF reports. This can be done with a separate code.


              ExtentReports extent = new ExtentReports();
              extent.createDomainFromJsonArchive("json report path");
              extent.attachReporter(sparkReport);
              extent.attachReporter(pdfReport);
              extent.flush();

              Have a look at this for detailed code – https://github.com/grasshopper7/extentreports-merge/blob/496b9f6c78904d882da0ccbd8d209a41e0277d6a/extentreports-merge/src/main/java/tech/grasshopper/combiner/report/MergedReport.java#L27

  23. Hi,

    Can I check if spark report shows attached videos? I tried attaching videos as given below.

    File video = new File(“file_example_MP4_640_3MG.mp4”);
    byte[] videoAttachment = Files.toByteArray(video);
    scenario.attach(videoAttachment, “video/mp4”, “video”);

    I can see it is shown in cucumber report. But it is not shown in spark report. Can you help to resolve this issue?

  24. Hi

    Is there any way to add API Response in this report as on previous version we used ExtentTestManager to add API response but not sure how to add it here.

    Please help me on this.

    Thanks,
    Sinha

  25. I need to add some other logs in the Extent report. How can i add that something like assertion being passed or some other logging

  26. How to explicitly fail a step?
    I am using try catch block for exception handling. I want the the test to fail when it goes to catch block but continue with other remaining tests.

    Please advise

    1. Throw an object of AssertionError from catch block. This will fail the step and skip any following steps in the scenario, if present.

  27. Hi Mounish,

    I have version 1.7.1 of extentreports-cucumber7-adapter working well. I’d like to output the Extent Reports to a similar folder structure as the log files something like this: \Reports\TestPass_20221103\14.30.47_Logs

    In extent.properties I’ve try different variations of this:
    basefolder.name=Reports/
    basefolder.datetimepattern=’TestPass’_yyyyMMdd/HH.mm.ss’_Reports’
    Which puts in the correct date/time but there is always a space between .name and .datetime parts.

    Is there a way to build the path without the space?

    Ideally, I’d like to pass the same folder to the logs and the reports. When they are separate, I sometime see a second or two discrepancy in the path name. I’ve tried doing something like this:
    System.setProperty(“basefolder.datetimepattern “, filepath);

    Which I’ve never gotten to work. Is it possible to set those properties when the test runner kicks off?

    Thanks in advance!

    1. I can look at fixing the first issue by adding a parameter for not using default space.

      For the second issue, there is no existing mechanism to synchronize the logs and report folders. I am assuming that these logs are generated by the testing process.
      I think you can try with a fixed folder name, ie do not use the basefolder parameters. Use this for both the report and logs. In the post-integration-test phase you could move these to a custom name with timestamp folder. Maybe this could work.

      1. Thanks for the quick reply!

        Great suggestion on moving the files. I have changed the config to drop the files in TestPass_Current. I then copy them to the current TestPass_yyyyMMdd folder and it seems to be working well.

        1. Good to know it worked.
          I have implemented a setting for enabling delimiter in name and also ability to choose a custom delimiter. Will release this in a couple of days.

    1. Hi, I do not think this image is configurable in default ‘online’ mode. Check out the relevant spark template – https://github.com/extent-framework/extentreports-java/blob/548ee3dfeb69a04cbcf7b822753bb54ef0dbf796/src/main/resources/com/aventstack/extentreports/templates/spark/partials/head.ftl#L27.

      It may be possible if you choose the ‘offline’ option in spark configuration file. You can create a folder ‘spark’ under ‘src/main/resources’ in the project and add your image and rename it to ‘logo.png’. I think it should be displayed. Give it a shot.

  28. Dear Mounish,
    Thank you so much for this article. It’s really useful for me while researching a solution for Cucumber Reports.

    I have one concern based on my first time applying your approach.
    How can I customize the location of “extent.properties” file or “pdf-config.yaml” file?
    Because my practice has included many configuration files, I wanted to categorize these files in corresponding directories instead of putting all of them in “resources” folder.

    Thanks for you time to read my comment.
    Looking forward your suggestion.

    Thanks sincerely,

    1. Hi, As per my understanding both these file locations cannot be changed. They are not configurable yet. I was planning to make the pdf config file location configurable but could not get the time to complete the change. I will look at it again. The extent.properties location is controlled by the extent report code which is not maintained by me. You will have to create an issue in their repository.

  29. Hi Mounish,
    HTML reports are getting generated.
    But the screenshots folder is not created and the images are not attached to the HTML report.

    Below are the build details;

    java version “1.8.0_202”

    extent.properties
    extent.reporter.spark.start=true
    extent.reporter.spark.config=src/test/resources/extent-config.xml
    extent.reporter.spark.out=test-output/SparkReport/
    screenshot.dir=test-output/
    screenshot.rel.path=../

    4.0.0
    Cucumberjava
    Cucumberjava
    0.0.1-SNAPSHOT

    io.cucumber
    cucumber-java
    7.3.0

    io.cucumber
    cucumber-junit
    7.3.0
    test

    io.cucumber
    cucumber-core
    7.3.0

    org.seleniumhq.selenium
    selenium-java
    4.1.3

    org.testng
    testng
    7.5

    io.cucumber
    cucumber-testng
    7.3.0

    tech.grasshopper
    extentreports-cucumber7-adapter
    1.7.0

    1. Hi, Pretty hard to tell the reason without code access but configuration in extent.properties seems correct. In the POM choose either cucumber-unit or cucumber-testng, and no need to add testng or junit explicitly. Not sure it has anything to do with your problem though.
      Have you tried with the sample implementation – https://github.com/grasshopper7/cuke7-extent-adapter-report.
      Thanks

  30. Hi Mounish ,

    Hope you doing well ! I observed some issue with Cucumber 7 adapter plugin which was observed in Cucumber 6 adapter too .
    But later on it was fixed .

    Please Refer below link –
    https://github.com/extent-framework/extentreports-java/issues/263

    Exact same issue is observed in cucumber 7 adapter . Where count of scenario outline is duplicated .
    https://stackoverflow.com/questions/71028279/cucumber-7-spark-report-test-scenario-outline-displayed-twice-issues

    Dependency I am using

    io.cucumber
    cucumber-java
    7.3.4

    io.cucumber
    cucumber-junit
    7.3.4
    test

    tech.grasshopper
    extentreports-cucumber7-adapter
    1.5.1
    test

    1. There has been no changes from version 6 to 7. I have explained this display issue in a comment earlier but unable to locate it now.

      Same name row multiple display in case of Scenario Outline – ExtentReport tests are hierarchical. An Extent Test is created for a Scenario Outline. The first row is the scenario outline name provided in the feature file. The rows after that are coming from the examples table. Each row corresponds to a scenario and a child Extent Test with the parent Scenario Outline Extent Test. This child Extent Test needs a name which is inherited from the Scenario Outline name. This is the reason the Scenario Outline name is repeated multiple times. Easiest way is to add additional data to the Scenario Outline name with the bracket notation. – https://github.com/grasshopper7/cuke7-extent-adapter-report/blob/9f73d7213f134b808992476c41724519936edcd7/cuke7-extent-adapter-report/src/test/resources/stepdefs/scenario%26outline.feature#L8

      Tag count in dashboard – The tag on the Scenario Outline Extent Test is inherited by the example rows Extent Test. Due to this the tag count of the scenarios under a scenario outline is incremented by 1. The same reason also applies for the categories page in which an extra row is added. I do not remember the exact code logic why this cannot be changed as it depends on the main extentreport code. Will look into it – https://github.com/grasshopper7/extentreports-cucumber7-adapter/issues/5

      1. Hi Mounish.
        I am getting the below error while generating the PDF report. I have generated yaml file and its not finding the same.
        INFO: PDF report configuration YAML file not found. Using default settings.
        Jun 08, 2022 1:41:22 PM tech.grasshopper.pdf.PDFCucumberReport createReport
        SEVERE: An exception occurred
        java.io.IOException: The TrueType font null does not contain a ‘cmap’ table

      2. Hi Mounish,

        Is there any solution for this Problem with the incorrect Tag count when a Scenario Outline is used? We really want to use this great report.

        1. Hi, This is related to the main extentreport code logic which I do not have any ownership. You will need to raise an issue with them. This will require the count calculation code to change for BDD type report, not sure how trivial this is. Thanks.

          1. Hi, I was wrong. I have checked again and I made a mistake in the adapter code. I have fixed it and initial tests look good. If all checks out will release a new version in a couple of days which should fix this issue. Thanks

  31. Hi Mounish,

    I have been using the extentreports-cucumber7-adapter(version 1.1.0) with gradle for a couple of months. Today I upgraded it to the latest version 1.5.1. Now I am seeing the screenshots in the pdf file as a thumbnail only. In order to view it in the original size, I have to download the pdf file and click on the pin at the top right corner of the thumbnail. Is it possible to view that in the original size from the pdf file itself like in the earlier versions so that I can view directly from mobile/email.

    Have one more question. If there are huge no of test cases and there are lot of failures then no of screenshots will also be large in number. Will this affect the pdf report generation? If so are there any solutions for that?

    1. Hi, The zoomed in view of screenshots was removed in latest version. The attachment style is more performance friendly and allowed the user to use any native application to view files. I can revert it with some modifications but it will not be a default option, will have to be explicitly enabled.

      The report generation times will be directly proportional to the number of steps\hooks containing images. Keeping base64 image style to default value of false, will help pdf report performance. Are you facing any issues? What count of test case are you executing?

      For me the pdf report has more value in providing an overall summary rather than a detailed view of each step or scenario. The reason for this is that the details are constrained by the page dimensions which reduces the data that can be displayed horizontally and splits vertical data into multiple pages. It is not an infinite blank canvas like a webpage.

      I am planning to add an option for a section which will only display details of failed scenarios. The report creator can choose whether to show detailed view of all scenarios or just failed\skipped ones.

      1. Hi Mounish,

        My apologies for the late reply.

        I understand the technical limitations. But if it’s possible to revert it with some modifications as mentioned in the comment that would be really helpful. Since I am using gradle as the build tool I prefer the settings in extent.properties file something like extent.reporter.pdf.base64imagesrc=true.

        In my testing framework I am including the screenshots of only the failed testcases. Currently I don’t have any huge no of test cases but I am planning to implement this in bigger projects. Before proceeding, I just want to know the limit of the number of screenshots(as you mentioned large number of screenshots can affect the performance). Suppose there are around 200 testcases and if the login API fails then all testcases will fail. Will the pdf report be able to handle that amount of screenshots?

        1. Will add the earlier expanded section with changes. – https://github.com/grasshopper7/cucumber-pdf-report/issues/37.
          base64 image processing will take longer as physical file needs to be created and deleted. Have not been successful yet with creating images directly from base64 string.
          There is no limit of an actual number that can be handled but definitely report generation time will be larger. I will have to check for any memory issues. Will have to check the code and probably simulate extreme number of cases.
          Is there a possibility to check the report generation with one of your larger projects, in a development environment ? Thanks.

        2. The expanded section is added back in latest version – 1.6.0. This has to be enabled in the pdfconfig.yaml. Set the displayAttached: false & displayExpanded: true & displayDetailed: true. Will uppdate the details in the article and github later on.

  32. Hi Mounish,

    Great thanks to your article! It does help a lot. However, I have 2 questions here hope that you could reply:

    1) I saw there is “log” for spark.vieworder – but how to enable the log tab here & to have log contents?
    2) Is that possible to attach a file in the extent report? Instead of scenario.log to log out each of the test data, is there a way to attach JSON or properties file etc?

    Thanks! Appreciate your reply on this.

    1. 1. The “log” tab refers to String logs which are added to the ExtentReports instance. You can activate it by using the methods – addTestRunnerOutput(Strng) – https://github.com/extent-framework/extentreports-java/blob/548ee3dfeb69a04cbcf7b822753bb54ef0dbf796/src/main/java/com/aventstack/extentreports/ExtentReports.java#L340 or addTestRunnerOutput(List String) – https://github.com/extent-framework/extentreports-java/blob/548ee3dfeb69a04cbcf7b822753bb54ef0dbf796/src/main/java/com/aventstack/extentreports/ExtentReports.java#L318. It is a rarely used feature which I frankly thought had been removed.
      You would probably use it in the BeforeClass or AfterClass method of the runner. U would need to write something like – ExtentService.getInstance().addTestRunnerOutput(). If I remember correctly the display is pretty basic.

      2. It should be possible to attach any file to the extent report, though I have not tried with json files. The problem will be displaying the files because the adapter or the report currently does not support any other mime types other than images. Even ExtentReport method signature to attach files are all about media related files. Give it a try, I could be wrong. There are static hook methods in the adapter which expose the currently step ExtentTest which you can use to add the files. ExtentCucumberAdapter.getCurrentStep().info(title, MediaEntityBuilder.createScreenCaptureFromPath(path).build()).

      Will have a look at the second point and update. Thanks

      1. You’re right. #2 only for media related files. It would be great if it can support other files type.
        And first thought to have the whole bunch of data printed as log, but too bad the log is using “append” instead of “new line”, thus it’s not much useful here.

        1. I have opened an issue to support other mime types – https://github.com/grasshopper7/extentreports-cucumber7-adapter/issues/9

          In your case, there is a much simpler option of creating a html link in the report which opens up the log file. Store the contents into a file and save it to some assigned location. Access the currently executing ExtentTest step and add a log with the html link.

          ExtentCucumberAdapter.getCurrentStep().info(“?a href=’props.properties’ target=’_blank’?LOG FILE?/a?”)
          *Replace ? with appropriate html opening and closing brackets. Comments remove them

          You should get links. – Have a look at the image in the section “Spark Report” in this article – https://ghauto.tech/4199/.

  33. I am using the recently released cucumber-jvm version-7 (1.4.1) and not able to generate the pdf report. The required pdf input folder is generated but the pdf file cannot be seen. I am not using multiple runners but a single runner.

    1. U getting any exception in the console? Also what cucumber version are you using?
      Did u try with the sample implementation?

      1. I wasn’t getting any exception in the console. Had implemented using cucumber 7.2.3 version and java 11.
        But the sample implementation helped 🙂 post downgrade to java8 and using the latest cucumber version 7.3.1. It worked. So evolved by pom.xml file based on the dependencies added in pom.xml file of the sample implementation. I am not sure whether java 11 was the problem or the inclusion of the dependencies if there is any link to the same ? –

        org.junit
        junit-bom
        5.8.2
        pom
        import

        io.cucumber
        cucumber-bom
        7.2.3
        pom
        import

        com.github.ralfstuckert.pdfbox-layout
        pdfbox2-layout
        1.0.1

        com.aventstack
        extentreports
        5.0.9

        io.cucumber
        cucumber-testng
        test

        org.testng
        testng
        7.5
        test

        io.cucumber
        cucumber-junit-platform-engine
        test

        org.junit.jupiter
        junit-jupiter-engine
        test

        org.junit.vintage
        junit-vintage-engine
        test

        io.cucumber
        cucumber-junit
        test

        org.junit.jupiter
        junit-jupiter-api
        test

        org.junit.platform
        junit-platform-suite
        test

        org.junit.jupiter
        junit-jupiter
        test

        org.junit.platform
        junit-platform-launcher
        test

        Also I had to add the below plugin –

        org.apache.maven.plugins
        maven-resources-plugin
        3.1.0

        1. ExtentReports core has been tested with Java 8. This is the version I still use for adapter code. Cannot comment with much confidence if Java 11 is the issue. I have not seen much action in the extent core repository for a long time so not sure of future developments.

          The dependencies show cucumber-testng as well as junit jars, maybe you could have a look again. Most of these dependencies are transitive and no need to add them explicitly to the main pom.

  34. Hi Mounish,

    I have a scenario where am trying to execute the same set of features/scenarios in two different browsers in parallel using TestNG and am using the extent reports for reporting.
    Let’s say there is a feature file with 4 scenarios in it and that feature file is executed in 2 different browsers in parallel mode, then the report generated currently will be something like as below.
    Feature
    Scenario 1
    Feature
    Scenario 2
    Scenario 3
    Scenario 4
    Scenario 1
    Scenario 2
    Scenario 3
    Scenario 4

    Is there any way where we can have the report generated as below
    Feature
    Scenario 1
    Scenario 2
    Scenario 3
    Scenario 4
    Feature
    Scenario 1
    Scenario 2
    Scenario 3
    Scenario 4

    1. Hi,
      Not exactly sure I understand your setup. Are u using testng.xml to trigger runner?

      The adapter code stores the “Feature names” which is used to link the scenarios in the Extent Test hierarchy. This “fails” when there are two feature with the same name. This logic applies to scenario outline also.

      Easiest solution is to have copies of the feature file by appending the browser type in the feature name. Like below.
      Feature: Adding stops to route – Chrome
      Feature: Adding stops to route – Firefox

      U do not need to manually create them but use a Maven (if u r using) phase like ‘process-test-resources’ to copy and edit the feature files. So the original feature file becomes a template.

      Give it a try and let me know. Thanks.

  35. Hi Mounish,
    I am using cucumber latest version 7.2.3.
    I have followed the steps for adding extent report adapter and everything seems to be fine.
    But it is not generating the file, the folders are creating but there is no report file into it.

    what might be the reason?

    4.0.0

    BDD
    Cucumber_Framework
    0.0.1-SNAPSHOT

    Cucumber_Framework

    http://www.example.com

    UTF-8
    1.7
    1.7

    io.cucumber
    cucumber-testng
    7.2.3

    io.cucumber
    cucumber-java
    7.2.3

    org.seleniumhq.selenium
    selenium-java
    4.1.3

    io.cucumber
    cucumber-picocontainer
    7.2.3

    tech.grasshopper
    extentreports-cucumber7-adapter
    1.3.0

    com.aventstack
    extentreports
    5.0.9

    maven-clean-plugin
    3.1.0

    maven-resources-plugin
    3.0.2

    maven-compiler-plugin
    3.8.0

    maven-surefire-plugin
    2.22.1

    maven-jar-plugin
    3.0.2

    maven-install-plugin
    2.5.2

    maven-deploy-plugin
    2.8.2

    maven-site-plugin
    3.7.1

    maven-project-info-reports-plugin
    3.0.0

  36. Hi Mounish,
    I have tried your sample project and find out that status filtering for scenarios and steps doesn’t work in ExtentHtml.html. I mean 4 icons (pass, fail, skip, clear) placed on right side. If you click on pass, fail or skip then pane becomes empty.
    Please could you check it?
    Thank you.

    1. Yeah, you are correct. The functionality does not work as intended.
      As mentioned in the article this report was deprecated in version 4 and I just ported the report code to work with Extent version 5. I kind of liked the display better than the official supported Spark html report. The problem is that js scripts, images, etc are hosted at a location to which I have no access. If the bug is related to those code artifacts it would not be of much help.
      Anyways, I will have a look and update. Thanks.

  37. Hi,
    Is there a possible to add Environment and System information like ExtentCucumberAdapter.setSystemInfo(“OS”, System.getProperty(“os.name”))? It’s easier to customize rather than it was mentioned above.

    1. You can try with ExtentService.getInstance()..setSystemInfo(” ” ,” “) in a beforeclass or similar method in the runner.

  38. If I want to add any log or info to the result how I can do that if I have complex project structure

      1. How to format the log output on the html report? Like putting the log inside a block or formatting the log text so it is different from the scenario steps.
        Thanks!

  39. Hi,
    I have a question regarding pdf output.
    I just started to learn cucumber and reports. Now I’m trying to implement your pdf report.
    When I do not include pdf-config.yaml in the project src/test/resource folder, I am receiving this message: Mar 11, 2022 12:10:45 PM tech.grasshopper.pdf.PDFCucumberReport collectReportConfiguration
    INFO: PDF report configuration YAML file not found. Using default settings.
    Pdf report is created.
    But, when I include pdf-config.yaml in the project src/test/resource folder, I am getting this message:
    Mar 11, 2022 12:20:42 PM tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter flush
    SEVERE: An exception occurred
    Cannot create property=displayAttached for JavaBean=ReportConfig(passColor=05a167, failColor=ff00ff, skipColor=a89132, displayFeature=true, displayScenario=true, displayDetailed=true, displayExpanded=false, summaryConfig=SummaryConfig(title=Cucumber Report, titleColor=null, dateColor=null, timeColor=null, dial=SummaryConfig.DialConfig(featureRanges=0.60 0.85, scenarioRanges=0.60 0.85, stepRanges=0.60 0.85, badColor=null, averageColor=null, goodColor=null), dataBackgroundColor=null), featureConfig=ReportConfig.FeatureConfig(featureCount=null, totalColor=null, durationColor=null, defaultCount=10), scenarioConfig=ReportConfig.ScenarioConfig(scenarioCount=null, totalColor=null, durationColor=null, defaultCount=10), detailedFeatureConfig=DetailedConfig.DetailedFeatureConfig(featureNameColor=null), detailedScenarioConfig=DetailedConfig.DetailedScenarioConfig(featureNameColor=null, scenarioNameColor=null, stepChartBarColor=null), detailedStepHookConfig=DetailedConfig.DetailedStepHookConfig(stepCount=null, stepTextColor=null, stepBackgroundColor=null, hookTextColor=null, hookBackgroundColor=null, durationColor=null, errorMsgColor=null, logMsgColor=null, defaultCount=15))
    in ‘reader’, line 1, column 1:
    passColor: 05a167
    ^
    Unable to find property ‘displayAttached’ on class: tech.grasshopper.pdf.config.ReportConfig
    in ‘reader’, line 8, column 18:
    displayAttached: true
    ^

    at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:291)
    at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:172)
    at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:332)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:230)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:220)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:174)
    at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:158)
    at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:490)
    at org.yaml.snakeyaml.Yaml.load(Yaml.java:429)
    at tech.grasshopper.pdf.PDFCucumberReport.collectReportConfiguration(PDFCucumberReport.java:80)
    at tech.grasshopper.pdf.PDFCucumberReport.(PDFCucumberReport.java:63)
    at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter.flush(ExtentPDFCucumberReporter.java:79)
    at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter.access$100(ExtentPDFCucumberReporter.java:19)
    at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter$1.onNext(ExtentPDFCucumberReporter.java:56)
    at tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter$1.onNext(ExtentPDFCucumberReporter.java:49)
    at io.reactivex.rxjava3.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:310)
    at io.reactivex.rxjava3.subjects.PublishSubject.onNext(PublishSubject.java:226)
    at com.aventstack.extentreports.ReactiveSubject.onFlush(ReactiveSubject.java:83)
    at com.aventstack.extentreports.AbstractProcessor.onFlush(AbstractProcessor.java:85)
    at com.aventstack.extentreports.ExtentReports.flush(ExtentReports.java:279)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.finishReport(ExtentCucumberAdapter.java:300)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.access$600(ExtentCucumberAdapter.java:62)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$8.receive(ExtentCucumberAdapter.java:136)
    at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$8.receive(ExtentCucumberAdapter.java:133)
    at io.cucumber.core.eventbus.AbstractEventPublisher.send(AbstractEventPublisher.java:51)
    at io.cucumber.core.eventbus.AbstractEventBus.send(AbstractEventBus.java:12)
    at io.cucumber.core.runtime.SynchronizedEventBus.send(SynchronizedEventBus.java:47)
    at io.cucumber.core.runtime.CucumberExecutionContext.emitTestRunFinished(CucumberExecutionContext.java:131)
    at io.cucumber.core.runtime.CucumberExecutionContext.finishTestRun(CucumberExecutionContext.java:118)
    at io.cucumber.junit.Cucumber$FinishTestRun.evaluate(Cucumber.java:250)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
    Caused by: org.yaml.snakeyaml.error.YAMLException: Unable to find property ‘displayAttached’ on class: tech.grasshopper.pdf.config.ReportConfig
    at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:158)
    at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:148)
    at org.yaml.snakeyaml.TypeDescription.discoverProperty(TypeDescription.java:254)
    at org.yaml.snakeyaml.TypeDescription.getProperty(TypeDescription.java:265)
    at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:231)
    … 38 more
    Process finished with exit code 0
    I have downloaded your project from git, but receiving this error:
    \Grasshopper\src\test\java\stepdefs\Stepdefs.java:32:25
    java: package sun.security.util does not exist
    I am using java 17 adoptium – termium lts.
    Any help?

    1. Interesting regarding the yaml file… the ‘displayAttached’ was added in the latest version with some major changes in supporting jars. Can you delete the report related jars (groupid tech.grasshopper) from your project setup and fetch them again? If you still get this error, let me know I will look into it.

      It is my mistake for the exception import, it is wrong one. I will fix it. I have primarily tested the code in Java 8 which allows this. U can comment this import line and cucumber pendingexception. Or else comment the line in the step definition https://github.com/grasshopper7/cuke7-extent-adapter-report/blob/0ac555f46593b11505d6ebc28ed66225310d7c53/cuke7-extent-adapter-report/src/test/java/stepdefs/Stepdefs.java#L181. Thanks.

      edit — Have fixed the exception import in git

      1. Hi,
        thanks for update, and sorry for late reply.
        I have downloaded project from git, commented: import sun.security.util.PendingException;
        removed throw and put into method to log Pending step definition.
        When I run test there is failures and pdf is not created.
        [ERROR] Run 5: RunCukeIT.runScenario expected [true] but found [false]
        [ERROR] Run 7: RunCukeIT.runScenario expected [true] but found [false]
        [ERROR] Run 8: RunCukeIT.runScenario » Runtime
        [ERROR] Run 9: RunCukeIT.runScenario » Runtime
        [ERROR] Run 24: RunCukeIT>AbstractTestNGCucumberTests.runScenario:35 » UndefinedStep The step …
        [ERROR] RunCukeIT>AbstractTestNGCucumberTests.tearDownClass:57 » InaccessibleObject Un…
        [ERROR] Tests run: 2, Failures: 2, Errors: 0, Skipped: 0

        I have noticed that some “runs” are ment to be failures (hope so).
        Any suggestions?
        Any chance to communicate via mail, and put solution here, not to bomb site with logs?

        Best regards,
        Jovan

        1. Solution:
          There will be 2 lines in the extent.properties related to json formatter.
          Set the first one to false -> extent.reporter.json.start=false
          And comment the second -> extent.reporter.json.out=test-output/Json/ExtentJson.json.

          The above settings should stop the json report from being created which is throwing the exception.

          After doing that, I am receiving pdf reports.
          Thanks for help Mounish.

  40. How can we add details like {project.name}, {project.build.directory} into the system.info section of extent.properties.
    can you please help on that ?

    1. Unfortunately it is not possible to add dynamic values which need to be resolved. U will need to add the actual value.

  41. Hi Mounish,
    I am using cucumber latest version 7.2.3.
    I have followed the steps for adding extent report adapter and everything seems to be fine.
    But it is not generating the file, the folders are creating but there is no report file into it.

    what might be the reason?

      1. Have u tried with the sample implementation. I tried it 4-5 days back and it worked. Share a stripped down version of your code for me to give more clear solutions. Thx

  42. In my extent report can able to see my screenshot but i cant able to see a screenshot in other pc. what can i do . please suggest me to resolve this issue

      1. Hi Mounish, Thanks for you reply. please tell me what should i do now ???

        Is there any possible way screenshot will come under reports??
        Please tell me. what should i write in screenshot rel.path

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

        extent.reporter.html.start=true
        extent.reporter.html.out=test-output/HtmlReport/ExtentHtml.html
        screenshot.dir=test-output/
        screenshot.rel.path=../

        basefolder.name=reports
        basefolder.datetimepattern=d-MMM-YY HH-mm-ss

        please do reply because your reply will help me lot. Thanks

        1. if “screenshot” and “test-output” are at the same level then your “screenshot.rel.path” configuration is correct.
          Easiest way for a portable report is to zip everything and send it. Else u can use base 64 images, in tht case no “screenshot.rel.path” is required but report size can be large

          1. yes Mounish. Screenshot located at under report>report.html>embedded.png. But embedded.png folder created I dont know why its created and seprate the screenshot and how to write relative path for embeded.png

      2. Hi Mounish ,
        Thanks for your reply , Is there any possible way screenshot will come under reports??
        Please tell me. what should i write in screenshot rel.path
        screenshot.dir=screenshot/
        screenshot.rel.path=../../screenshot/

  43. Hi Team,

    I am working on cucumber extent reports , i have a question on date time stamp format on reports where in i could see date time stamp format as : Dec,27 2018 09:44:49 AM but i am expecting my time format to be displayed as : Dec,27 2018 09:44:49 IST AM(Along with time zone it needs to be printed). Is there any facility/configuration that brings time zone on reports to display along with existing time stamp format
    Current time format displaying: Dec,27 2018 09:44:49 AM
    Expected time format to be displayed: Dec,27 2018 09:44:49 IST AM

    Kindly advise me on this my request how can it be done,,Thank you!!

    Please find the attached snippet of html report for the reference

            1. I am unable to understand what u r looking for? If u use the ‘timeStampFormat’, the report will print the date-time in the same format. For abbreviated time zone u need to add ‘zzz’ to the pattern.

  44. Hi

    How can we implement extent report 6 with pdf for karate framework as it does not have any step definitions defined.

  45. The latest ExtentReports adoptor had removed a lot of features. I think adding Serenity BBD + PDF Extent Report reporting should be good.
    Have you tried this with the current project +Serenity BBD for reporting?

    1. The adapter for cucumber 7 has the same features as the one for cucumber 6. Are you talking of Extent Report version 5 changes from 4?
      Serenity BDD produces amazing HTML reports on its own. I have not researched into developing a PDF report format for the same. Also Serenity only works with JUnit, which limits its usage.
      Though Serenity provides an implementation of the ScreenPlay pattern which is a far better approach then Page Object Model for any non-trivial project.

  46. Hi Mounish

    Is there a way to get the latest report folder name printed on the console?..this would enable me to zip the entire report and attach it to a test management tool or send an email?
    or is there any workaround to do the same?
    Appreciate your response.

    Regards,

    1. Currently there is no console message functionality other than for exceptions. U can add a github issue and I will look into it. Thanks

  47. The same reason to align the .properties files to a separate folder.
    I will use the workaround as you said thanks.

  48. Hi Mounish,
    Thanks for the article and plugin.
    Is there a way to relocate the the pdf-config.yaml file from test resources to a another folder and set it as system.setproperty(“extent.reporter.pdf.config”,”configs/pdf-config.yaml”);

    much appreciate your response.

      1. I have a separate folder for all configuration.properties in a separate folder , and was thinking to align the reporting properties also at the same location

          1. Appreciate your work, yes It would be helpful to have them aligned at a single location.

            Also I noticed another thing, I am using the cucumber 5 adaptor and it was allowing me to set the extent properties from system.set property, but when I do the same for this version it throws an error java.lang.exceptioninitalizeerror…is the extent properties file also hard-coded?

              1. This is the stacktrace i get: io.cucumber.core.exception.CucumberException: java.lang.ExceptionInInitializerError

                at io.cucumber.core.plugin.PluginFactory.newInstance(PluginFactory.java:120)
                at io.cucumber.core.plugin.PluginFactory.instantiate(PluginFactory.java:99)
                at io.cucumber.core.plugin.PluginFactory.create(PluginFactory.java:63)
                at io.cucumber.core.plugin.Plugins.createPlugins(Plugins.java:32)
                at io.cucumber.core.plugin.Plugins.(Plugins.java:25)
                at io.cucumber.testng.TestNGCucumberRunner.(TestNGCucumberRunner.java:108)
                at io.cucumber.testng.AbstractTestNGCucumberTests.setUpClass(AbstractTestNGCucumberTests.java:27)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.base/java.lang.reflect.Method.invoke(Method.java:566)
                at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
                at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:62)
                at org.testng.internal.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:340)
                at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:294)
                at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:176)
                at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:122)
                at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
                at org.testng.TestRunner.privateRun(TestRunner.java:770)
                at org.testng.TestRunner.run(TestRunner.java:591)
                at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
                at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:396)
                at org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
                at org.testng.SuiteRunner.run(SuiteRunner.java:304)
                at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
                at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
                at org.testng.TestNG.runSuitesSequentially(TestNG.java:1180)
                at org.testng.TestNG.runSuitesLocally(TestNG.java:1102)
                at org.testng.TestNG.runSuites(TestNG.java:1032)
                at org.testng.TestNG.run(TestNG.java:1000)
                at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
                at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
                Caused by: java.lang.ExceptionInInitializerError
                at com.aventstack.extentreports.service.ExtentService.getInstance(ExtentService.java:37)
                at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.(ExtentCucumberAdapter.java:141)
                at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
                at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
                at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
                at io.cucumber.core.plugin.PluginFactory.newInstance(PluginFactory.java:116)
                … 31 more
                Caused by: java.lang.NullPointerException
                at com.aventstack.extentreports.service.ExtentService$ExtentReportsLoader.sparkBase64PngImageStyle(ExtentService.java:245)
                at com.aventstack.extentreports.service.ExtentService$ExtentReportsLoader.initSpark(ExtentService.java:230)
                at com.aventstack.extentreports.service.ExtentService$ExtentReportsLoader.createViaSystem(ExtentService.java:158)
                at com.aventstack.extentreports.service.ExtentService$ExtentReportsLoader.(ExtentService.java:114)
                … 38 more

                I set the properties in TestNG by @Override
                public void onStart(ITestContext context) {
                ….
                ….
                System.setProperty(“extent.reporter.klov.start”, “false”);
                System.setProperty(“extent.reporter.spark.start”, “true”);
                System.setProperty(“extent.reporter.json.start”, “true”);
                System.setProperty(“extent.reporter.pdf.start”, “false”);

                System.setProperty(“extent.reporter.klov.config”, “src/test/resources/klov.properties”);
                System.setProperty(“extent.reporter.spark.config”, “configs/extent-config.xml”);

                System.setProperty(“extent.reporter.spark.out”, “test-output/Spark/ExtentSpark.html”);
                System.setProperty(“extent.reporter.json.out”, “test-output/Json/ExtentJson.json”);
                System.setProperty(“extent.reporter.pdf.out”, “test-output/PdfReport/ExtentPdf.pdf”);
                ….
                ….

                }

                and Java Version is 11

              2. Have to check the code. In the meanwhile, you can create a extent.properties in ur src/test/resources folder and add the extent.reporter.spark.base64imagesrc=false property. I think this work around should work. Not really sure why u are setting properties in the code.

Leave a Reply

Your email address will not be published. Required fields are marked *