From edfa138bb2ea03f81076e662c0cc7d23b58b702c Mon Sep 17 00:00:00 2001 From: far11ven Date: Mon, 2 Dec 2019 20:59:19 +0530 Subject: [PATCH 1/4] added methods to support addStepLog,addStepScreenCaptureFromPath,setSystemInfo,setTestRunnerOutput --- .../adapter/ExtentCucumberAdapter.java | 815 +++++++++--------- .../extentreports/service/ExtentService.java | 19 + 2 files changed, 438 insertions(+), 396 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java b/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java index 493f2f4..724f709 100644 --- a/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java +++ b/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java @@ -54,403 +54,426 @@ import gherkin.pickles.PickleTable; /** - * A port of Cucumber-JVM (MIT licensed) HtmlFormatter for Extent Framework - * Original source: https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/HTMLFormatter.java + * A port of Cucumber-JVM (MIT licensed) HtmlFormatter for Extent Framework + * Original source: + * https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/HTMLFormatter.java * */ -public class ExtentCucumberAdapter - implements ConcurrentEventListener { - - private static final String SCREENSHOT_DIR_PROPERTY = "screenshot.dir"; - - private static Map featureMap = new ConcurrentHashMap<>(); - private static ThreadLocal featureTestThreadLocal = new InheritableThreadLocal<>(); - private static Map scenarioOutlineMap = new ConcurrentHashMap<>(); - private static ThreadLocal scenarioOutlineThreadLocal = new InheritableThreadLocal<>(); - private static ThreadLocal scenarioThreadLocal = new InheritableThreadLocal<>(); - private static ThreadLocal isHookThreadLocal = new InheritableThreadLocal<>(); - private static ThreadLocal stepTestThreadLocal = new InheritableThreadLocal<>(); - - @SuppressWarnings("serial") - private static final Map MIME_TYPES_EXTENSIONS = new HashMap() { - { - put("image/bmp", "bmp"); - put("image/gif", "gif"); - put("image/jpeg", "jpg"); - put("image/png", "png"); - put("image/svg+xml", "svg"); - put("video/ogg", "ogg"); - } - }; - - private static final AtomicInteger EMBEDDED_INT = new AtomicInteger(0); - - private final TestSourcesModel testSources = new TestSourcesModel(); - - private ThreadLocal currentFeatureFile = new ThreadLocal<>(); - private ThreadLocal currentScenarioOutline = new InheritableThreadLocal<>(); - private ThreadLocal currentExamples = new InheritableThreadLocal<>(); - - private EventHandler testSourceReadHandler = new EventHandler() { - @Override - public void receive(TestSourceRead event) { - handleTestSourceRead(event); - } - }; - private EventHandler caseStartedHandler= new EventHandler() { - @Override - public void receive(TestCaseStarted event) { - handleTestCaseStarted(event); - } - }; - private EventHandler stepStartedHandler = new EventHandler() { - @Override - public void receive(TestStepStarted event) { - handleTestStepStarted(event); - } - }; - private EventHandler stepFinishedHandler = new EventHandler() { - @Override - public void receive(TestStepFinished event) { - handleTestStepFinished(event); - } - }; - private EventHandler embedEventhandler = new EventHandler() { - @Override - public void receive(EmbedEvent event) { - handleEmbed(event); - } - }; - private EventHandler writeEventhandler = new EventHandler() { - @Override - public void receive(WriteEvent event) { - handleWrite(event); - } - }; - private EventHandler runFinishedHandler = new EventHandler() { - @Override - public void receive(TestRunFinished event) { - finishReport(); - } - }; - - public ExtentCucumberAdapter(String arg) { } - - @Override - public void setEventPublisher(EventPublisher publisher) { - publisher.registerHandlerFor(TestSourceRead.class, testSourceReadHandler); - publisher.registerHandlerFor(TestCaseStarted.class, caseStartedHandler); - publisher.registerHandlerFor(TestStepStarted.class, stepStartedHandler); - publisher.registerHandlerFor(TestStepFinished.class, stepFinishedHandler); - publisher.registerHandlerFor(EmbedEvent.class, embedEventhandler); - publisher.registerHandlerFor(WriteEvent.class, writeEventhandler); - publisher.registerHandlerFor(TestRunFinished.class, runFinishedHandler); - } - - private void handleTestSourceRead(TestSourceRead event) { - testSources.addTestSourceReadEvent(event.uri, event); - } - - private synchronized void handleTestCaseStarted(TestCaseStarted event) { - handleStartOfFeature(event.testCase); - handleScenarioOutline(event.testCase); - createTestCase(event.testCase); - if (testSources.hasBackground(currentFeatureFile.get(), event.testCase.getLine())) { - // background - } - } - - private synchronized void handleTestStepStarted(TestStepStarted event) { - isHookThreadLocal.set(false); - - if (event.testStep instanceof HookTestStep) { - ExtentTest t = scenarioThreadLocal.get() - .createNode(Asterisk.class, event.testStep.getCodeLocation()); - stepTestThreadLocal.set(t); - isHookThreadLocal.set(true); - } - - if (event.testStep instanceof PickleStepTestStep) { - PickleStepTestStep testStep = (PickleStepTestStep) event.testStep; - createTestStep(testStep); - } - } - - private synchronized void handleTestStepFinished(TestStepFinished event) { - updateResult(event.result); - } - - private synchronized void updateResult(Result result) { - switch (result.getStatus().lowerCaseName()) { - case "failed": - stepTestThreadLocal.get().fail(result.getError()); - break; - case "skipped": - case "pending": - Boolean currentEndingEventSkipped = stepTestThreadLocal.get().getModel().getLogContext() != null - && !stepTestThreadLocal.get().getModel().getLogContext().isEmpty() - ? stepTestThreadLocal.get().getModel().getLogContext().getLast().getStatus() == Status.SKIP - : false; - if (result.getError() != null) { - stepTestThreadLocal.get().skip(result.getError()); - } else if (!currentEndingEventSkipped) { - String details = result.getErrorMessage() == null ? "Step skipped" : result.getErrorMessage(); - stepTestThreadLocal.get().skip(details); - } - break; - case "passed": - if (stepTestThreadLocal.get()!= null && stepTestThreadLocal.get().getModel().getLogContext().isEmpty()) { - stepTestThreadLocal.get().pass(""); - } - if (isHookThreadLocal.get() && !stepTestThreadLocal.get().getModel().hasLog() && !stepTestThreadLocal.get().getModel().getLogContext().getFirst().hasScreenCapture()) { - ExtentService.getInstance().removeTest(stepTestThreadLocal.get()); - } - break; - default: - break; - } - } - - private synchronized void handleEmbed(EmbedEvent event) { - String mimeType = event.mimeType; - String extension = MIME_TYPES_EXTENSIONS.get(mimeType); - if (extension != null) { - StringBuilder fileName = new StringBuilder("embedded").append(EMBEDDED_INT.incrementAndGet()).append(".").append(extension); - try { - URL url = toUrl(fileName.toString()); - writeBytesToURL(event.data, url); - try { - File f = new File(url.toURI()); - stepTestThreadLocal.get().info("", MediaEntityBuilder.createScreenCaptureFromPath(f.getAbsolutePath()).build()); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static void writeBytesToURL(byte[] buf, URL url) throws IOException { - OutputStream out = createReportFileOutputStream(url); - try { - out.write(buf); - } catch (IOException e) { - throw new IOException("Unable to write to report file item: ", e); - } - } - - private static OutputStream createReportFileOutputStream(URL url) { - try { - return new URLOutputStream(url); - } catch (IOException e) { - throw new CucumberException(e); - } - } - - private URL toUrl(String fileName) { - try { - Object prop = ExtentService.getProperty(SCREENSHOT_DIR_PROPERTY); - String screenshotDir = prop == null ? "test-output/" : String.valueOf(prop); - URL url = Paths.get(screenshotDir, fileName).toUri().toURL(); - return url; - } catch (IOException e) { - throw new CucumberException(e); - } - } - - private void handleWrite(WriteEvent event) { - String text = event.text; - if (text != null && !text.isEmpty()) { - stepTestThreadLocal.get().info(text); - } - } - - private void finishReport() { - ExtentService.getInstance().flush(); - } - - private synchronized void handleStartOfFeature(TestCase testCase) { - if (currentFeatureFile == null || !currentFeatureFile.equals(testCase.getUri())) { - currentFeatureFile.set(testCase.getUri()); - createFeature(testCase); - } - } - - private synchronized void createFeature(TestCase testCase) { - Feature feature = testSources.getFeature(testCase.getUri()); - if (feature != null) { - if (featureMap.containsKey(feature.getName())) { - featureTestThreadLocal.set(featureMap.get(feature.getName())); - return; - } - if (featureTestThreadLocal.get() != null && featureTestThreadLocal.get().getModel().getName().equals(feature.getName())) { - return; - } - ExtentTest t = ExtentService.getInstance() - .createTest(com.aventstack.extentreports.gherkin.model.Feature.class, feature.getName(), feature.getDescription()); - featureTestThreadLocal.set(t); - featureMap.put(feature.getName(), t); - List tagList = createTagsList(feature.getTags()); - tagList.forEach(featureTestThreadLocal.get()::assignCategory); - } - } - - private List createTagsList(List tags) { - List tagList = new ArrayList<>(); - for (Tag tag : tags) { - tagList.add(tag.getName()); - } - return tagList; - } - - private synchronized void handleScenarioOutline(TestCase testCase) { - TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); - if (TestSourcesModel.isScenarioOutlineScenario(astNode)) { - ScenarioOutline scenarioOutline = (ScenarioOutline)TestSourcesModel.getScenarioDefinition(astNode); - if (currentScenarioOutline.get() == null || !currentScenarioOutline.get().getName().equals(scenarioOutline.getName())) { - scenarioOutlineThreadLocal.set(null); - createScenarioOutline(scenarioOutline); - currentScenarioOutline.set(scenarioOutline); - addOutlineStepsToReport(scenarioOutline); - } - Examples examples = (Examples)astNode.parent.node; - if (currentExamples.get() == null || !currentExamples.get().equals(examples)) { - currentExamples.set(examples); - createExamples(examples); - } - } else { - scenarioOutlineThreadLocal.set(null); - currentScenarioOutline.set(null); - currentExamples.set(null); - } - } - - private synchronized void createScenarioOutline(ScenarioOutline scenarioOutline) { - if (scenarioOutlineMap.containsKey(scenarioOutline.getName())) { - scenarioOutlineThreadLocal.set(scenarioOutlineMap.get(scenarioOutline.getName())); - return; - } - if (scenarioOutlineThreadLocal.get() == null) { - ExtentTest t = featureTestThreadLocal.get() - .createNode(com.aventstack.extentreports.gherkin.model.ScenarioOutline.class, scenarioOutline.getName(), scenarioOutline.getDescription()); - scenarioOutlineThreadLocal.set(t); - scenarioOutlineMap.put(scenarioOutline.getName(), t); - List tags = createTagsList(scenarioOutline.getTags()); - tags.forEach(scenarioOutlineThreadLocal.get()::assignCategory); - } - } - - private synchronized void addOutlineStepsToReport(ScenarioOutline scenarioOutline) { - for (Step step : scenarioOutline.getSteps()) { - if (step.getArgument() != null) { - Node argument = step.getArgument(); - if (argument instanceof DocString) { - createDocStringMap((DocString)argument); - } else if (argument instanceof DataTable) { - - } - } - } - } - - private Map createDocStringMap(DocString docString) { - Map docStringMap = new HashMap(); - docStringMap.put("value", docString.getContent()); - return docStringMap; - } - - private void createExamples(Examples examples) { - List rows = new ArrayList<>(); - rows.add(examples.getTableHeader()); - rows.addAll(examples.getTableBody()); - String[][] data = getTable(rows); - String markup = MarkupHelper.createTable(data).getMarkup(); - if (examples.getName() != null && !examples.getName().isEmpty()) { - markup = examples.getName() + markup; - } - markup = scenarioOutlineThreadLocal.get().getModel().getDescription() + markup; - scenarioOutlineThreadLocal.get().getModel().setDescription(markup); - } - - private String[][] getTable(List rows) { - String data[][] = null; - int rowSize = rows.size(); - for (int i = 0; i < rowSize; i++) { - TableRow row = rows.get(i); - List cells = row.getCells(); - int cellSize = cells.size(); - if (data == null) { - data = new String[rowSize][cellSize]; - } - for (int j = 0; j < cellSize; j++) { - data[i][j] = cells.get(j).getValue(); - } - } - return data; - } - - private synchronized void createTestCase(TestCase testCase) { - TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); - if (astNode != null) { - ScenarioDefinition scenarioDefinition = TestSourcesModel.getScenarioDefinition(astNode); - ExtentTest parent = scenarioOutlineThreadLocal.get() != null ? scenarioOutlineThreadLocal.get() : featureTestThreadLocal.get(); - ExtentTest t = parent.createNode(com.aventstack.extentreports.gherkin.model.Scenario.class, scenarioDefinition.getName(), scenarioDefinition.getDescription()); - scenarioThreadLocal.set(t); - } - if (!testCase.getTags().isEmpty()) { - testCase.getTags().forEach(x -> scenarioThreadLocal.get().assignCategory(x.getName())); - } - } - - private synchronized void createTestStep(PickleStepTestStep testStep) { - String stepName = testStep.getStepText(); - TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testStep.getStepLine()); - if (astNode != null) { - Step step = (Step) astNode.node; - try { - String name = stepName == null || stepName.isEmpty() - ? step.getText().replace("<", "<").replace(">", ">") - : stepName; - ExtentTest t = scenarioThreadLocal.get() - .createNode(new GherkinKeyword(step.getKeyword().trim()), step.getKeyword() + name, testStep.getCodeLocation()); - stepTestThreadLocal.set(t); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - } - if (!testStep.getStepArgument().isEmpty()) { - Argument argument = testStep.getStepArgument().get(0); - if (argument instanceof PickleString) { - createDocStringMap((PickleString)argument); - } else if (argument instanceof PickleTable) { - List rows = ((PickleTable) argument).getRows(); - stepTestThreadLocal.get().pass(MarkupHelper.createTable(getPickleTable(rows)).getMarkup()); - } - } - } - - private String[][] getPickleTable(List rows) { - String data[][] = null; - int rowSize = rows.size(); - for (int i = 0; i < rowSize; i++) { - PickleRow row = rows.get(i); - List cells = row.getCells(); - int cellSize = cells.size(); - if (data == null) { - data = new String[rowSize][cellSize]; - } - for (int j = 0; j < cellSize; j++) { - data[i][j] = cells.get(j).getValue(); - } - } - return data; - } - - private Map createDocStringMap(PickleString docString) { - Map docStringMap = new HashMap(); - docStringMap.put("value", docString.getContent()); - return docStringMap; - } +public class ExtentCucumberAdapter implements ConcurrentEventListener { + private static final String SCREENSHOT_DIR_PROPERTY = "screenshot.dir"; + + private static Map featureMap = new ConcurrentHashMap<>(); + private static ThreadLocal featureTestThreadLocal = new InheritableThreadLocal<>(); + private static Map scenarioOutlineMap = new ConcurrentHashMap<>(); + private static ThreadLocal scenarioOutlineThreadLocal = new InheritableThreadLocal<>(); + private static ThreadLocal scenarioThreadLocal = new InheritableThreadLocal<>(); + private static ThreadLocal isHookThreadLocal = new InheritableThreadLocal<>(); + private static ThreadLocal stepTestThreadLocal = new InheritableThreadLocal<>(); + + @SuppressWarnings("serial") + private static final Map MIME_TYPES_EXTENSIONS = new HashMap() { + { + put("image/bmp", "bmp"); + put("image/gif", "gif"); + put("image/jpeg", "jpg"); + put("image/png", "png"); + put("image/svg+xml", "svg"); + put("video/ogg", "ogg"); + } + }; + + private static final AtomicInteger EMBEDDED_INT = new AtomicInteger(0); + + private final TestSourcesModel testSources = new TestSourcesModel(); + + private ThreadLocal currentFeatureFile = new ThreadLocal<>(); + private ThreadLocal currentScenarioOutline = new InheritableThreadLocal<>(); + private ThreadLocal currentExamples = new InheritableThreadLocal<>(); + + private EventHandler testSourceReadHandler = new EventHandler() { + @Override + public void receive(TestSourceRead event) { + handleTestSourceRead(event); + } + }; + private EventHandler caseStartedHandler = new EventHandler() { + @Override + public void receive(TestCaseStarted event) { + handleTestCaseStarted(event); + } + }; + private EventHandler stepStartedHandler = new EventHandler() { + @Override + public void receive(TestStepStarted event) { + handleTestStepStarted(event); + } + }; + private EventHandler stepFinishedHandler = new EventHandler() { + @Override + public void receive(TestStepFinished event) { + handleTestStepFinished(event); + } + }; + private EventHandler embedEventhandler = new EventHandler() { + @Override + public void receive(EmbedEvent event) { + handleEmbed(event); + } + }; + private EventHandler writeEventhandler = new EventHandler() { + @Override + public void receive(WriteEvent event) { + handleWrite(event); + } + }; + private EventHandler runFinishedHandler = new EventHandler() { + @Override + public void receive(TestRunFinished event) { + finishReport(); + } + }; + + public ExtentCucumberAdapter(String arg) { + } + + @Override + public void setEventPublisher(EventPublisher publisher) { + publisher.registerHandlerFor(TestSourceRead.class, testSourceReadHandler); + publisher.registerHandlerFor(TestCaseStarted.class, caseStartedHandler); + publisher.registerHandlerFor(TestStepStarted.class, stepStartedHandler); + publisher.registerHandlerFor(TestStepFinished.class, stepFinishedHandler); + publisher.registerHandlerFor(EmbedEvent.class, embedEventhandler); + publisher.registerHandlerFor(WriteEvent.class, writeEventhandler); + publisher.registerHandlerFor(TestRunFinished.class, runFinishedHandler); + } + + private void handleTestSourceRead(TestSourceRead event) { + testSources.addTestSourceReadEvent(event.uri, event); + } + + private synchronized void handleTestCaseStarted(TestCaseStarted event) { + handleStartOfFeature(event.testCase); + handleScenarioOutline(event.testCase); + createTestCase(event.testCase); + if (testSources.hasBackground(currentFeatureFile.get(), event.testCase.getLine())) { + // background + } + } + + private synchronized void handleTestStepStarted(TestStepStarted event) { + isHookThreadLocal.set(false); + + if (event.testStep instanceof HookTestStep) { + ExtentTest t = scenarioThreadLocal.get().createNode(Asterisk.class, event.testStep.getCodeLocation()); + stepTestThreadLocal.set(t); + isHookThreadLocal.set(true); + } + + if (event.testStep instanceof PickleStepTestStep) { + PickleStepTestStep testStep = (PickleStepTestStep) event.testStep; + createTestStep(testStep); + } + } + + private synchronized void handleTestStepFinished(TestStepFinished event) { + updateResult(event.result); + } + + private synchronized void updateResult(Result result) { + switch (result.getStatus().lowerCaseName()) { + case "failed": + stepTestThreadLocal.get().fail(result.getError()); + break; + case "skipped": + case "pending": + Boolean currentEndingEventSkipped = stepTestThreadLocal.get().getModel().getLogContext() != null + && !stepTestThreadLocal.get().getModel().getLogContext().isEmpty() + ? stepTestThreadLocal.get().getModel().getLogContext().getLast().getStatus() == Status.SKIP + : false; + if (result.getError() != null) { + stepTestThreadLocal.get().skip(result.getError()); + } else if (!currentEndingEventSkipped) { + String details = result.getErrorMessage() == null ? "Step skipped" : result.getErrorMessage(); + stepTestThreadLocal.get().skip(details); + } + break; + case "passed": + if (stepTestThreadLocal.get() != null && stepTestThreadLocal.get().getModel().getLogContext().isEmpty()) { + stepTestThreadLocal.get().pass(""); + } + if (isHookThreadLocal.get() && !stepTestThreadLocal.get().getModel().hasLog() + && !stepTestThreadLocal.get().getModel().getLogContext().getFirst().hasScreenCapture()) { + ExtentService.getInstance().removeTest(stepTestThreadLocal.get()); + } + break; + default: + break; + } + } + + private synchronized void handleEmbed(EmbedEvent event) { + String mimeType = event.mimeType; + String extension = MIME_TYPES_EXTENSIONS.get(mimeType); + if (extension != null) { + StringBuilder fileName = new StringBuilder("embedded").append(EMBEDDED_INT.incrementAndGet()).append(".") + .append(extension); + try { + URL url = toUrl(fileName.toString()); + writeBytesToURL(event.data, url); + try { + File f = new File(url.toURI()); + stepTestThreadLocal.get().info("", + MediaEntityBuilder.createScreenCaptureFromPath(f.getAbsolutePath()).build()); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private static void writeBytesToURL(byte[] buf, URL url) throws IOException { + OutputStream out = createReportFileOutputStream(url); + try { + out.write(buf); + } catch (IOException e) { + throw new IOException("Unable to write to report file item: ", e); + } + } + + private static OutputStream createReportFileOutputStream(URL url) { + try { + return new URLOutputStream(url); + } catch (IOException e) { + throw new CucumberException(e); + } + } + + private URL toUrl(String fileName) { + try { + Object prop = ExtentService.getProperty(SCREENSHOT_DIR_PROPERTY); + String screenshotDir = prop == null ? "test-output/" : String.valueOf(prop); + URL url = Paths.get(screenshotDir, fileName).toUri().toURL(); + return url; + } catch (IOException e) { + throw new CucumberException(e); + } + } + + private void handleWrite(WriteEvent event) { + String text = event.text; + if (text != null && !text.isEmpty()) { + stepTestThreadLocal.get().info(text); + } + } + + private void finishReport() { + ExtentService.getInstance().flush(); + } + + private synchronized void handleStartOfFeature(TestCase testCase) { + if (currentFeatureFile == null || !currentFeatureFile.equals(testCase.getUri())) { + currentFeatureFile.set(testCase.getUri()); + createFeature(testCase); + } + } + + private synchronized void createFeature(TestCase testCase) { + Feature feature = testSources.getFeature(testCase.getUri()); + if (feature != null) { + if (featureMap.containsKey(feature.getName())) { + featureTestThreadLocal.set(featureMap.get(feature.getName())); + return; + } + if (featureTestThreadLocal.get() != null + && featureTestThreadLocal.get().getModel().getName().equals(feature.getName())) { + return; + } + ExtentTest t = ExtentService.getInstance().createTest( + com.aventstack.extentreports.gherkin.model.Feature.class, feature.getName(), + feature.getDescription()); + featureTestThreadLocal.set(t); + featureMap.put(feature.getName(), t); + List tagList = createTagsList(feature.getTags()); + tagList.forEach(featureTestThreadLocal.get()::assignCategory); + } + } + + private List createTagsList(List tags) { + List tagList = new ArrayList<>(); + for (Tag tag : tags) { + tagList.add(tag.getName()); + } + return tagList; + } + + private synchronized void handleScenarioOutline(TestCase testCase) { + TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); + if (TestSourcesModel.isScenarioOutlineScenario(astNode)) { + ScenarioOutline scenarioOutline = (ScenarioOutline) TestSourcesModel.getScenarioDefinition(astNode); + if (currentScenarioOutline.get() == null + || !currentScenarioOutline.get().getName().equals(scenarioOutline.getName())) { + scenarioOutlineThreadLocal.set(null); + createScenarioOutline(scenarioOutline); + currentScenarioOutline.set(scenarioOutline); + addOutlineStepsToReport(scenarioOutline); + } + Examples examples = (Examples) astNode.parent.node; + if (currentExamples.get() == null || !currentExamples.get().equals(examples)) { + currentExamples.set(examples); + createExamples(examples); + } + } else { + scenarioOutlineThreadLocal.set(null); + currentScenarioOutline.set(null); + currentExamples.set(null); + } + } + + private synchronized void createScenarioOutline(ScenarioOutline scenarioOutline) { + if (scenarioOutlineMap.containsKey(scenarioOutline.getName())) { + scenarioOutlineThreadLocal.set(scenarioOutlineMap.get(scenarioOutline.getName())); + return; + } + if (scenarioOutlineThreadLocal.get() == null) { + ExtentTest t = featureTestThreadLocal.get().createNode( + com.aventstack.extentreports.gherkin.model.ScenarioOutline.class, scenarioOutline.getName(), + scenarioOutline.getDescription()); + scenarioOutlineThreadLocal.set(t); + scenarioOutlineMap.put(scenarioOutline.getName(), t); + List tags = createTagsList(scenarioOutline.getTags()); + tags.forEach(scenarioOutlineThreadLocal.get()::assignCategory); + } + } + + private synchronized void addOutlineStepsToReport(ScenarioOutline scenarioOutline) { + for (Step step : scenarioOutline.getSteps()) { + if (step.getArgument() != null) { + Node argument = step.getArgument(); + if (argument instanceof DocString) { + createDocStringMap((DocString) argument); + } else if (argument instanceof DataTable) { + + } + } + } + } + + private Map createDocStringMap(DocString docString) { + Map docStringMap = new HashMap(); + docStringMap.put("value", docString.getContent()); + return docStringMap; + } + + private void createExamples(Examples examples) { + List rows = new ArrayList<>(); + rows.add(examples.getTableHeader()); + rows.addAll(examples.getTableBody()); + String[][] data = getTable(rows); + String markup = MarkupHelper.createTable(data).getMarkup(); + if (examples.getName() != null && !examples.getName().isEmpty()) { + markup = examples.getName() + markup; + } + markup = scenarioOutlineThreadLocal.get().getModel().getDescription() + markup; + scenarioOutlineThreadLocal.get().getModel().setDescription(markup); + } + + private String[][] getTable(List rows) { + String data[][] = null; + int rowSize = rows.size(); + for (int i = 0; i < rowSize; i++) { + TableRow row = rows.get(i); + List cells = row.getCells(); + int cellSize = cells.size(); + if (data == null) { + data = new String[rowSize][cellSize]; + } + for (int j = 0; j < cellSize; j++) { + data[i][j] = cells.get(j).getValue(); + } + } + return data; + } + + private synchronized void createTestCase(TestCase testCase) { + TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); + if (astNode != null) { + ScenarioDefinition scenarioDefinition = TestSourcesModel.getScenarioDefinition(astNode); + ExtentTest parent = scenarioOutlineThreadLocal.get() != null ? scenarioOutlineThreadLocal.get() + : featureTestThreadLocal.get(); + ExtentTest t = parent.createNode(com.aventstack.extentreports.gherkin.model.Scenario.class, + scenarioDefinition.getName(), scenarioDefinition.getDescription()); + scenarioThreadLocal.set(t); + } + if (!testCase.getTags().isEmpty()) { + testCase.getTags().forEach(x -> scenarioThreadLocal.get().assignCategory(x.getName())); + } + } + + private synchronized void createTestStep(PickleStepTestStep testStep) { + String stepName = testStep.getStepText(); + TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testStep.getStepLine()); + if (astNode != null) { + Step step = (Step) astNode.node; + try { + String name = stepName == null || stepName.isEmpty() + ? step.getText().replace("<", "<").replace(">", ">") + : stepName; + ExtentTest t = scenarioThreadLocal.get().createNode(new GherkinKeyword(step.getKeyword().trim()), + step.getKeyword() + name, testStep.getCodeLocation()); + stepTestThreadLocal.set(t); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + if (!testStep.getStepArgument().isEmpty()) { + Argument argument = testStep.getStepArgument().get(0); + if (argument instanceof PickleString) { + createDocStringMap((PickleString) argument); + } else if (argument instanceof PickleTable) { + List rows = ((PickleTable) argument).getRows(); + stepTestThreadLocal.get().pass(MarkupHelper.createTable(getPickleTable(rows)).getMarkup()); + } + } + } + + private String[][] getPickleTable(List rows) { + String data[][] = null; + int rowSize = rows.size(); + for (int i = 0; i < rowSize; i++) { + PickleRow row = rows.get(i); + List cells = row.getCells(); + int cellSize = cells.size(); + if (data == null) { + data = new String[rowSize][cellSize]; + } + for (int j = 0; j < cellSize; j++) { + data[i][j] = cells.get(j).getValue(); + } + } + return data; + } + + private Map createDocStringMap(PickleString docString) { + Map docStringMap = new HashMap(); + docStringMap.put("value", docString.getContent()); + return docStringMap; + } + + public static synchronized void addStepLog(final String message) { + stepTestThreadLocal.get().info(message); + } + + public static synchronized void addStepScreenCaptureFromPath(final String imagePath) throws IOException { + stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath); + } + + public static synchronized void addStepScreenCaptureFromPath(final String imagePath, final String title) + throws IOException { + stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath, title); + } + + } diff --git a/src/main/java/com/aventstack/extentreports/service/ExtentService.java b/src/main/java/com/aventstack/extentreports/service/ExtentService.java index be93436..2144875 100644 --- a/src/main/java/com/aventstack/extentreports/service/ExtentService.java +++ b/src/main/java/com/aventstack/extentreports/service/ExtentService.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.io.Serializable; import java.util.Arrays; +import java.util.List; import java.util.Optional; import java.util.Properties; @@ -41,6 +42,22 @@ private ExtentReports readResolve() { return ExtentReportsLoader.INSTANCE; } + private static ExtentReports getExtentReports() { + return ExtentService.getInstance(); + } + + public static void setSystemInfo(String key, String value) { + getExtentReports().setSystemInfo(key, value); + } + + public static void setTestRunnerOutput(List log) { + getExtentReports().setTestRunnerOutput(log); + } + + public static void setTestRunnerOutput(String outputMessage) { + getExtentReports().setTestRunnerOutput(outputMessage); + } + private static class ExtentReportsLoader { private static final ExtentReports INSTANCE = new ExtentReports(); @@ -254,6 +271,8 @@ private static void attach(ConfigurableReporter r, Properties properties, String r.loadXMLConfig(String.valueOf(configPath)); INSTANCE.attachReporter(((ExtentReporter) r)); } + + } } From 3f041a9611a9f612aa4baee06d0cf0fa20a5fe60 Mon Sep 17 00:00:00 2001 From: far11ven Date: Tue, 3 Dec 2019 19:51:32 +0530 Subject: [PATCH 2/4] moved setSystemInfo,setTestRunnerOutput from ExtentService to ExtentCucumberAdapter --- .../adapter/ExtentCucumberAdapter.java | 12 ++++++++++++ .../extentreports/service/ExtentService.java | 19 +------------------ 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java b/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java index 724f709..f96a615 100644 --- a/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java +++ b/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java @@ -475,5 +475,17 @@ public static synchronized void addStepScreenCaptureFromPath(final String imageP stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath, title); } + public static synchronized void setSystemInfo(String key, String value) { + ExtentService.getInstance().setSystemInfo(key, value); + } + + public static synchronized void setTestRunnerOutput(List log) { + ExtentService.getInstance().setTestRunnerOutput(log); + } + + public static synchronized void setTestRunnerOutput(String outputMessage) { + ExtentService.getInstance().setTestRunnerOutput(outputMessage); + } + } diff --git a/src/main/java/com/aventstack/extentreports/service/ExtentService.java b/src/main/java/com/aventstack/extentreports/service/ExtentService.java index 2144875..ca7ba6a 100644 --- a/src/main/java/com/aventstack/extentreports/service/ExtentService.java +++ b/src/main/java/com/aventstack/extentreports/service/ExtentService.java @@ -4,7 +4,6 @@ import java.io.InputStream; import java.io.Serializable; import java.util.Arrays; -import java.util.List; import java.util.Optional; import java.util.Properties; @@ -41,23 +40,7 @@ public static Object getProperty(String key) { private ExtentReports readResolve() { return ExtentReportsLoader.INSTANCE; } - - private static ExtentReports getExtentReports() { - return ExtentService.getInstance(); - } - - public static void setSystemInfo(String key, String value) { - getExtentReports().setSystemInfo(key, value); - } - - public static void setTestRunnerOutput(List log) { - getExtentReports().setTestRunnerOutput(log); - } - - public static void setTestRunnerOutput(String outputMessage) { - getExtentReports().setTestRunnerOutput(outputMessage); - } - + private static class ExtentReportsLoader { private static final ExtentReports INSTANCE = new ExtentReports(); From 4bb455a91223a5ecfb9f30f66b09948f14237530 Mon Sep 17 00:00:00 2001 From: Kushal Bhalaik Date: Wed, 19 Feb 2020 12:08:47 +0530 Subject: [PATCH 3/4] Merge branch 'master' into master --- .../adapter/ExtentCucumberAdapter.java | 209 ++++++++---------- 1 file changed, 90 insertions(+), 119 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java b/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java index 22f6fc1..c33967b 100644 --- a/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java +++ b/src/main/java/com/aventstack/extentreports/cucumber/adapter/ExtentCucumberAdapter.java @@ -44,13 +44,14 @@ /** * A port of Cucumber-JVM (MIT licensed) HtmlFormatter for Extent Framework - * Original source: - * https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/HTMLFormatter.java + * Original source: https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/HTMLFormatter.java * */ -public class ExtentCucumberAdapter implements ConcurrentEventListener { +public class ExtentCucumberAdapter + implements ConcurrentEventListener { private static final String SCREENSHOT_DIR_PROPERTY = "screenshot.dir"; + private static final String SCREENSHOT_REL_PATH_PROPERTY = "screenshot.rel.path"; private static Map featureMap = new ConcurrentHashMap<>(); private static ThreadLocal featureTestThreadLocal = new InheritableThreadLocal<>(); @@ -60,6 +61,9 @@ public class ExtentCucumberAdapter implements ConcurrentEventListener { private static ThreadLocal isHookThreadLocal = new InheritableThreadLocal<>(); private static ThreadLocal stepTestThreadLocal = new InheritableThreadLocal<>(); + private String screenshotDir; + private String screenshotRelPath; + @SuppressWarnings("serial") private static final Map MIME_TYPES_EXTENSIONS = new HashMap() { { @@ -80,48 +84,13 @@ public class ExtentCucumberAdapter implements ConcurrentEventListener { private ThreadLocal currentScenarioOutline = new InheritableThreadLocal<>(); private ThreadLocal currentExamples = new InheritableThreadLocal<>(); - private synchronized void handleTestStepFinished(TestStepFinished event) { - updateResult(event.result); - } - - private synchronized void updateResult(Result result) { - switch (result.getStatus().lowerCaseName()) { - case "failed": - stepTestThreadLocal.get().fail(result.getError()); - break; - case "skipped": - case "pending": - Boolean currentEndingEventSkipped = stepTestThreadLocal.get().getModel().getLogContext() != null - && !stepTestThreadLocal.get().getModel().getLogContext().isEmpty() - ? stepTestThreadLocal.get().getModel().getLogContext().getLast().getStatus() == Status.SKIP - : false; - if (result.getError() != null) { - stepTestThreadLocal.get().skip(result.getError()); - } else if (!currentEndingEventSkipped) { - String details = result.getErrorMessage() == null ? "Step skipped" : result.getErrorMessage(); - stepTestThreadLocal.get().skip(details); - } - break; - case "passed": - if (stepTestThreadLocal.get()!= null && stepTestThreadLocal.get().getModel().getLogContext().isEmpty()) { - stepTestThreadLocal.get().pass(""); - } - if (isHookThreadLocal.get() && !TestService.testHasLog(stepTestThreadLocal.get().getModel()) && !LogService.logHasScreenCapture(stepTestThreadLocal.get().getModel().getLogContext().getFirst())) { - ExtentService.getInstance().removeTest(stepTestThreadLocal.get()); - } - break; - default: - break; - } - } - private EventHandler testSourceReadHandler = new EventHandler() { @Override public void receive(TestSourceRead event) { handleTestSourceRead(event); } }; - private EventHandler caseStartedHandler = new EventHandler() { + private EventHandler caseStartedHandler= new EventHandler() { @Override public void receive(TestCaseStarted event) { handleTestCaseStarted(event); @@ -159,6 +128,12 @@ public void receive(TestRunFinished event) { }; public ExtentCucumberAdapter(String arg) { + ExtentService.getInstance(); + Object prop = ExtentService.getProperty(SCREENSHOT_DIR_PROPERTY); + screenshotDir = prop == null ? "test-output/" : String.valueOf(prop); + prop = ExtentService.getProperty(SCREENSHOT_REL_PATH_PROPERTY); + screenshotRelPath = prop == null || String.valueOf(prop).isEmpty() ? screenshotDir : String.valueOf(prop); + screenshotRelPath = screenshotRelPath == null ? "" : screenshotRelPath; } @Override @@ -189,8 +164,6 @@ private synchronized void handleTestStepStarted(TestStepStarted event) { isHookThreadLocal.set(false); if (event.testStep instanceof HookTestStep) { - ExtentTest t = scenarioThreadLocal.get().createNode(Asterisk.class, event.testStep.getCodeLocation()); - stepTestThreadLocal.set(t); isHookThreadLocal.set(true); } @@ -206,33 +179,32 @@ private synchronized void handleTestStepFinished(TestStepFinished event) { private synchronized void updateResult(Result result) { switch (result.getStatus().lowerCaseName()) { - case "failed": - stepTestThreadLocal.get().fail(result.getError()); - break; - case "skipped": - case "pending": - Boolean currentEndingEventSkipped = stepTestThreadLocal.get().getModel().getLogContext() != null - && !stepTestThreadLocal.get().getModel().getLogContext().isEmpty() - ? stepTestThreadLocal.get().getModel().getLogContext().getLast().getStatus() == Status.SKIP - : false; - if (result.getError() != null) { - stepTestThreadLocal.get().skip(result.getError()); - } else if (!currentEndingEventSkipped) { - String details = result.getErrorMessage() == null ? "Step skipped" : result.getErrorMessage(); - stepTestThreadLocal.get().skip(details); - } - break; - case "passed": - if (stepTestThreadLocal.get() != null && stepTestThreadLocal.get().getModel().getLogContext().isEmpty()) { - stepTestThreadLocal.get().pass(""); - } - if (isHookThreadLocal.get() && !stepTestThreadLocal.get().getModel().hasLog() - && !stepTestThreadLocal.get().getModel().getLogContext().getFirst().hasScreenCapture()) { - ExtentService.getInstance().removeTest(stepTestThreadLocal.get()); - } - break; - default: - break; + case "failed": + stepTestThreadLocal.get().fail(result.getError()); + break; + case "skipped": + case "pending": + Boolean currentEndingEventSkipped = stepTestThreadLocal.get().getModel().getLogContext() != null + && !stepTestThreadLocal.get().getModel().getLogContext().isEmpty() + ? stepTestThreadLocal.get().getModel().getLogContext().getLast().getStatus() == Status.SKIP + : false; + if (result.getError() != null) { + stepTestThreadLocal.get().skip(result.getError()); + } else if (!currentEndingEventSkipped) { + String details = result.getErrorMessage() == null ? "Step skipped" : result.getErrorMessage(); + stepTestThreadLocal.get().skip(details); + } + break; + case "passed": + if (stepTestThreadLocal.get()!= null && stepTestThreadLocal.get().getModel().getLogContext().isEmpty()) { + stepTestThreadLocal.get().pass(""); + } + if (isHookThreadLocal.get() && !TestService.testHasLog(stepTestThreadLocal.get().getModel()) && !LogService.logHasScreenCapture(stepTestThreadLocal.get().getModel().getLogContext().getFirst())) { + ExtentService.getInstance().removeTest(stepTestThreadLocal.get()); + } + break; + default: + break; } } @@ -240,15 +212,18 @@ private synchronized void handleEmbed(EmbedEvent event) { String mimeType = event.mimeType; String extension = MIME_TYPES_EXTENSIONS.get(mimeType); if (extension != null) { - StringBuilder fileName = new StringBuilder("embedded").append(EMBEDDED_INT.incrementAndGet()).append(".") - .append(extension); + StringBuilder fileName = new StringBuilder("embedded").append(EMBEDDED_INT.incrementAndGet()).append(".").append(extension); try { URL url = toUrl(fileName.toString()); writeBytesToURL(event.data, url); try { File f = new File(url.toURI()); - stepTestThreadLocal.get().info("", - MediaEntityBuilder.createScreenCaptureFromPath(f.getAbsolutePath()).build()); + if (stepTestThreadLocal.get() == null) { + ExtentTest t = scenarioThreadLocal.get() + .createNode(Asterisk.class, "Embed"); + stepTestThreadLocal.set(t); + } + stepTestThreadLocal.get().info("", MediaEntityBuilder.createScreenCaptureFromPath(screenshotRelPath + f.getName()).build()); } catch (URISyntaxException e) { e.printStackTrace(); } @@ -277,8 +252,6 @@ private static OutputStream createReportFileOutputStream(URL url) { private URL toUrl(String fileName) { try { - Object prop = ExtentService.getProperty(SCREENSHOT_DIR_PROPERTY); - String screenshotDir = prop == null ? "test-output/" : String.valueOf(prop); URL url = Paths.get(screenshotDir, fileName).toUri().toURL(); return url; } catch (IOException e) { @@ -311,13 +284,11 @@ private synchronized void createFeature(TestCase testCase) { featureTestThreadLocal.set(featureMap.get(feature.getName())); return; } - if (featureTestThreadLocal.get() != null - && featureTestThreadLocal.get().getModel().getName().equals(feature.getName())) { + if (featureTestThreadLocal.get() != null && featureTestThreadLocal.get().getModel().getName().equals(feature.getName())) { return; } - ExtentTest t = ExtentService.getInstance().createTest( - com.aventstack.extentreports.gherkin.model.Feature.class, feature.getName(), - feature.getDescription()); + ExtentTest t = ExtentService.getInstance() + .createTest(com.aventstack.extentreports.gherkin.model.Feature.class, feature.getName(), feature.getDescription()); featureTestThreadLocal.set(t); featureMap.put(feature.getName(), t); List tagList = createTagsList(feature.getTags()); @@ -336,15 +307,14 @@ private List createTagsList(List tags) { private synchronized void handleScenarioOutline(TestCase testCase) { TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); if (TestSourcesModel.isScenarioOutlineScenario(astNode)) { - ScenarioOutline scenarioOutline = (ScenarioOutline) TestSourcesModel.getScenarioDefinition(astNode); - if (currentScenarioOutline.get() == null - || !currentScenarioOutline.get().getName().equals(scenarioOutline.getName())) { + ScenarioOutline scenarioOutline = (ScenarioOutline)TestSourcesModel.getScenarioDefinition(astNode); + if (currentScenarioOutline.get() == null || !currentScenarioOutline.get().getName().equals(scenarioOutline.getName())) { scenarioOutlineThreadLocal.set(null); createScenarioOutline(scenarioOutline); currentScenarioOutline.set(scenarioOutline); addOutlineStepsToReport(scenarioOutline); } - Examples examples = (Examples) astNode.parent.node; + Examples examples = (Examples)astNode.parent.node; if (currentExamples.get() == null || !currentExamples.get().equals(examples)) { currentExamples.set(examples); createExamples(examples); @@ -362,9 +332,8 @@ private synchronized void createScenarioOutline(ScenarioOutline scenarioOutline) return; } if (scenarioOutlineThreadLocal.get() == null) { - ExtentTest t = featureTestThreadLocal.get().createNode( - com.aventstack.extentreports.gherkin.model.ScenarioOutline.class, scenarioOutline.getName(), - scenarioOutline.getDescription()); + ExtentTest t = featureTestThreadLocal.get() + .createNode(com.aventstack.extentreports.gherkin.model.ScenarioOutline.class, scenarioOutline.getName(), scenarioOutline.getDescription()); scenarioOutlineThreadLocal.set(t); scenarioOutlineMap.put(scenarioOutline.getName(), t); List tags = createTagsList(scenarioOutline.getTags()); @@ -377,7 +346,7 @@ private synchronized void addOutlineStepsToReport(ScenarioOutline scenarioOutlin if (step.getArgument() != null) { Node argument = step.getArgument(); if (argument instanceof DocString) { - createDocStringMap((DocString) argument); + createDocStringMap((DocString)argument); } else if (argument instanceof DataTable) { } @@ -425,10 +394,8 @@ private synchronized void createTestCase(TestCase testCase) { TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); if (astNode != null) { ScenarioDefinition scenarioDefinition = TestSourcesModel.getScenarioDefinition(astNode); - ExtentTest parent = scenarioOutlineThreadLocal.get() != null ? scenarioOutlineThreadLocal.get() - : featureTestThreadLocal.get(); - ExtentTest t = parent.createNode(com.aventstack.extentreports.gherkin.model.Scenario.class, - scenarioDefinition.getName(), scenarioDefinition.getDescription()); + ExtentTest parent = scenarioOutlineThreadLocal.get() != null ? scenarioOutlineThreadLocal.get() : featureTestThreadLocal.get(); + ExtentTest t = parent.createNode(com.aventstack.extentreports.gherkin.model.Scenario.class, scenarioDefinition.getName(), scenarioDefinition.getDescription()); scenarioThreadLocal.set(t); } if (!testCase.getTags().isEmpty()) { @@ -445,8 +412,8 @@ private synchronized void createTestStep(PickleStepTestStep testStep) { String name = stepName == null || stepName.isEmpty() ? step.getText().replace("<", "<").replace(">", ">") : stepName; - ExtentTest t = scenarioThreadLocal.get().createNode(new GherkinKeyword(step.getKeyword().trim()), - step.getKeyword() + name, testStep.getCodeLocation()); + ExtentTest t = scenarioThreadLocal.get() + .createNode(new GherkinKeyword(step.getKeyword().trim()), step.getKeyword() + name, testStep.getCodeLocation()); stepTestThreadLocal.set(t); } catch (ClassNotFoundException e) { e.printStackTrace(); @@ -455,7 +422,7 @@ private synchronized void createTestStep(PickleStepTestStep testStep) { if (!testStep.getStepArgument().isEmpty()) { Argument argument = testStep.getStepArgument().get(0); if (argument instanceof PickleString) { - createDocStringMap((PickleString) argument); + createDocStringMap((PickleString)argument); } else if (argument instanceof PickleTable) { List rows = ((PickleTable) argument).getRows(); stepTestThreadLocal.get().pass(MarkupHelper.createTable(getPickleTable(rows)).getMarkup()); @@ -485,30 +452,34 @@ private Map createDocStringMap(PickleString docString) { docStringMap.put("value", docString.getContent()); return docStringMap; } - + public static synchronized void setSystemInfo(String key, String value) { ExtentService.getInstance().setSystemInfo(key, value); - } - - public static synchronized void setTestRunnerOutput(List log) { - ExtentService.getInstance().setTestRunnerOutput(log); - } - - public static synchronized void setTestRunnerOutput(String outputMessage) { - ExtentService.getInstance().setTestRunnerOutput(outputMessage); - } - - // the below additions are from PR #33 - // https://github.com/extent-framework/extentreports-cucumber4-adapter/pull/33 - public static synchronized void addTestStepLog(String message) { - stepTestThreadLocal.get().info(message); - } - - public static synchronized void addTestStepScreenCaptureFromPath(String imagePath) throws IOException { - stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath); - } - - public static synchronized void addTestStepScreenCaptureFromPath(String imagePath, String title) throws IOException { - stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath, title); - } -} + } + + public static synchronized void setTestRunnerOutput(List log) { + ExtentService.getInstance().setTestRunnerOutput(log); + } + + public static synchronized void setTestRunnerOutput(String outputMessage) { + ExtentService.getInstance().setTestRunnerOutput(outputMessage); + } + + // the below additions are from PR #33 + // https://github.com/extent-framework/extentreports-cucumber4-adapter/pull/33 + public static synchronized void addTestStepLog(String message) { + stepTestThreadLocal.get().info(message); + } + + public static synchronized void addTestStepScreenCaptureFromPath(String imagePath) throws IOException { + stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath); + } + + public static synchronized void addTestStepScreenCaptureFromPath(String imagePath, String title) throws IOException { + stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath, title); + } + + public static ExtentTest getCurrentStep() { + return stepTestThreadLocal.get(); + } +} \ No newline at end of file From bce22c200beab7cbe9824b803e41d1566095e78e Mon Sep 17 00:00:00 2001 From: Kushal Bhalaik Date: Wed, 19 Feb 2020 12:20:38 +0530 Subject: [PATCH 4/4] removed unintended file commit --- .../extentreports/cucumber/adapter/abc | 473 ------------------ 1 file changed, 473 deletions(-) delete mode 100644 src/main/java/com/aventstack/extentreports/cucumber/adapter/abc diff --git a/src/main/java/com/aventstack/extentreports/cucumber/adapter/abc b/src/main/java/com/aventstack/extentreports/cucumber/adapter/abc deleted file mode 100644 index f9e4292..0000000 --- a/src/main/java/com/aventstack/extentreports/cucumber/adapter/abc +++ /dev/null @@ -1,473 +0,0 @@ -package com.aventstack.extentreports.cucumber.adapter; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - -import com.aventstack.extentreports.ExtentTest; -import com.aventstack.extentreports.GherkinKeyword; -import com.aventstack.extentreports.MediaEntityBuilder; -import com.aventstack.extentreports.Status; -import com.aventstack.extentreports.gherkin.model.Asterisk; -import com.aventstack.extentreports.markuputils.MarkupHelper; -import com.aventstack.extentreports.model.service.LogService; -import com.aventstack.extentreports.model.service.TestService; -import com.aventstack.extentreports.service.ExtentService; - -import cucumber.api.HookTestStep; -import cucumber.api.PickleStepTestStep; -import cucumber.api.Result; -import cucumber.api.TestCase; -import cucumber.api.event.*; -import cucumber.runtime.CucumberException; -import gherkin.ast.DataTable; -import gherkin.ast.DocString; -import gherkin.ast.Examples; -import gherkin.ast.Feature; -import gherkin.ast.Node; -import gherkin.ast.ScenarioDefinition; -import gherkin.ast.ScenarioOutline; -import gherkin.ast.Step; -import gherkin.ast.TableCell; -import gherkin.ast.TableRow; -import gherkin.ast.Tag; -import gherkin.pickles.*; - -/** - * A port of Cucumber-JVM (MIT licensed) HtmlFormatter for Extent Framework - * Original source: https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/HTMLFormatter.java - * - */ -public class ExtentCucumberAdapter - implements ConcurrentEventListener { - - private static final String SCREENSHOT_DIR_PROPERTY = "screenshot.dir"; - private static final String SCREENSHOT_REL_PATH_PROPERTY = "screenshot.rel.path"; - - private static Map featureMap = new ConcurrentHashMap<>(); - private static ThreadLocal featureTestThreadLocal = new InheritableThreadLocal<>(); - private static Map scenarioOutlineMap = new ConcurrentHashMap<>(); - private static ThreadLocal scenarioOutlineThreadLocal = new InheritableThreadLocal<>(); - private static ThreadLocal scenarioThreadLocal = new InheritableThreadLocal<>(); - private static ThreadLocal isHookThreadLocal = new InheritableThreadLocal<>(); - private static ThreadLocal stepTestThreadLocal = new InheritableThreadLocal<>(); - - private String screenshotDir; - private String screenshotRelPath; - - @SuppressWarnings("serial") - private static final Map MIME_TYPES_EXTENSIONS = new HashMap() { - { - put("image/bmp", "bmp"); - put("image/gif", "gif"); - put("image/jpeg", "jpg"); - put("image/png", "png"); - put("image/svg+xml", "svg"); - put("video/ogg", "ogg"); - } - }; - - private static final AtomicInteger EMBEDDED_INT = new AtomicInteger(0); - - private final TestSourcesModel testSources = new TestSourcesModel(); - - private ThreadLocal currentFeatureFile = new ThreadLocal<>(); - private ThreadLocal currentScenarioOutline = new InheritableThreadLocal<>(); - private ThreadLocal currentExamples = new InheritableThreadLocal<>(); - - private EventHandler testSourceReadHandler = new EventHandler() { - @Override - public void receive(TestSourceRead event) { - handleTestSourceRead(event); - } - }; - private EventHandler caseStartedHandler= new EventHandler() { - @Override - public void receive(TestCaseStarted event) { - handleTestCaseStarted(event); - } - }; - private EventHandler stepStartedHandler = new EventHandler() { - @Override - public void receive(TestStepStarted event) { - handleTestStepStarted(event); - } - }; - private EventHandler stepFinishedHandler = new EventHandler() { - @Override - public void receive(TestStepFinished event) { - handleTestStepFinished(event); - } - }; - private EventHandler embedEventhandler = new EventHandler() { - @Override - public void receive(EmbedEvent event) { - handleEmbed(event); - } - }; - private EventHandler writeEventhandler = new EventHandler() { - @Override - public void receive(WriteEvent event) { - handleWrite(event); - } - }; - private EventHandler runFinishedHandler = new EventHandler() { - @Override - public void receive(TestRunFinished event) { - finishReport(); - } - }; - - public ExtentCucumberAdapter(String arg) { - ExtentService.getInstance(); - Object prop = ExtentService.getProperty(SCREENSHOT_DIR_PROPERTY); - screenshotDir = prop == null ? "test-output/" : String.valueOf(prop); - prop = ExtentService.getProperty(SCREENSHOT_REL_PATH_PROPERTY); - screenshotRelPath = prop == null || String.valueOf(prop).isEmpty() ? screenshotDir : String.valueOf(prop); - screenshotRelPath = screenshotRelPath == null ? "" : screenshotRelPath; - } - - @Override - public void setEventPublisher(EventPublisher publisher) { - publisher.registerHandlerFor(TestSourceRead.class, testSourceReadHandler); - publisher.registerHandlerFor(TestCaseStarted.class, caseStartedHandler); - publisher.registerHandlerFor(TestStepStarted.class, stepStartedHandler); - publisher.registerHandlerFor(TestStepFinished.class, stepFinishedHandler); - publisher.registerHandlerFor(EmbedEvent.class, embedEventhandler); - publisher.registerHandlerFor(WriteEvent.class, writeEventhandler); - publisher.registerHandlerFor(TestRunFinished.class, runFinishedHandler); - } - - private void handleTestSourceRead(TestSourceRead event) { - testSources.addTestSourceReadEvent(event.uri, event); - } - - private synchronized void handleTestCaseStarted(TestCaseStarted event) { - handleStartOfFeature(event.testCase); - handleScenarioOutline(event.testCase); - createTestCase(event.testCase); - if (testSources.hasBackground(currentFeatureFile.get(), event.testCase.getLine())) { - // background - } - } - - private synchronized void handleTestStepStarted(TestStepStarted event) { - isHookThreadLocal.set(false); - - if (event.testStep instanceof HookTestStep) { - isHookThreadLocal.set(true); - } - - if (event.testStep instanceof PickleStepTestStep) { - PickleStepTestStep testStep = (PickleStepTestStep) event.testStep; - createTestStep(testStep); - } - } - - private synchronized void handleTestStepFinished(TestStepFinished event) { - updateResult(event.result); - } - - private synchronized void updateResult(Result result) { - switch (result.getStatus().lowerCaseName()) { - case "failed": - stepTestThreadLocal.get().fail(result.getError()); - break; - case "skipped": - case "pending": - Boolean currentEndingEventSkipped = stepTestThreadLocal.get().getModel().getLogContext() != null - && !stepTestThreadLocal.get().getModel().getLogContext().isEmpty() - ? stepTestThreadLocal.get().getModel().getLogContext().getLast().getStatus() == Status.SKIP - : false; - if (result.getError() != null) { - stepTestThreadLocal.get().skip(result.getError()); - } else if (!currentEndingEventSkipped) { - String details = result.getErrorMessage() == null ? "Step skipped" : result.getErrorMessage(); - stepTestThreadLocal.get().skip(details); - } - break; - case "passed": - if (stepTestThreadLocal.get()!= null && stepTestThreadLocal.get().getModel().getLogContext().isEmpty()) { - stepTestThreadLocal.get().pass(""); - } - if (isHookThreadLocal.get() && !TestService.testHasLog(stepTestThreadLocal.get().getModel()) && !LogService.logHasScreenCapture(stepTestThreadLocal.get().getModel().getLogContext().getFirst())) { - ExtentService.getInstance().removeTest(stepTestThreadLocal.get()); - } - break; - default: - break; - } - } - - private synchronized void handleEmbed(EmbedEvent event) { - String mimeType = event.mimeType; - String extension = MIME_TYPES_EXTENSIONS.get(mimeType); - if (extension != null) { - StringBuilder fileName = new StringBuilder("embedded").append(EMBEDDED_INT.incrementAndGet()).append(".").append(extension); - try { - URL url = toUrl(fileName.toString()); - writeBytesToURL(event.data, url); - try { - File f = new File(url.toURI()); - if (stepTestThreadLocal.get() == null) { - ExtentTest t = scenarioThreadLocal.get() - .createNode(Asterisk.class, "Embed"); - stepTestThreadLocal.set(t); - } - stepTestThreadLocal.get().info("", MediaEntityBuilder.createScreenCaptureFromPath(screenshotRelPath + f.getName()).build()); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static void writeBytesToURL(byte[] buf, URL url) throws IOException { - OutputStream out = createReportFileOutputStream(url); - try { - out.write(buf); - } catch (IOException e) { - throw new IOException("Unable to write to report file item: ", e); - } - } - - private static OutputStream createReportFileOutputStream(URL url) { - try { - return new URLOutputStream(url); - } catch (IOException e) { - throw new CucumberException(e); - } - } - - private URL toUrl(String fileName) { - try { - URL url = Paths.get(screenshotDir, fileName).toUri().toURL(); - return url; - } catch (IOException e) { - throw new CucumberException(e); - } - } - - private void handleWrite(WriteEvent event) { - String text = event.text; - if (text != null && !text.isEmpty()) { - stepTestThreadLocal.get().info(text); - } - } - - private void finishReport() { - ExtentService.getInstance().flush(); - } - - private synchronized void handleStartOfFeature(TestCase testCase) { - if (currentFeatureFile == null || !currentFeatureFile.equals(testCase.getUri())) { - currentFeatureFile.set(testCase.getUri()); - createFeature(testCase); - } - } - - private synchronized void createFeature(TestCase testCase) { - Feature feature = testSources.getFeature(testCase.getUri()); - if (feature != null) { - if (featureMap.containsKey(feature.getName())) { - featureTestThreadLocal.set(featureMap.get(feature.getName())); - return; - } - if (featureTestThreadLocal.get() != null && featureTestThreadLocal.get().getModel().getName().equals(feature.getName())) { - return; - } - ExtentTest t = ExtentService.getInstance() - .createTest(com.aventstack.extentreports.gherkin.model.Feature.class, feature.getName(), feature.getDescription()); - featureTestThreadLocal.set(t); - featureMap.put(feature.getName(), t); - List tagList = createTagsList(feature.getTags()); - tagList.forEach(featureTestThreadLocal.get()::assignCategory); - } - } - - private List createTagsList(List tags) { - List tagList = new ArrayList<>(); - for (Tag tag : tags) { - tagList.add(tag.getName()); - } - return tagList; - } - - private synchronized void handleScenarioOutline(TestCase testCase) { - TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); - if (TestSourcesModel.isScenarioOutlineScenario(astNode)) { - ScenarioOutline scenarioOutline = (ScenarioOutline)TestSourcesModel.getScenarioDefinition(astNode); - if (currentScenarioOutline.get() == null || !currentScenarioOutline.get().getName().equals(scenarioOutline.getName())) { - scenarioOutlineThreadLocal.set(null); - createScenarioOutline(scenarioOutline); - currentScenarioOutline.set(scenarioOutline); - addOutlineStepsToReport(scenarioOutline); - } - Examples examples = (Examples)astNode.parent.node; - if (currentExamples.get() == null || !currentExamples.get().equals(examples)) { - currentExamples.set(examples); - createExamples(examples); - } - } else { - scenarioOutlineThreadLocal.set(null); - currentScenarioOutline.set(null); - currentExamples.set(null); - } - } - - private synchronized void createScenarioOutline(ScenarioOutline scenarioOutline) { - if (scenarioOutlineMap.containsKey(scenarioOutline.getName())) { - scenarioOutlineThreadLocal.set(scenarioOutlineMap.get(scenarioOutline.getName())); - return; - } - if (scenarioOutlineThreadLocal.get() == null) { - ExtentTest t = featureTestThreadLocal.get() - .createNode(com.aventstack.extentreports.gherkin.model.ScenarioOutline.class, scenarioOutline.getName(), scenarioOutline.getDescription()); - scenarioOutlineThreadLocal.set(t); - scenarioOutlineMap.put(scenarioOutline.getName(), t); - List tags = createTagsList(scenarioOutline.getTags()); - tags.forEach(scenarioOutlineThreadLocal.get()::assignCategory); - } - } - - private synchronized void addOutlineStepsToReport(ScenarioOutline scenarioOutline) { - for (Step step : scenarioOutline.getSteps()) { - if (step.getArgument() != null) { - Node argument = step.getArgument(); - if (argument instanceof DocString) { - createDocStringMap((DocString)argument); - } else if (argument instanceof DataTable) { - - } - } - } - } - - private Map createDocStringMap(DocString docString) { - Map docStringMap = new HashMap(); - docStringMap.put("value", docString.getContent()); - return docStringMap; - } - - private void createExamples(Examples examples) { - List rows = new ArrayList<>(); - rows.add(examples.getTableHeader()); - rows.addAll(examples.getTableBody()); - String[][] data = getTable(rows); - String markup = MarkupHelper.createTable(data).getMarkup(); - if (examples.getName() != null && !examples.getName().isEmpty()) { - markup = examples.getName() + markup; - } - markup = scenarioOutlineThreadLocal.get().getModel().getDescription() + markup; - scenarioOutlineThreadLocal.get().getModel().setDescription(markup); - } - - private String[][] getTable(List rows) { - String data[][] = null; - int rowSize = rows.size(); - for (int i = 0; i < rowSize; i++) { - TableRow row = rows.get(i); - List cells = row.getCells(); - int cellSize = cells.size(); - if (data == null) { - data = new String[rowSize][cellSize]; - } - for (int j = 0; j < cellSize; j++) { - data[i][j] = cells.get(j).getValue(); - } - } - return data; - } - - private synchronized void createTestCase(TestCase testCase) { - TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testCase.getLine()); - if (astNode != null) { - ScenarioDefinition scenarioDefinition = TestSourcesModel.getScenarioDefinition(astNode); - ExtentTest parent = scenarioOutlineThreadLocal.get() != null ? scenarioOutlineThreadLocal.get() : featureTestThreadLocal.get(); - ExtentTest t = parent.createNode(com.aventstack.extentreports.gherkin.model.Scenario.class, scenarioDefinition.getName(), scenarioDefinition.getDescription()); - scenarioThreadLocal.set(t); - } - if (!testCase.getTags().isEmpty()) { - testCase.getTags().forEach(x -> scenarioThreadLocal.get().assignCategory(x.getName())); - } - } - - private synchronized void createTestStep(PickleStepTestStep testStep) { - String stepName = testStep.getStepText(); - TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile.get(), testStep.getStepLine()); - if (astNode != null) { - Step step = (Step) astNode.node; - try { - String name = stepName == null || stepName.isEmpty() - ? step.getText().replace("<", "<").replace(">", ">") - : stepName; - ExtentTest t = scenarioThreadLocal.get() - .createNode(new GherkinKeyword(step.getKeyword().trim()), step.getKeyword() + name, testStep.getCodeLocation()); - stepTestThreadLocal.set(t); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - } - if (!testStep.getStepArgument().isEmpty()) { - Argument argument = testStep.getStepArgument().get(0); - if (argument instanceof PickleString) { - createDocStringMap((PickleString)argument); - } else if (argument instanceof PickleTable) { - List rows = ((PickleTable) argument).getRows(); - stepTestThreadLocal.get().pass(MarkupHelper.createTable(getPickleTable(rows)).getMarkup()); - } - } - } - - private String[][] getPickleTable(List rows) { - String data[][] = null; - int rowSize = rows.size(); - for (int i = 0; i < rowSize; i++) { - PickleRow row = rows.get(i); - List cells = row.getCells(); - int cellSize = cells.size(); - if (data == null) { - data = new String[rowSize][cellSize]; - } - for (int j = 0; j < cellSize; j++) { - data[i][j] = cells.get(j).getValue(); - } - } - return data; - } - - private Map createDocStringMap(PickleString docString) { - Map docStringMap = new HashMap(); - docStringMap.put("value", docString.getContent()); - return docStringMap; - } - - // the below additions are from PR #33 - // https://github.com/extent-framework/extentreports-cucumber4-adapter/pull/33 - public static synchronized void addTestStepLog(String message) { - stepTestThreadLocal.get().info(message); - } - - public static synchronized void addTestStepScreenCaptureFromPath(String imagePath) throws IOException { - stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath); - } - - public static synchronized void addTestStepScreenCaptureFromPath(String imagePath, String title) throws IOException { - stepTestThreadLocal.get().addScreenCaptureFromPath(imagePath, title); - } - - public static ExtentTest getCurrentStep() { - return stepTestThreadLocal.get(); - } -} \ No newline at end of file