All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sitture.ExtentFormatter Maven / Gradle / Ivy

package com.sitture;

import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.GherkinKeyword;
import com.aventstack.extentreports.gherkin.model.Scenario;
import com.aventstack.extentreports.markuputils.MarkupHelper;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import cucumber.api.Result;
import cucumber.api.TestCase;
import cucumber.api.TestStep;
import cucumber.api.event.EventHandler;
import cucumber.api.event.EventPublisher;
import cucumber.api.event.TestCaseStarted;
import cucumber.api.event.TestRunFinished;
import cucumber.api.event.TestSourceRead;
import cucumber.api.event.TestStepFinished;
import cucumber.api.event.TestStepStarted;
import cucumber.api.formatter.Formatter;
import gherkin.ast.Background;
import gherkin.ast.Examples;
import gherkin.ast.Feature;
import gherkin.ast.ScenarioDefinition;
import gherkin.ast.ScenarioOutline;
import gherkin.ast.TableCell;
import gherkin.ast.TableRow;
import gherkin.ast.Tag;

import java.io.File;
import java.util.List;

/**
 * Cucumber formatter for formatting Extent Reports.
 * See Extent reports for more information.
 */
public class ExtentFormatter implements Formatter {

    private static final String DEFAULT_REPORT_DIRECTORY = "extent-report";
    private static final String DEFAULT_FILE_NAME = "index.html";

    private static ExtentReports extentReport;
    private static ExtentHtmlReporter htmlReport;

    private static ThreadLocal featureTestThreadLocal = new InheritableThreadLocal<>();
    private static ThreadLocal backgroundThreadLocal = new InheritableThreadLocal<>();
    private static ThreadLocal scenarioOutlineThreadLocal = new InheritableThreadLocal<>();
    private static ThreadLocal scenarioThreadLocal = new InheritableThreadLocal<>();
    private static ThreadLocal stepTestThreadLocal = new InheritableThreadLocal<>();

    private String currentFeatureFile;
    private boolean scenarioOutlineTest;
    private final TestSourcesModel testSources = new TestSourcesModel();

