diff --git a/.gitignore b/.gitignore index 7b26945..36fdb7a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ *.iml target output -*.DS_Store \ No newline at end of file +*.DS_Store +/test-output/report.html diff --git a/Changelog.md b/Changelog.md index 26c2ffa..6e0d5c6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,8 @@ # Changelog +### v2.0.3 +- Fixed the bug while running on parallel using TestNG + ### v2.0.2 - Fixed the system info when execute from multiple runners diff --git a/Readme.md b/Readme.md index 55551dc..439a600 100644 --- a/Readme.md +++ b/Readme.md @@ -14,7 +14,7 @@ If you are using a maven based project, you can directly add this library as a d com.vimalselvam cucumber-extentsreport - 2.0.1 + 2.0.3 ``` @@ -64,6 +64,8 @@ public class RunCukesTest { ``` +Please note that the plugin `com.cucumber.listener.ExtentCucumberFormatter` takes an argument of where the report file should be generated. If you omit the parameter of file path, the report will be generated in the `test-output` folder in your project directory by default with the file name as `report.html`. + The above example shows a JUnit runner. However, you can use the TestNG runner too. Also make sure the `loadXMLConfig`, `setSystemInfo` and `setTestRunnerOutput` methods should be in your `@AfterClass` method. diff --git a/pom.xml b/pom.xml index 184d27b..a54d357 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,19 @@ com.vimalselvam cucumber-extentsreport - 2.0.2 + 2.0.3 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + jar Cucumber Extents Report @@ -57,6 +69,13 @@ test + + info.cukes + cucumber-testng + ${cucumber.version} + test + + junit junit diff --git a/src/main/java/com/cucumber/listener/ExtentCucumberFormatter.java b/src/main/java/com/cucumber/listener/ExtentCucumberFormatter.java index a777392..4ec151c 100644 --- a/src/main/java/com/cucumber/listener/ExtentCucumberFormatter.java +++ b/src/main/java/com/cucumber/listener/ExtentCucumberFormatter.java @@ -7,17 +7,7 @@ import com.aventstack.extentreports.reporter.ExtentHtmlReporter; import gherkin.formatter.Formatter; import gherkin.formatter.Reporter; -import gherkin.formatter.model.Background; -import gherkin.formatter.model.DataTableRow; -import gherkin.formatter.model.Examples; -import gherkin.formatter.model.ExamplesTableRow; -import gherkin.formatter.model.Feature; -import gherkin.formatter.model.Match; -import gherkin.formatter.model.Result; -import gherkin.formatter.model.Scenario; -import gherkin.formatter.model.ScenarioOutline; -import gherkin.formatter.model.Step; -import gherkin.formatter.model.Tag; +import gherkin.formatter.model.*; import java.io.File; import java.util.LinkedList; @@ -27,43 +17,54 @@ * A cucumber based reporting listener which generates the Extent Report */ public class ExtentCucumberFormatter implements Reporter, Formatter { - private static ThreadLocal reportsThreadLocal = new ThreadLocal(); - private static ThreadLocal htmlReporterThreadLocal = - new ThreadLocal(); - private static ThreadLocal featureTestThreadLocal = new ThreadLocal(); - private static ThreadLocal scenarioOutlineThreadLocal = - new ThreadLocal(); - static ThreadLocal scenarioThreadLocal = new ThreadLocal(); + private static ExtentReports extentReports; + private static ExtentHtmlReporter htmlReporter; + private static ThreadLocal featureTestThreadLocal = new InheritableThreadLocal<>(); + private static ThreadLocal scenarioOutlineThreadLocal = new InheritableThreadLocal<>(); + static ThreadLocal scenarioThreadLocal = new InheritableThreadLocal<>(); private static ThreadLocal> stepListThreadLocal = - new ThreadLocal>(); - static ThreadLocal stepTestThreadLocal = new ThreadLocal(); + new InheritableThreadLocal<>(); + static ThreadLocal stepTestThreadLocal = new InheritableThreadLocal<>(); private boolean scenarioOutlineFlag; + public ExtentCucumberFormatter() { + this(null); + } + public ExtentCucumberFormatter(File file) { - if (getExtentReport() == null) { - setExtentHtmlReport(new ExtentHtmlReporter(file)); - ExtentReports extentReports = new ExtentReports(); - extentReports.attachReporter(getExtentHtmlReport()); - setExtentReport(extentReports); - } + setExtentHtmlReport(file); + setExtentReport(); stepListThreadLocal.set(new LinkedList()); scenarioOutlineFlag = false; } - private static void setExtentHtmlReport(ExtentHtmlReporter htmlReport) { - htmlReporterThreadLocal.set(htmlReport); + private static void setExtentHtmlReport(File file) { + if (htmlReporter != null) { + return; + } + if (file == null) { + file = new File("test-output/report.html"); + if (!file.exists()) { + file.getParentFile().mkdirs(); + } + } + htmlReporter = new ExtentHtmlReporter(file); } static ExtentHtmlReporter getExtentHtmlReport() { - return htmlReporterThreadLocal.get(); + return htmlReporter; } - private static void setExtentReport(ExtentReports extentReports) { - reportsThreadLocal.set(extentReports); + private static void setExtentReport() { + if (extentReports != null) { + return; + } + extentReports = new ExtentReports(); + extentReports.attachReporter(htmlReporter); } static ExtentReports getExtentReport() { - return reportsThreadLocal.get(); + return extentReports; } public void syntaxError(String state, String event, List legalEvents, String uri, diff --git a/src/main/java/com/cucumber/listener/Reporter.java b/src/main/java/com/cucumber/listener/Reporter.java index 9fbb8ac..e5f93cc 100644 --- a/src/main/java/com/cucumber/listener/Reporter.java +++ b/src/main/java/com/cucumber/listener/Reporter.java @@ -14,7 +14,7 @@ * This class houses few utilities required for the report */ public class Reporter { - private static Map systemInfoKeyMap = new HashMap(); + private static Map systemInfoKeyMap = new HashMap<>(); private Reporter() { // Defeat instantiation diff --git a/src/test/java/com/cucumber/runner/MyTestNGCukesRunner.java b/src/test/java/com/cucumber/runner/MyTestNGCukesRunner.java new file mode 100644 index 0000000..41efab7 --- /dev/null +++ b/src/test/java/com/cucumber/runner/MyTestNGCukesRunner.java @@ -0,0 +1,23 @@ +package com.cucumber.runner; + +import com.cucumber.listener.Reporter; +import cucumber.api.CucumberOptions; +import cucumber.api.testng.AbstractTestNGCucumberTests; +import org.testng.annotations.AfterClass; + +import java.io.File; + +@CucumberOptions( + features = {"src/test/resources/features/MySecondFeature.feature"}, + glue = {"com.cucumber.stepdefinitions"}, + plugin = {"com.cucumber.listener.ExtentCucumberFormatter"} +) +public class MyTestNGCukesRunner extends AbstractTestNGCucumberTests { + @AfterClass + public static void setup() { + Reporter.loadXMLConfig(new File("src/test/resources/extent-config.xml")); + Reporter.setSystemInfo("user", System.getProperty("user.name")); + Reporter.setSystemInfo("os", "Mac OSX"); + Reporter.setTestRunnerOutput("Sample test runner output message"); + } +} diff --git a/src/test/java/com/cucumber/runner/TestNGCukesRunner.java b/src/test/java/com/cucumber/runner/TestNGCukesRunner.java new file mode 100644 index 0000000..1bd2ab5 --- /dev/null +++ b/src/test/java/com/cucumber/runner/TestNGCukesRunner.java @@ -0,0 +1,23 @@ +package com.cucumber.runner; + +import com.cucumber.listener.Reporter; +import cucumber.api.CucumberOptions; +import cucumber.api.testng.AbstractTestNGCucumberTests; +import org.testng.annotations.AfterClass; + +import java.io.File; + +@CucumberOptions( + features = {"src/test/resources/features/MyFeature.feature"}, + glue = {"com.cucumber.stepdefinitions"}, + plugin = {"com.cucumber.listener.ExtentCucumberFormatter"} +) +public class TestNGCukesRunner extends AbstractTestNGCucumberTests { + @AfterClass + public static void setup() { + Reporter.loadXMLConfig(new File("src/test/resources/extent-config.xml")); + Reporter.setSystemInfo("user", System.getProperty("user.name")); + Reporter.setSystemInfo("os", "Mac OSX"); + Reporter.setTestRunnerOutput("Sample test runner output message"); + } +} diff --git a/src/test/resources/suite.xml b/src/test/resources/suite.xml new file mode 100644 index 0000000..4345a40 --- /dev/null +++ b/src/test/resources/suite.xml @@ -0,0 +1,10 @@ + + + + + + + + + +