Package net.thucydides.core.reports.html

Source Code of net.thucydides.core.reports.html.HtmlAggregateStoryReporter

package net.thucydides.core.reports.html;

import com.beust.jcommander.internal.Lists;
import net.thucydides.core.ThucydidesSystemProperties;
import net.thucydides.core.ThucydidesSystemProperty;
import net.thucydides.core.guice.Injectors;
import net.thucydides.core.issues.IssueTracking;
import net.thucydides.core.model.NumericalFormatter;
import net.thucydides.core.model.Release;
import net.thucydides.core.model.TestResult;
import net.thucydides.core.model.TestTag;
import net.thucydides.core.releases.ReleaseManager;
import net.thucydides.core.reports.*;
import net.thucydides.core.reports.csv.CSVReporter;
import net.thucydides.core.requirements.RequirementsProviderService;
import net.thucydides.core.requirements.RequirementsService;
import net.thucydides.core.requirements.model.Requirement;
import net.thucydides.core.requirements.model.RequirementsConfiguration;
import net.thucydides.core.requirements.reports.RequirementOutcome;
import net.thucydides.core.requirements.reports.RequirementsOutcomes;
import net.thucydides.core.requirements.reports.RequirmentsOutcomeFactory;
import net.thucydides.core.util.EnvironmentVariables;
import net.thucydides.core.util.Inflector;
import net.thucydides.core.util.VersionProvider;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Generates an aggregate acceptance test report in HTML form.
* Reads all the reports from the output directory to generates aggregate HTML reports
* summarizing the results.
*/
public class HtmlAggregateStoryReporter extends HtmlReporter implements UserStoryTestReporter {

    private static final Logger LOGGER = LoggerFactory.getLogger(HtmlAggregateStoryReporter.class);

    private static final String HISTORY_TEMPLATE_PATH = "freemarker/history.ftl";
    private static final String TEST_OUTCOME_TEMPLATE_PATH = "freemarker/home.ftl";
    private static final String RELEASES_TEMPLATE_PATH = "freemarker/releases.ftl";
    private static final String RELEASE_TEMPLATE_PATH = "freemarker/release.ftl";
    private static final String TAGTYPE_TEMPLATE_PATH = "freemarker/results-by-tagtype.ftl";
    private static final String REQUIREMENT_TYPE_TEMPLATE_PATH = "freemarker/requirement-type.ftl";

//    private TestHistory testHistory;
    private String projectName;
    private String relativeLink;
    private ReportNameProvider reportNameProvider;
    private final IssueTracking issueTracking;
    private final RequirementsService requirementsService;
    private final RequirmentsOutcomeFactory requirementsFactory;
    private final HtmlRequirementsReporter htmlRequirementsReporter;
    private final RequirementsConfiguration requirementsConfiguration;
    private final EnvironmentVariables environmentVariables;
    private FormatConfiguration formatConfiguration;

    public HtmlAggregateStoryReporter(final String projectName) {
        this(projectName, "");
    }

    public HtmlAggregateStoryReporter(final String projectName, final String relativeLink) {
        this(projectName, relativeLink,
             Injectors.getInjector().getInstance(IssueTracking.class),
             Injectors.getInjector().getInstance(RequirementsService.class),
             Injectors.getInjector().getProvider(EnvironmentVariables.class).get() );
    }

    public HtmlAggregateStoryReporter(final String projectName,
                                      final IssueTracking issueTracking) {
        this(projectName, "", issueTracking, Injectors.getInjector().getInstance(RequirementsService.class),
             Injectors.getInjector().getProvider(EnvironmentVariables.class).get() );
    }

    public HtmlAggregateStoryReporter(final String projectName,
                                      final String relativeLink,
                                      final IssueTracking issueTracking,
                                      final RequirementsService requirementsService,
                                      final EnvironmentVariables environmentVariables) {
        this.projectName = projectName;
        this.relativeLink = relativeLink;
        this.issueTracking = issueTracking;
//        this.testHistory = testHistory;
        this.reportNameProvider = new ReportNameProvider();
        this.htmlRequirementsReporter = new HtmlRequirementsReporter(relativeLink);

        RequirementsProviderService requirementsProviderService = Injectors.getInjector().getInstance(RequirementsProviderService.class);
        this.requirementsFactory = new RequirmentsOutcomeFactory(requirementsProviderService.getRequirementsProviders(), issueTracking);
        this.requirementsService = requirementsService;
        this.requirementsConfiguration = new RequirementsConfiguration(getEnvironmentVariables());
        this.environmentVariables = environmentVariables;
        this.formatConfiguration = new FormatConfiguration(environmentVariables);
    }

    public OutcomeFormat getFormat() {
       return formatConfiguration.getPreferredFormat();
    }

    public String getProjectName() {
        return projectName;
    }

    private void addFormattersToContext(final Map<String, Object> context) {
        Formatter formatter = new Formatter(issueTracking);
        context.put("formatter", formatter);
        context.put("formatted", new NumericalFormatter());
        context.put("inflection", Inflector.getInstance());
        context.put("relativeLink", relativeLink);
        context.put("reportOptions", new ReportOptions(getEnvironmentVariables()));
    }

    public TestOutcomes generateReportsForTestResultsFrom(final File sourceDirectory) throws IOException {
        TestOutcomes allTestOutcomes = loadTestOutcomesFrom(sourceDirectory);
        copyScreenshotsFrom(sourceDirectory);
        generateReportsForTestResultsIn(allTestOutcomes);
        return allTestOutcomes;
    }

    private void copyScreenshotsFrom(File sourceDirectory) {
        if ((getOutputDirectory() != null) && (getOutputDirectory() != sourceDirectory)) {
            CopyOption[] options = new CopyOption[]{ StandardCopyOption.COPY_ATTRIBUTES };

            Path targetPath = Paths.get(getOutputDirectory().toURI());
            Path sourcePath = Paths.get(sourceDirectory.toURI());
            try {

                DirectoryStream<Path> directoryContents = Files.newDirectoryStream(sourcePath);
                for(Path sourceFile : directoryContents) {
                    Path destinationFile = targetPath.resolve(sourceFile.getFileName());
                    if (Files.notExists(destinationFile)) {
                        Files.copy(sourceFile, destinationFile, options);
                    }
                }
            } catch (IOException e) {
                LOGGER.error("Error during copying files to the target directory", e);
            }
        }
    }

    public void generateReportsForTestResultsIn(TestOutcomes testOutcomes) throws IOException {
        RequirementsOutcomes requirementsOutcomes = requirementsFactory.buildRequirementsOutcomesFrom(testOutcomes.withRequirementsTags());

        copyResourcesToOutputDirectory();
        copyTestResultsToOutputDirectory();

        generateAggregateReportFor(testOutcomes);
        generateTagReportsFor(testOutcomes);
        generateTagTypeReportsFor(testOutcomes);
        for (String name : testOutcomes.getTagNames()) {
            generateTagTypeReportsFor(testOutcomes.withTag(name), new ReportNameProvider(name));
        }
        generateRequirementTypeReports(requirementsOutcomes);
        generateResultReportsFor(testOutcomes);
//        generateHistoryReportFor(testOutcomes);
//        generateCoverageReportsFor(testOutcomes);

        generateRequirementsReportsFor(requirementsOutcomes);

        generateReleasesReportFor(testOutcomes, requirementsOutcomes);

    }

    private void generateRequirementTypeReports(RequirementsOutcomes requirementsOutcomes) throws IOException {
        List<String> requirementTypes = requirementsOutcomes.getTypes();
        for (String requirementType : requirementTypes) {
            generateRequirementTypeReportFor(requirementType,
                    requirementsOutcomes.requirementsOfType(requirementType),
                    new ReportNameProvider());
        }
    }

    private void generateRequirementTypeReportFor(String requirementType,
                                                  RequirementsOutcomes requirementsOutcomes,
                                                  ReportNameProvider reporter) throws IOException {
        Map<String, Object> context = buildContext(requirementsOutcomes.getTestOutcomes(), getReportNameProvider());
        context.put("report", ReportProperties.forAggregateResultsReport());
        context.put("requirementType", requirementType);
        context.put("requirements", requirementsOutcomes);

        String reportName = reporter.forRequirementType(requirementType);
        generateReportPage(context, REQUIREMENT_TYPE_TEMPLATE_PATH, reportName);

    }

    private void generateCSVReportFor(TestOutcomes testOutcomes, String reportName) throws IOException {
        CSVReporter csvReporter = new CSVReporter(getOutputDirectory(), getEnvironmentVariables());
        csvReporter.generateReportFor(testOutcomes, reportName);
    }

    List<Requirement> reportTally = Lists.newArrayList();

    public void generateRequirementsReportsFor(RequirementsOutcomes requirementsOutcomes) throws IOException {

        htmlRequirementsReporter.setOutputDirectory(getOutputDirectory());
        htmlRequirementsReporter.generateReportFor(requirementsOutcomes);

//        htmlProgressReporter.setOutputDirectory(getOutputDirectory());
//        htmlProgressReporter.generateReportFor(requirementsOutcomes);

        clearReportTally();
        generateRequirementsReportsForChildRequirements(requirementsOutcomes);
    }

    private void clearReportTally() {
        reportTally.clear();
    }

    private void generateRequirementsReportsForChildRequirements(RequirementsOutcomes requirementsOutcomes) throws IOException {
        List<RequirementOutcome> requirementOutcomes = requirementsOutcomes.getRequirementOutcomes();
        for (RequirementOutcome outcome : requirementOutcomes) {
            Requirement requirement = outcome.getRequirement();
            if (!reportTally.contains(requirement)) {
                TestOutcomes testOutcomesForThisRequirement = outcome.getTestOutcomes().withTag(requirement.asTag());
                RequirementsOutcomes requirementOutcomesForThisRequirement = requirementsFactory.buildRequirementsOutcomesFrom(requirement, testOutcomesForThisRequirement);
                generateNestedRequirementsReportsFor(requirement, requirementOutcomesForThisRequirement);
            }
        }
    }

    private void generateNestedRequirementsReportsFor(Requirement parentRequirement, RequirementsOutcomes requirementsOutcomes) throws IOException {
        htmlRequirementsReporter.setOutputDirectory(getOutputDirectory());
        String reportName = reportNameProvider.forRequirement(parentRequirement);
        if (!reportTally.contains(parentRequirement)) {
            reportTally.add(parentRequirement);
            htmlRequirementsReporter.generateReportFor(requirementsOutcomes, requirementsOutcomes.getTestOutcomes(), reportName);
        }

        generateRequirementsReportsForChildRequirements(requirementsOutcomes);

    }

    private TestOutcomes loadTestOutcomesFrom(File sourceDirectory) throws IOException {
        return TestOutcomeLoader.loadTestOutcomes().inFormat(getFormat()).from(sourceDirectory).withHistory().withRequirementsTags();
    }

    private void generateAggregateReportFor(TestOutcomes testOutcomes) throws IOException {

        ReportNameProvider defaultNameProvider = new ReportNameProvider();
        Map<String, Object> context = buildContext(testOutcomes, defaultNameProvider, true);
        context.put("report", ReportProperties.forAggregateResultsReport());
        context.put("csvReport", "results.csv");

        generateReportPage(context, TEST_OUTCOME_TEMPLATE_PATH, "index.html");
        generateCSVReportFor(testOutcomes, "results.csv");
    }

    private ReleaseManager releaseManager;

    private ReleaseManager getReleaseManager() {
        if (releaseManager == null) {
            ReportNameProvider defaultNameProvider = new ReportNameProvider();
            releaseManager = new ReleaseManager(getEnvironmentVariables(), defaultNameProvider);
        }
        return releaseManager;
    }

    private ReportNameProvider defaultNameProvider;

    private ReportNameProvider getReportNameProvider() {
        if (defaultNameProvider == null) {
            defaultNameProvider = new ReportNameProvider();
        }
        return defaultNameProvider;
    }

    private void generateReleasesReportFor(TestOutcomes testOutcomes,
                                           RequirementsOutcomes requirementsOutcomes) throws IOException {
        Map<String, Object> context = buildContext(testOutcomes, getReportNameProvider());
        context.put("report", ReportProperties.forAggregateResultsReport());
        List<Release> releases = getReleaseManager().getReleasesFrom(testOutcomes);
        LOGGER.info("Generating release reports for: " + releases);
        if (!releases.isEmpty()) {
            String releaseData = getReleaseManager().getJSONReleasesFrom(testOutcomes);
            context.put("releases", releases);
            context.put("releaseData", releaseData);
            context.put("requirements", requirementsOutcomes);

            generateReportPage(context, RELEASES_TEMPLATE_PATH, "releases.html");
            generateReleaseDetailsReportsFor(testOutcomes, requirementsOutcomes);
        }
    }

    private void generateReleaseDetailsReportsFor(TestOutcomes testOutcomes,
                                                  RequirementsOutcomes requirementsOutcomes) throws IOException {
        List<Release> allReleases = getReleaseManager().getFlattenedReleasesFrom(testOutcomes);
        List<String> requirementsTypes = getRequirementTypes();
        String topLevelRequirementType = requirementsTypes.get(0);
        String secondLevelRequirementType = "";
        String secondLevelRequirementTypeTitle = "";
        String topLevelRequirementTypeTitle = Inflector.getInstance().of(topLevelRequirementType)
                .inPluralForm().asATitle().toString();

        if (requirementsTypes.size() > 1) {
            secondLevelRequirementType = requirementsTypes.get(1);
            secondLevelRequirementTypeTitle = Inflector.getInstance().of(secondLevelRequirementType)
                    .inPluralForm().asATitle().toString();
        }
        for (Release release : allReleases) {
            RequirementsOutcomes releaseRequirements = requirementsOutcomes.getReleasedRequirementsFor(release);
            Map<String, Object> context = buildContext(testOutcomes, getReportNameProvider());

            context.put("report", ReportProperties.forAggregateResultsReport());
            context.put("release", release);

            context.put("releaseData", getReleaseManager().getJSONReleasesFrom(release));
            context.put("releaseRequirementOutcomes", releaseRequirements.getRequirementOutcomes());
            context.put("releaseTestOutcomes", testOutcomes.withTag(release.getReleaseTag()));

            context.put("requirementType", topLevelRequirementTypeTitle);
            if (StringUtils.isNotBlank(secondLevelRequirementTypeTitle)) {
                context.put("secondLevelRequirementType", secondLevelRequirementTypeTitle);
            }

            // capability | features | total automated tests | %automated pass | total manual | % manual
            String reportName = getReportNameProvider().forRelease(release);
            generateReportPage(context, RELEASE_TEMPLATE_PATH, reportName);
        }
    }

    private void generateTagReportsFor(TestOutcomes testOutcomes) throws IOException {

        for (TestTag tag : testOutcomes.getTags()) {
            generateTagReport(testOutcomes, reportNameProvider, tag);
            generateAssociatedTagReportsForTag(testOutcomes.withTag(tag), tag.getName());
        }
    }

    private void generateTagTypeReportsFor(TestOutcomes testOutcomes) throws IOException {
        generateTagTypeReportsFor(testOutcomes, reportNameProvider);
    }

    private void generateTagTypeReportsFor(TestOutcomes testOutcomes, ReportNameProvider reportNameProvider) throws IOException {

        for (String tagType : testOutcomes.getTagTypes()) {
            generateTagTypeReport(testOutcomes, reportNameProvider, tagType);
        }
    }

    private void generateResultReportsFor(TestOutcomes testOutcomes) throws IOException {
        generateResultReports(testOutcomes, reportNameProvider);

        for (TestTag tag : testOutcomes.getTags()) {
            generateResultReports(testOutcomes.withTag(tag), new ReportNameProvider(tag.getName()), tag);
        }
    }

//    private void generateCoverageReportsFor(TestOutcomes testOutcomes) throws IOException {
//
//        for (String tagType : testOutcomes.getTagTypes()) {
//            generateCoverageData(testOutcomes, tagType);
//        }
//    }
    private void generateResultReports(TestOutcomes testOutcomes, ReportNameProvider reportName) throws IOException {
        generateResultReports(testOutcomes,reportName, TestTag.EMPTY_TAG);
    }

    private void generateResultReports(TestOutcomes testOutcomesForThisTag, ReportNameProvider reportName, TestTag tag) throws IOException {
        if (testOutcomesForThisTag.getTotalTests().withResult(TestResult.SUCCESS) > 0) {
            generateResultReport(testOutcomesForThisTag.getPassingTests(), reportName, tag, "success");
        }
        if (testOutcomesForThisTag.getTotalTests().withResult(TestResult.PENDING) > 0) {
            generateResultReport(testOutcomesForThisTag.getPendingTests(), reportName, tag, "pending");
        }
        if (testOutcomesForThisTag.getTotalTests().withResult(TestResult.FAILURE) > 0) {
            generateResultReport(testOutcomesForThisTag.getFailingTests(), reportName, tag, "failure");
        }
        if (testOutcomesForThisTag.getTotalTests().withResult(TestResult.ERROR) > 0) {
            generateResultReport(testOutcomesForThisTag.getErrorTests(), reportName, tag, "error");
        }
        if (testOutcomesForThisTag.getTotalTests().withResult(TestResult.IGNORED) > 0) {
            generateResultReport(testOutcomesForThisTag.havingResult(TestResult.IGNORED), reportName, tag, "ignored");
        }
        if (testOutcomesForThisTag.getTotalTests().withResult(TestResult.SKIPPED) > 0) {
            generateResultReport(testOutcomesForThisTag.havingResult(TestResult.SKIPPED), reportName, tag, "skipped");
        }
    }

    private void generateResultReport(TestOutcomes testOutcomes, ReportNameProvider reportName, TestTag tag, String testResult) throws IOException {
        Map<String, Object> context = buildContext(testOutcomes, reportName);
        context.put("report", ReportProperties.forTestResultsReport());
        context.put("currentTagType", tag.getType());
        context.put("currentTag", tag);

        String csvReport = reportName.forCSVFiles().forTestResult(testResult);
        context.put("csvReport", csvReport);
        String report = reportName.withPrefix(tag).forTestResult(testResult);
        generateReportPage(context, TEST_OUTCOME_TEMPLATE_PATH, report);
        generateCSVReportFor(testOutcomes, csvReport);
    }

    private void generateTagReport(TestOutcomes testOutcomes, ReportNameProvider reportName, TestTag tag) throws IOException {
        TestOutcomes testOutcomesForTag = testOutcomes.withTag(tag);
        Map<String, Object> context = buildContext(testOutcomesForTag, reportName);
        context.put("report", ReportProperties.forTagResultsReport());
        context.put("currentTagType", tag.getType());
        context.put("currentTag", tag);

        String csvReport = reportName.forCSVFiles().forTag(tag);
        context.put("csvReport", csvReport);

        String report = reportName.forTag(tag);
        generateReportPage(context, TEST_OUTCOME_TEMPLATE_PATH, report);
        generateCSVReportFor(testOutcomesForTag, csvReport);
    }


    private void generateTagTypeReport(TestOutcomes testOutcomes, ReportNameProvider reportName, String tagType) throws IOException {

        TestOutcomes testOutcomesForTagType = testOutcomes.withTagType(tagType);

        Map<String, Object> context = buildContext(testOutcomesForTagType, reportName);
        context.put("report", ReportProperties.forTagTypeResultsReport());
        context.put("tagType", tagType);

        String csvReport = reportName.forCSVFiles().forTagType(tagType);
        context.put("csvReport", csvReport);

        String report = reportName.forTagType(tagType);
        generateReportPage(context, TAGTYPE_TEMPLATE_PATH, report);
        generateCSVReportFor(testOutcomesForTagType, csvReport);
    }

    private void generateAssociatedTagReportsForTag(TestOutcomes testOutcomes, String sourceTag) throws IOException {
        ReportNameProvider reportName = new ReportNameProvider(sourceTag);
        for (TestTag tag : testOutcomes.getTags()) {
            generateTagReport(testOutcomes, reportName, tag);
        }
    }

    private Map<String, Object> buildContext(TestOutcomes testOutcomesForTagType,
                                             ReportNameProvider reportName) {
        return buildContext(testOutcomesForTagType, reportName, false);
    }

    private Map<String, Object> buildContext(TestOutcomes testOutcomesForTagType,
                                             ReportNameProvider reportName,
                                             boolean useFiltering) {
        Map<String, Object> context = new HashMap<String, Object>();
        TagFilter tagFilter = new TagFilter(getEnvironmentVariables());
        context.put("testOutcomes", testOutcomesForTagType);
        context.put("allTestOutcomes", testOutcomesForTagType.getRootOutcomes());
        if (useFiltering) {
            context.put("tagTypes", tagFilter.filteredTagTypes(testOutcomesForTagType.getTagTypes()));
        } else {
            context.put("tagTypes", testOutcomesForTagType.getTagTypes());
        }
        context.put("currentTag", TestTag.EMPTY_TAG);
        context.put("reportName", reportName);
        context.put("absoluteReportName", new ReportNameProvider());

        context.put("reportOptions", new ReportOptions(getEnvironmentVariables()));
        //context.put("timestamp", timestampFrom(testOutcomesForTagType.getRootOutcomes()));
        context.put("timestamp", timestampFrom(currentTime()));
        context.put("requirementTypes", requirementsService.getRequirementTypes());
        addFormattersToContext(context);


        VersionProvider versionProvider = new VersionProvider(environmentVariables);
        context.put("thucydidesVersionNumber", versionProvider.getVersion());
        context.put("buildNumber", versionProvider.getBuildNumberText());

        return context;
    }

    private void generateReportPage(final Map<String, Object> context,
                                    final String template,
                                    final String outputFile) throws IOException {
        String htmlContents = mergeTemplate(template).usingContext(context);
        writeReportToOutputDirectory(outputFile, htmlContents);
    }

    protected ThucydidesSystemProperties getSystemProperties() {
        return ThucydidesSystemProperties.getProperties();
    }

    public void setIssueTrackerUrl(String issueTrackerUrl) {
        if (issueTrackerUrl != null) {
            getSystemProperties().setValue(ThucydidesSystemProperty.THUCYDIDES_ISSUE_TRACKER_URL, issueTrackerUrl);
        }
    }

    public void setJiraUrl(String jiraUrl) {
        if (jiraUrl != null) {
            getSystemProperties().setValue(ThucydidesSystemProperty.JIRA_URL, jiraUrl);
        }
    }

    public void setJiraProject(String jiraProject) {
        if (jiraProject != null) {
            getSystemProperties().setValue(ThucydidesSystemProperty.JIRA_PROJECT, jiraProject);
        }
    }

    public void setJiraUsername(String jiraUsername) {
        if (jiraUsername != null) {
            getSystemProperties().setValue(ThucydidesSystemProperty.JIRA_USERNAME, jiraUsername);
        }
    }

    public void setJiraPassword(String jiraPassword) {
        if (jiraPassword != null) {
            getSystemProperties().setValue(ThucydidesSystemProperty.JIRA_PASSWORD, jiraPassword);
        }
    }

    public List<String> getRequirementTypes() {
        List<String> types = requirementsService.getRequirementTypes();
        if (types.isEmpty()) {
            LOGGER.warn("No requirement types found in the test outcome requirements: using default requirements");
            return requirementsConfiguration.getRequirementTypes();
        } else {
            return types;
        }
    }

    /**
     * Check the test outcomes for failures or errors, and throw an appropriate exception if one is found.
     */
    public void checkOutcomes() {

    }
}
TOP

Related Classes of net.thucydides.core.reports.html.HtmlAggregateStoryReporter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.