    private EventHandler testSourceReadHandler = new EventHandler() {
        @Override
        public void receive(TestSourceRead event) {
            testSources.addTestSourceReadEvent(event.uri, 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 runFinishedHandler = new EventHandler() {
        @Override
        public void receive(TestRunFinished event) {
            handleTestRunFinished();
        }
    };

    public ExtentFormatter(File report) {
        scenarioOutlineTest = false;
        if (htmlReport == null) {
            htmlReport = new ExtentHtmlReporter(getReportsDir(report));
        }

        if (extentReport == null) {
            extentReport = new ExtentReports();
            extentReport.attachReporter(getHtmlReport());
        }
    }

    @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(TestRunFinished.class, runFinishedHandler);
    }

    private void handleTestCaseStarted(TestCaseStarted event) {
        scenarioOutlineTest = false;

        handleStartOfFeature(event.testCase);
        handleScenarioOutline(event.testCase);
        handleScenario(event.testCase);
        handleBackground(event.testCase);
    }

    private void handleTestStepStarted(TestStepStarted event) {
        TestStep testStep = event.testStep;
        if (TestSourcesModel.isBackgroundStep(testSources.getAstNode(currentFeatureFile, testStep.getStepLine()))) {
            String keywordFromSource = testSources.getKeywordFromSource(currentFeatureFile, testStep.getStepLine());
            try {
                ExtentTest node = backgroundThreadLocal.get().createNode(new GherkinKeyword(keywordFromSource), testStep.getStepText());
                stepTestThreadLocal.set(node);
            } catch (ClassNotFoundException e) {
                System.out.println("Something went wrong while trying to parse the Gherkin keyword for this step: " + e);
            }
        }
        if (!scenarioOutlineTest) {
            ExtentTest scenarioTest = scenarioThreadLocal.get();
            if (scenarioTest != null) {
                String keywordFromSource = testSources.getKeywordFromSource(currentFeatureFile, testStep.getStepLine());
                ExtentTest testNode;
                try {
                    if (!TestSourcesModel.isBackgroundStep(testSources.getAstNode(currentFeatureFile, testStep.getStepLine()))) {
                        testNode = scenarioTest.createNode(new GherkinKeyword(keywordFromSource), testStep.getStepText());
                        stepTestThreadLocal.set(testNode);
                    }
                } catch (ClassNotFoundException e) {
                    System.out.println("Something went wrong while trying to parse the Gherkin keyword for this step: " + e);
                }
            }
        }
    }

    private void handleTestStepFinished(TestStepFinished event) {
        if (!scenarioOutlineTest) {
            if (Result.Type.PASSED.equals(event.result.getStatus())) {
                getStepTestThreadLocal().get().pass(Result.Type.PASSED.name());
            } else if (Result.Type.FAILED.equals(event.result.getStatus())) {
                getStepTestThreadLocal().get().fail(event.result.getError());
            } else if (Result.Type.SKIPPED.equals(event.result.getStatus())) {
                getStepTestThreadLocal().get().skip(Result.Type.SKIPPED.name());
            } else if (Result.Type.UNDEFINED.equals(event.result.getStatus())) {
                getStepTestThreadLocal().get().warning(Result.Type.UNDEFINED.name());
            }
        }
    }

    private void handleStartOfFeature(TestCase testCase) {
        if (currentFeatureFile == null || !currentFeatureFile.equals(testCase.getUri())) {
            currentFeatureFile = testCase.getUri();

            Feature cucumberFeature = getFeature(testCase);
            ExtentTest feature = getExtentReport().createTest(cucumberFeature.getName(), cucumberFeature.getDescription());

            for (Tag tag : cucumberFeature.getTags()) {
                feature.assignCategory(tag.getName());
            }
            featureTestThreadLocal.set(feature);
        }
    }

    private void handleBackground(TestCase testCase) {
        Background background = TestSourcesModel.getBackgoundForTestCase(testSources.getAstNode(currentFeatureFile, testCase.getLine()));
        if (background != null) {
            if (scenarioOutlineTest) {
                ExtentTest backgroundNode = scenarioOutlineThreadLocal.get()
                        .createNode(com.aventstack.extentreports.gherkin.model.Background.class, background.getName());
                backgroundThreadLocal.set(backgroundNode);
            } else {
                ExtentTest backgroundNode = scenarioThreadLocal.get()
                        .createNode(com.aventstack.extentreports.gherkin.model.Background.class, background.getName());
                backgroundThreadLocal.set(backgroundNode);
            }
        }
    }

    private void handleScenarioOutline(TestCase testCase) {
        if (TestSourcesModel.isScenarioOutlineScenario(testSources.getAstNode(currentFeatureFile, testCase.getLine()))) {
            ScenarioOutline scenarioOutline = (ScenarioOutline) TestSourcesModel.getScenarioDefinition(testSources.getAstNode(currentFeatureFile, testCase.getLine()));
            scenarioOutlineTest = true;

            ExtentTest node = featureTestThreadLocal.get()
                    .createNode(com.aventstack.extentreports.gherkin.model.ScenarioOutline.class, scenarioOutline.getName(), scenarioOutline.getDescription());
            scenarioOutlineThreadLocal.set(node);

            List examples = scenarioOutline.getExamples();
            for (Examples example : examples) {
                examples(example);
            }

            for (Tag tag : scenarioOutline.getTags()) {
                node.assignCategory(tag.getName());
            }
        }
    }

    private void handleScenario(TestCase testCase) {
        ExtentTest scenario;
        if (scenarioOutlineTest) {
            scenarioOutlineTest = false;
            ScenarioDefinition scenarioDefinition = TestSourcesModel.getScenarioDefinition(testSources.getAstNode(currentFeatureFile, testCase.getLine()));
            scenario = scenarioOutlineThreadLocal.get().createNode(Scenario.class, scenarioDefinition.getName());
        } else {
            gherkin.ast.Scenario scenarioDefinition = (gherkin.ast.Scenario) TestSourcesModel.getScenarioDefinition(testSources.getAstNode(currentFeatureFile, testCase.getLine()));
            scenario = featureTestThreadLocal.get().createNode(Scenario.class, scenarioDefinition.getName(), scenarioDefinition.getDescription());
            for (Tag tag : scenarioDefinition.getTags()) {
                scenario.assignCategory(tag.getName());
            }
        }
        scenarioThreadLocal.set(scenario);
    }

    private void handleTestRunFinished() {
        getExtentReport().flush();
    }

    private Feature getFeature(TestCase testCase) {
        return testSources.getFeature(testCase.getUri());
    }

    private static File getReportsDir(File file) {
        File reportsDir = new File(
                DEFAULT_REPORT_DIRECTORY + File.separator + System.currentTimeMillis() + File.separator + DEFAULT_FILE_NAME);
        if (file != null) {
            reportsDir = file;
        }
        if (!reportsDir.exists()) {
            reportsDir.getParentFile().mkdirs();
        }
        return reportsDir;
    }

    private void examples(Examples examples) {
        ExtentTest test = scenarioOutlineThreadLocal.get();

        String[][] data = null;
        List rows = examples.getTableBody();
        int rowSize = rows.size();
        for (int i = 0; i < rowSize; i++) {
            TableRow examplesTableRow = rows.get(i);
            List cells = examplesTableRow.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();
            }
        }
        test.info(MarkupHelper.createTable(data));
    }

    public static ExtentReports getExtentReport() {
        return extentReport;
    }

    public static ExtentHtmlReporter getHtmlReport() {
        return htmlReport;
    }

    public static ThreadLocal getStepTestThreadLocal() {
        return stepTestThreadLocal;
    }

    public static ThreadLocal getScenarioThreadLocal() {
        return scenarioThreadLocal;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy