3434import cucumber .api .formatter .Formatter ;
3535import cucumber .runtime .CucumberException ;
3636import cucumber .runtime .io .URLOutputStream ;
37- import gherkin .ast .Background ;
3837import gherkin .ast .DataTable ;
3938import gherkin .ast .DocString ;
4039import gherkin .ast .Examples ;
5352import gherkin .pickles .PickleTable ;
5453
5554/**
56- * A port of Cucumber-JVM (MIT licensed) HtmlFormatter for Extent Framework
57- * Original source: https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/HTMLFormatter.java
55+ * A port of Cucumber-JVM (MIT licensed) HtmlFormatter for Extent Framework
56+ * Original source:
57+ * https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/HTMLFormatter.java
5858 *
5959 */
60- public class ExtentCucumberAdapter
61- implements Formatter {
60+ public class ExtentCucumberAdapter implements Formatter {
6261
6362 private static final String SCREENSHOT_DIR_PROPERTY = "screenshot.dir" ;
64-
63+
6564 private static ThreadLocal <ExtentTest > featureTestThreadLocal = new InheritableThreadLocal <>();
6665 private static ThreadLocal <ExtentTest > scenarioOutlineThreadLocal = new InheritableThreadLocal <>();
6766 private static ThreadLocal <ExtentTest > scenarioThreadLocal = new InheritableThreadLocal <>();
6867 private static ThreadLocal <ExtentTest > stepTestThreadLocal = new InheritableThreadLocal <>();
69-
68+
7069 @ SuppressWarnings ("serial" )
7170 private static final Map <String , String > MIME_TYPES_EXTENSIONS = new HashMap <String , String >() {
7271 {
@@ -78,9 +77,9 @@ public class ExtentCucumberAdapter
7877 put ("video/ogg" , "ogg" );
7978 }
8079 };
81-
80+
8281 private static final AtomicInteger EMBEDDED_INT = new AtomicInteger (0 );
83-
82+
8483 private final TestSourcesModel testSources = new TestSourcesModel ();
8584
8685 private ThreadLocal <String > currentFeatureFile = new ThreadLocal <>();
@@ -93,7 +92,7 @@ public void receive(TestSourceRead event) {
9392 handleTestSourceRead (event );
9493 }
9594 };
96- private EventHandler <TestCaseStarted > caseStartedHandler = new EventHandler <TestCaseStarted >() {
95+ private EventHandler <TestCaseStarted > caseStartedHandler = new EventHandler <TestCaseStarted >() {
9796 @ Override
9897 public void receive (TestCaseStarted event ) {
9998 handleTestCaseStarted (event );
@@ -130,8 +129,9 @@ public void receive(TestRunFinished event) {
130129 }
131130 };
132131
133- public ExtentCucumberAdapter (String s ) { }
134-
132+ public ExtentCucumberAdapter (String s ) {
133+ }
134+
135135 @ Override
136136 public void setEventPublisher (EventPublisher publisher ) {
137137 publisher .registerHandlerFor (TestSourceRead .class , testSourceReadHandler );
@@ -151,7 +151,7 @@ private void handleTestCaseStarted(TestCaseStarted event) {
151151 handleStartOfFeature (event .testCase );
152152 handleScenarioOutline (event .testCase );
153153 createTestCase (event .testCase );
154- if (testSources .hasBackground (currentFeatureFile .get (), event .testCase .getLine ())) {
154+ if (testSources .hasBackground (currentFeatureFile .get (), event .testCase .getLine ())) {
155155 // background
156156 }
157157 }
@@ -170,13 +170,15 @@ private void handleEmbed(EmbedEvent event) {
170170 String mimeType = event .mimeType ;
171171 String extension = MIME_TYPES_EXTENSIONS .get (mimeType );
172172 if (extension != null ) {
173- StringBuilder fileName = new StringBuilder ("embedded" ).append (EMBEDDED_INT .incrementAndGet ()).append ("." ).append (extension );
173+ StringBuilder fileName = new StringBuilder ("embedded" ).append (EMBEDDED_INT .incrementAndGet ()).append ("." )
174+ .append (extension );
174175 try {
175176 URL url = toUrl (fileName .toString ());
176177 writeBytesToURL (event .data , url );
177178 try {
178179 File f = new File (url .toURI ());
179- stepTestThreadLocal .get ().info ("" , MediaEntityBuilder .createScreenCaptureFromPath (f .getAbsolutePath ()).build ());
180+ stepTestThreadLocal .get ().info ("" ,
181+ MediaEntityBuilder .createScreenCaptureFromPath (f .getAbsolutePath ()).build ());
180182 } catch (URISyntaxException e ) {
181183 e .printStackTrace ();
182184 }
@@ -194,27 +196,28 @@ private static void writeBytesToURL(byte[] buf, URL url) throws IOException {
194196 throw new IOException ("Unable to write to report file item: " , e );
195197 }
196198 }
197-
199+
198200 private static OutputStream createReportFileOutputStream (URL url ) {
199201 try {
200202 return new URLOutputStream (url );
201203 } catch (IOException e ) {
202204 throw new CucumberException (e );
203205 }
204206 }
205-
207+
206208 private URL toUrl (String fileName ) {
207209 try {
208210 Object prop = ExtentService .getProperty (SCREENSHOT_DIR_PROPERTY );
209211 String screenshotDir = prop == null ? "test-output/" : String .valueOf (prop );
210212 URL url = Paths .get (screenshotDir , fileName ).toUri ().toURL ();
211213 return url ;
212214 } catch (IOException e ) {
213- throw new CucumberException (e );
215+ throw new CucumberException (e );
214216 }
215217 }
216218
217- private void handleWrite (WriteEvent event ) { }
219+ private void handleWrite (WriteEvent event ) {
220+ }
218221
219222 private void finishReport () {
220223 ExtentService .getInstance ().flush ();
@@ -230,17 +233,19 @@ private void handleStartOfFeature(TestCase testCase) {
230233 private void createFeature (TestCase testCase ) {
231234 Feature feature = testSources .getFeature (testCase .getUri ());
232235 if (feature != null ) {
233- if (featureTestThreadLocal .get () != null && featureTestThreadLocal .get ().getModel ().getName ().equals (feature .getName ())) {
236+ if (featureTestThreadLocal .get () != null
237+ && featureTestThreadLocal .get ().getModel ().getName ().equals (feature .getName ())) {
234238 return ;
235239 }
236- ExtentTest t = ExtentService .getInstance ()
237- .createTest (com .aventstack .extentreports .gherkin .model .Feature .class , feature .getName (), feature .getDescription ());
240+ ExtentTest t = ExtentService .getInstance ().createTest (
241+ com .aventstack .extentreports .gherkin .model .Feature .class , feature .getName (),
242+ feature .getDescription ());
238243 featureTestThreadLocal .set (t );
239244 List <String > tagList = createTagsList (feature .getTags ());
240245 tagList .forEach (featureTestThreadLocal .get ()::assignCategory );
241246 }
242247 }
243-
248+
244249 private List <String > createTagsList (List <Tag > tags ) {
245250 List <String > tagList = new ArrayList <>();
246251 for (Tag tag : tags ) {
@@ -252,14 +257,15 @@ private List<String> createTagsList(List<Tag> tags) {
252257 private void handleScenarioOutline (TestCase testCase ) {
253258 TestSourcesModel .AstNode astNode = testSources .getAstNode (currentFeatureFile .get (), testCase .getLine ());
254259 if (TestSourcesModel .isScenarioOutlineScenario (astNode )) {
255- ScenarioOutline scenarioOutline = (ScenarioOutline )TestSourcesModel .getScenarioDefinition (astNode );
256- if (currentScenarioOutline .get () == null || !currentScenarioOutline .get ().getName ().equals (scenarioOutline .getName ())) {
260+ ScenarioOutline scenarioOutline = (ScenarioOutline ) TestSourcesModel .getScenarioDefinition (astNode );
261+ if (currentScenarioOutline .get () == null
262+ || !currentScenarioOutline .get ().getName ().equals (scenarioOutline .getName ())) {
257263 scenarioOutlineThreadLocal .set (null );
258264 createScenarioOutline (scenarioOutline );
259265 currentScenarioOutline .set (scenarioOutline );
260266 addOutlineStepsToReport (scenarioOutline );
261267 }
262- Examples examples = (Examples )astNode .parent .node ;
268+ Examples examples = (Examples ) astNode .parent .node ;
263269 if (currentExamples .get () == null || !currentExamples .get ().equals (examples )) {
264270 currentExamples .set (examples );
265271 createExamples (examples );
@@ -273,8 +279,9 @@ private void handleScenarioOutline(TestCase testCase) {
273279
274280 private void createScenarioOutline (ScenarioOutline scenarioOutline ) {
275281 if (scenarioOutlineThreadLocal .get () == null ) {
276- ExtentTest t = featureTestThreadLocal .get ()
277- .createNode (com .aventstack .extentreports .gherkin .model .ScenarioOutline .class , scenarioOutline .getName (), scenarioOutline .getDescription ());
282+ ExtentTest t = featureTestThreadLocal .get ().createNode (
283+ com .aventstack .extentreports .gherkin .model .ScenarioOutline .class , scenarioOutline .getName (),
284+ scenarioOutline .getDescription ());
278285 scenarioOutlineThreadLocal .set (t );
279286 List <String > tags = createTagsList (scenarioOutline .getTags ());
280287 tags .forEach (scenarioOutlineThreadLocal .get ()::assignCategory );
@@ -286,9 +293,9 @@ private void addOutlineStepsToReport(ScenarioOutline scenarioOutline) {
286293 if (step .getArgument () != null ) {
287294 Node argument = step .getArgument ();
288295 if (argument instanceof DocString ) {
289- createDocStringMap ((DocString )argument );
296+ createDocStringMap ((DocString ) argument );
290297 } else if (argument instanceof DataTable ) {
291-
298+
292299 }
293300 }
294301 }
@@ -300,12 +307,6 @@ private Map<String, Object> createDocStringMap(DocString docString) {
300307 return docStringMap ;
301308 }
302309
303- private Map <String , Object > createRowMap (TableRow row ) {
304- Map <String , Object > rowMap = new HashMap <String , Object >();
305- rowMap .put ("cells" , createCellList (row ));
306- return rowMap ;
307- }
308-
309310 private List <String > createCellList (TableRow row ) {
310311 List <String > cells = new ArrayList <String >();
311312 for (TableCell cell : row .getCells ()) {
@@ -326,7 +327,7 @@ private void createExamples(Examples examples) {
326327 markup = scenarioOutlineThreadLocal .get ().getModel ().getDescription () + markup ;
327328 scenarioOutlineThreadLocal .get ().getModel ().setDescription (markup );
328329 }
329-
330+
330331 private String [][] getTable (List <TableRow > rows ) {
331332 String data [][] = null ;
332333 int rowSize = rows .size ();
@@ -348,8 +349,10 @@ private void createTestCase(TestCase testCase) {
348349 TestSourcesModel .AstNode astNode = testSources .getAstNode (currentFeatureFile .get (), testCase .getLine ());
349350 if (astNode != null ) {
350351 ScenarioDefinition scenarioDefinition = TestSourcesModel .getScenarioDefinition (astNode );
351- ExtentTest parent = scenarioOutlineThreadLocal .get () != null ? scenarioOutlineThreadLocal .get () : featureTestThreadLocal .get ();
352- ExtentTest t = parent .createNode (com .aventstack .extentreports .gherkin .model .Scenario .class , scenarioDefinition .getName (), scenarioDefinition .getDescription ());
352+ ExtentTest parent = scenarioOutlineThreadLocal .get () != null ? scenarioOutlineThreadLocal .get ()
353+ : featureTestThreadLocal .get ();
354+ ExtentTest t = parent .createNode (com .aventstack .extentreports .gherkin .model .Scenario .class ,
355+ scenarioDefinition .getName (), scenarioDefinition .getDescription ());
353356 scenarioThreadLocal .set (t );
354357 }
355358 if (!testCase .getTags ().isEmpty ()) {
@@ -363,11 +366,10 @@ private void createTestStep(TestStep testStep) {
363366 if (astNode != null ) {
364367 Step step = (Step ) astNode .node ;
365368 try {
366- String name = stepName == null || stepName .isEmpty ()
367- ? step .getText ().replace ("<" , "<" ).replace (">" , ">" )
368- : stepName ;
369- ExtentTest t = scenarioThreadLocal .get ()
370- .createNode (new GherkinKeyword (step .getKeyword ().trim ()), step .getKeyword () + name );
369+ String name = stepName == null || stepName .isEmpty ()
370+ ? step .getText ().replace ("<" , "<" ).replace (">" , ">" ) : stepName ;
371+ ExtentTest t = scenarioThreadLocal .get ().createNode (new GherkinKeyword (step .getKeyword ().trim ()),
372+ step .getKeyword () + name );
371373 stepTestThreadLocal .set (t );
372374 } catch (ClassNotFoundException e ) {
373375 e .printStackTrace ();
@@ -376,7 +378,7 @@ private void createTestStep(TestStep testStep) {
376378 if (!testStep .getStepArgument ().isEmpty ()) {
377379 Argument argument = testStep .getStepArgument ().get (0 );
378380 if (argument instanceof PickleString ) {
379- createDocStringMap ((PickleString )argument );
381+ createDocStringMap ((PickleString ) argument );
380382 } else if (argument instanceof PickleTable ) {
381383 List <PickleRow > rows = ((PickleTable ) argument ).getRows ();
382384 stepTestThreadLocal .get ().pass (MarkupHelper .createTable (getPickleTable (rows )).getMarkup ());
@@ -400,7 +402,7 @@ private String[][] getPickleTable(List<PickleRow> rows) {
400402 }
401403 return data ;
402404 }
403-
405+
404406 private Map <String , Object > createDocStringMap (PickleString docString ) {
405407 Map <String , Object > docStringMap = new HashMap <String , Object >();
406408 docStringMap .put ("value" , docString .getContent ());
@@ -409,29 +411,29 @@ private Map<String, Object> createDocStringMap(PickleString docString) {
409411
410412 private synchronized void updateResult (Result result ) {
411413 switch (result .getStatus ().lowerCaseName ()) {
412- case "failed" :
413- stepTestThreadLocal .get ().fail (result .getError ());
414- break ;
415- case "skipped" :
416- case "pending" :
417- Boolean currentEndingEventSkipped = stepTestThreadLocal .get ().getModel ().getLogContext () != null
414+ case "failed" :
415+ stepTestThreadLocal .get ().fail (result .getError ());
416+ break ;
417+ case "skipped" :
418+ case "pending" :
419+ Boolean currentEndingEventSkipped = stepTestThreadLocal .get ().getModel ().getLogContext () != null
418420 && !stepTestThreadLocal .get ().getModel ().getLogContext ().isEmpty ()
419- ? stepTestThreadLocal .get ().getModel ().getLogContext ().getLast ().getStatus () == Status .SKIP
420- : false ;
421- if (result .getError () != null ) {
422- stepTestThreadLocal .get ().skip (result .getError ());
423- } else if (!currentEndingEventSkipped ) {
424- String details = result .getErrorMessage () == null ? "Step skipped" : result .getErrorMessage ();
425- stepTestThreadLocal .get ().skip (details );
426- }
427- break ;
428- case "passed" :
429- if (stepTestThreadLocal .get ()!= null && stepTestThreadLocal .get ().getModel ().getLogContext ().isEmpty ())
430- stepTestThreadLocal .get ().pass ("" );
431- break ;
432- default :
433- break ;
421+ ? stepTestThreadLocal .get ().getModel ().getLogContext ().getLast ().getStatus () == Status .SKIP
422+ : false ;
423+ if (result .getError () != null ) {
424+ stepTestThreadLocal .get ().skip (result .getError ());
425+ } else if (!currentEndingEventSkipped ) {
426+ String details = result .getErrorMessage () == null ? "Step skipped" : result .getErrorMessage ();
427+ stepTestThreadLocal .get ().skip (details );
428+ }
429+ break ;
430+ case "passed" :
431+ if (stepTestThreadLocal .get () != null && stepTestThreadLocal .get ().getModel ().getLogContext ().isEmpty ())
432+ stepTestThreadLocal .get ().pass ("" );
433+ break ;
434+ default :
435+ break ;
434436 }
435437 }
436-
438+
437439}
0 commit comments