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

net.masterthought.cucumber.CucumberReportGeneratorMojo Maven / Gradle / Ivy

Go to download

This project provides a maven mojo for using cucumber-reporting to publish pretty html reports for Cucumber. It works by generating html from the cucumber json report formatter. So can be used anywhere a json report is generated. Current use is in the cucumber jenkins plugin and a maven mojo to generate the same report from mvn command line when running locally.

There is a newer version: 9863b38b-beta
Show newest version
package net.masterthought.cucumber;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collections;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.StringUtils;

import net.masterthought.cucumber.json.support.Status;
import net.masterthought.cucumber.reducers.ReducingMethod;

/**
 * Goal which generates a Cucumber Report.
 *
 * @goal generate
 * @phase verify
 */
public class CucumberReportGeneratorMojo extends AbstractMojo {

    /**
     * Name of the project.
     *
     * @parameter property="project.name"
     * @required
     */
    private String projectName;

    /**
     * Build number.
     *
     * @parameter property="build.number" default-value="1"
     */
    private String buildNumber;

    /**
     * Location to output the HTML report to.
     *
     * @parameter default-value="${project.build.directory}/cucumber-reports"
     * @required
     */
    private File outputDirectory;

    /**
     * Location of the Cucumber JSON files to generate the report from.
     * Files in this directory will be matched against the patterns specified
     * in the jsonFiles property.
     * If not specified, defaults to the same value as outputDirectory.
     *
     * @parameter
     */
    private File inputDirectory;

    /**
     * Array of JSON files to process
     * @parameter
     * @required
     */
    private String[] jsonFiles;

    /**
     * Location of the classification files to add to the report.
     * Files in this directory will be matched against the patterns specified
     * in the classificationFiles property.
     * If not specified, defaults to the same value as outputDirectory.
     *
     * @parameter
     */
    private File classificationDirectory;

    /**
     * File where the trends is stored.
     * @parameter
     */
    private int trendsLimit;

    /**
     * File where the trends is stored.
     * @parameter
     */
    private File trendsFile;

    /**
     * Array of PROPERTY files to process
     *
     * @parameter
     */
    private String[] classificationFiles;

    /**
     * Skip check for failed build result.
     *
     * @parameter default-value="true"
     * @required
     */
    private Boolean checkBuildResult;

    /**
     * Treat failed scenarios as build failure when using checkBuildResult=true.
     *
     * @parameter default-value="false"
     */
    private Boolean treatScenariosAsFailed;

    /**
     * Treat 'undefined' steps as failures when using checkBuildResult=true.
     *
     * @parameter default-value="false"
     */
    private Boolean treatUndefinedAsFailed;

    /**
     * Treat 'pending' steps as failures when using checkBuildResult=true.
     *
     * @parameter default-value="false"
     */
    private Boolean treatPendingAsFailed;

    /**
     * Treat 'skipped' steps as failures when using checkBuildResult=true.
     *
     * @parameter default-value="false"
     */
    private Boolean treatSkippedAsFailed;

    /**
     * Additional attributes to classify current test run.
     *
     * @parameter
     */
    private Map classifications;

    /**
     * Set this to "true" to bypass generation of Cucumber Reports entirely.
     *
     * @parameter property="cucumber.report.skip" default-value="false"
     */
    private boolean skip;

    /**
     * Merge features with the same ID so scenarios are be merged into single feature.
     *
     * @parameter
     */
    private boolean mergeFeaturesById;

    /**
     * Merge features and scenarios from different JSON files of different runs
     * into a single report by features' and scenarios' ids.
     *
     * @parameter
     */
    private boolean mergeFeaturesWithRetest;

    /**
     * Skips JSON reports which have been parsed but have none features or are empty file at all.
     *
     * @parameter
     */
    private boolean skipEmptyJSONFiles;

    /**
     * Consider skipped tests as not failed ones.
     *
     * @parameter
     */
    private boolean setSkippedAsNotFailing;

    @Override
    public void execute() throws MojoExecutionException {

        if (skip) {
            getLog().info("Cucumber report generation is skipped.");
            return;
        }

        if (inputDirectory == null) {
            inputDirectory = outputDirectory;
        }

        if (classificationDirectory == null) {
            classificationDirectory = outputDirectory;
        }

        if (!outputDirectory.exists()) {
            outputDirectory.mkdirs();
        }

        // Find all json files that match json file include pattern...
        List jsonFilesToProcess = genericFindFiles(inputDirectory,jsonFiles);

        // Find all json files that match classification file include pattern...
        List classificationFilesToProcess = genericFindFiles(classificationDirectory, classificationFiles);

        try {
            Configuration configuration = new Configuration(outputDirectory, projectName);
            configuration.setBuildNumber(buildNumber);
            if (mergeFeaturesById) {
                configuration.addReducingMethod(ReducingMethod.MERGE_FEATURES_BY_ID);
            }
            if (!MapUtils.isEmpty(classifications)) {
                for (Map.Entry entry : classifications.entrySet()) {
                    configuration.addClassifications(StringUtils.capitalise(entry.getKey()), entry.getValue());
                }
            }
            if (CollectionUtils.isNotEmpty(classificationFilesToProcess)) {
                configuration.addClassificationFiles(classificationFilesToProcess);
            }
            if (mergeFeaturesById) {
                configuration.addReducingMethod(ReducingMethod.MERGE_FEATURES_BY_ID);
            }
            if (mergeFeaturesWithRetest) {
                configuration.addReducingMethod(ReducingMethod.MERGE_FEATURES_WITH_RETEST);
            }
            if (skipEmptyJSONFiles) {
                configuration.addReducingMethod(ReducingMethod.SKIP_EMPTY_JSON_FILES);
            }

            if (setSkippedAsNotFailing) {
                configuration.setNotFailingStatuses(Collections.singleton(Status.SKIPPED));
            }

            if (trendsFile != null) {
                configuration.setTrends(trendsFile, trendsLimit);
            }

            ReportBuilder reportBuilder = new ReportBuilder(jsonFilesToProcess, configuration);
            getLog().info("About to generate Cucumber report.");
            Reportable report = reportBuilder.generateReports();

            if (checkBuildResult && (report == null || report.getFailedSteps() > 0 ||
                    (treatScenariosAsFailed && report.getFailedScenarios() > 0) ||
                    (treatUndefinedAsFailed && report.getUndefinedSteps() > 0) ||
                    (treatPendingAsFailed && report.getPendingSteps() > 0) ||
                    (treatSkippedAsFailed && report.getSkippedSteps() > 0))) {
                throw new MojoExecutionException("BUILD FAILED - Check Report For Details");
            }

        } catch (Exception e) {
            throw new MojoExecutionException("Error Found:", e);
        }
    }

    static List genericFindFiles(File targetDirectory, String[] fileIncludePattern) {
        if (ArrayUtils.isEmpty(fileIncludePattern)) {
            return Collections.emptyList();
        }
        DirectoryScanner scanner = new DirectoryScanner();
        scanner.setIncludes(fileIncludePattern);
        scanner.setBasedir(targetDirectory);
        scanner.scan();
        String[] files = scanner.getIncludedFiles();
        return fullPathToFiles(files, targetDirectory);
    }

    private static List fullPathToFiles(String[] files, File targetDirectory) {
        List fullPathList = new ArrayList<>();
        for (String file : files) {
            fullPathList.add(new File(targetDirectory, file).getAbsolutePath());
        }
        return fullPathList;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy