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

nl.hsac.fitnesse.junit.reportmerge.writer.HtmlOverviewFileWriter Maven / Gradle / Ivy

package nl.hsac.fitnesse.junit.reportmerge.writer;

import nl.hsac.fitnesse.junit.reportmerge.TestReportHtml;

import java.io.File;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static nl.hsac.fitnesse.junit.reportmerge.TestReportHtml.ERROR_STATUS;
import static nl.hsac.fitnesse.junit.reportmerge.TestReportHtml.FAIL_STATUS;
import static nl.hsac.fitnesse.junit.reportmerge.TestReportHtml.IGNORE_STATUS;
import static nl.hsac.fitnesse.junit.reportmerge.TestReportHtml.NO_TEST_STATUS;
import static nl.hsac.fitnesse.junit.reportmerge.TestReportHtml.PASS_STATUS;

public class HtmlOverviewFileWriter extends OverviewFileWriter {
    private static final String TESTCOUNT_CHART_ID = "countPie";
    private static final String RUNTIME_CHART_ID = "runtimePie";
    private static final String STATUS_CHART_ID = "statusPie";
    private static final String TIME_PER_TEST_CHART_ID = "timePerTestChart";
    private static final String COPY_TO_CLIPBOARD_JS =
            "function elementContentsToClipboard(el) {" +
                    "var selected = document.getSelection().rangeCount > 0? document.getSelection().getRangeAt(0):false;" +
                    "var body = document.body, range, sel;" +
                    "if (document.createRange && window.getSelection) {" +
                    "range = document.createRange();" +
                    "sel = window.getSelection();" +
                    "sel.removeAllRanges();" +
                    "try {" +
                    "range.selectNodeContents(el);" +
                    "sel.addRange(range);" +
                    "} catch (e) {" +
                    "range.selectNode(el);" +
                    "sel.addRange(range);" +
                    "}" +
                    "document.execCommand('copy');" +
                    "} else if (body.createTextRange) {" +
                    "range = body.createTextRange();" +
                    "range.moveToElementText(el);" +
                    "range.select();" +
                    "range.execCommand('copy');" +
                    "}" +
                    "document.getSelection().removeAllRanges();" +
                    "if (selected) document.getSelection().addRange(selected);" +
                    "}";

    private final NumberFormat nf = NumberFormat.getIntegerInstance();
    protected Function jsonWriterFunction;

    public HtmlOverviewFileWriter(File parentDir, Function jsonWriterFunction) {
        super(parentDir, "index.html");
        this.jsonWriterFunction = jsonWriterFunction;
    }

    @Override
    protected void writeContent(List htmls) {
        writeHeader(pw, htmls);
        writeBody(pw, htmls);
        writeFooter(pw, htmls);
    }

    protected void writeHeader(PrintWriter pw, List htmls) {
        pw.write("");
        writeCssLink(pw, htmls);
        pw.write("");
        writeExtraHeaderContent(pw, htmls);
        pw.write("");
    }

    protected void writeCssLink(PrintWriter pw, List htmls) {
        pw.write("");
    }

    protected void writeExtraHeaderContent(PrintWriter pw, List htmls) {
        getChartWriter(pw).writeLoadScriptTag();
    }

    protected void writeFooter(PrintWriter pw, List htmls) {
        writeChartScript(pw, htmls);
        pw.write("");
    }

    protected void writeBody(PrintWriter pw, List htmls) {
        writeOverviewSection(pw, htmls);
        writeTestResultsSection(pw, htmls);
    }

    protected void writeOverviewSection(PrintWriter pw, List htmls) {
        writeOverviewGraph(pw, htmls);

        writeLinks(pw, htmls);

        List overviewPages = filterBy(htmls, TestReportHtml::isOverviewPage);
        writeSection(pw, "Overview Pages", overviewPages);
    }

    protected void writeOverviewGraph(PrintWriter pw, List htmls) {
        pw.write("
"); List testHtmls = filterBy(htmls, x -> !x.isOverviewPage() && !NO_TEST_STATUS.equals(x.getStatus())); pw.write(""); writeGraphCell(pw, ERROR_STATUS, testHtmls); writeGraphCell(pw, FAIL_STATUS, testHtmls); writeGraphCell(pw, IGNORE_STATUS, testHtmls); writeGraphCell(pw, PASS_STATUS, testHtmls); pw.write("
"); writePieChartsElement(pw, htmls); pw.write("
"); } protected void writeGraphCell(PrintWriter pw, String status, List testHtmls) { int totalCount = testHtmls.size(); int count = filterByStatus(testHtmls, status).size(); if (count > 0) { int pct = (count * 100) / totalCount; String cell = String.format("%s", status, pct, count); pw.write(cell); } } protected void writePieChartsElement(PrintWriter pw, List htmls) { pw.write("
"); writePieChartElements(pw, htmls); pw.write("
"); } protected void writeChartGeneratorBody(ChartWriter writer, List htmls) { List nonOverviews = filterBy(htmls, r -> !r.isOverviewPage()); writeStatusPieChartGenerator(writer, nonOverviews); writer.writePieChartGenerator("Tests / Run", TESTCOUNT_CHART_ID, nonOverviews, r -> r.getRunName(), Collectors.counting()); writer.writePieChartGenerator("Time / Run", RUNTIME_CHART_ID, nonOverviews, r -> r.getRunName(), Collectors.summingLong(r -> r.getTime() < 0 ? 0 : r.getTime())); writer.writeBarChartGenerator( pw -> jsonWriterFunction.apply(pw).writeContent(htmls), "ms / Test", TIME_PER_TEST_CHART_ID, ",hAxis:{textPosition:'none'}" ); } protected void writeStatusPieChartGenerator(ChartWriter writer, List htmls) { Map displayedStatus = getStatusMap(htmls); writer.writePieChartGenerator("Status", STATUS_CHART_ID, ",slices:[{color:'#ffffaa'},{color:'#FF6666'},{color:'orange'},{color:'#28B463'},{color:'lightgray'}]", r -> r.getKey(), r -> r.getValue(), displayedStatus.entrySet()); } protected void writePieChartElements(PrintWriter pw, List htmls) { pw.write("
"); pw.write("
"); pw.write("
"); } protected void writeLinks(PrintWriter pw, List htmls) { pw.write("
"); pw.write("Test results in: "); pw.write("CSV JSON"); pw.write("
"); } protected void writeTestResultsSection(PrintWriter pw, List htmls) { List testHtmls = filterBy(htmls, x -> !x.isOverviewPage()); pw.write("
"); List erroredTests = filterByStatus(testHtmls, ERROR_STATUS); writeSection(pw, "Errored Tests", erroredTests); List failedTests = filterByStatus(testHtmls, FAIL_STATUS); writeSection(pw, "Failed Tests", failedTests); List ignoredTests = filterByStatus(testHtmls, IGNORE_STATUS); writeSection(pw, "Ignored Tests", ignoredTests); pw.write("
"); List passedTests = filterByStatus(testHtmls, PASS_STATUS); writeSection(pw, "Passed Tests", passedTests); List noTests = filterByStatus(testHtmls, NO_TEST_STATUS); writeSection(pw, "Pages Without Assertions", noTests); pw.write("
"); } protected void writeSection(PrintWriter pw, String header, List htmls) { if (!htmls.isEmpty()) { String id = header.replaceAll("\\s", ""); pw.write("
"); pw.write("

"); pw.write(header); pw.write("

"); String tableId = id + "Table"; pw.write(""); writeTestsTable(pw, tableId, htmls); pw.write("
"); } } protected void writeTestsTable(PrintWriter pw, String id, List htmls) { pw.write(""); // slowest times at top htmls.sort((o1, o2) -> Long.compare(o2.getTime(), o1.getTime())); for (TestReportHtml test : htmls) { writeTestRow(pw, test); } pw.write("
RunNameRuntime (in milliseconds)
"); } protected void writeTestRow(PrintWriter pw, TestReportHtml html) { String testPageName = html.getRelativePath(); String status = html.getStatus(); String run = html.getRunName(); String testName = html.getTestName(); long time = html.getTime(); pw.write(""); pw.write(""); pw.write(run); pw.write(""); pw.write(""); pw.write(testName); pw.write(""); pw.write(time < 0 ? "unknown" : nf.format(time)); pw.write(""); } protected Map getStatusMap(List htmls) { Map statuses = htmls.stream() .collect(Collectors.groupingBy(TestReportHtml::getStatus, Collectors.counting())); Map displayedStatus = new LinkedHashMap<>(); addStatusEntry(ERROR_STATUS, statuses, displayedStatus); addStatusEntry(FAIL_STATUS, statuses, displayedStatus); addStatusEntry(IGNORE_STATUS, statuses, displayedStatus); addStatusEntry(PASS_STATUS, statuses, displayedStatus); addStatusEntry(NO_TEST_STATUS, statuses, displayedStatus); return displayedStatus; } protected void addStatusEntry(String status, Map statuses, Map displayedStatus) { displayedStatus.put(status, statuses.getOrDefault(status, 0L)); } protected void writeChartScript(PrintWriter pw, List htmls) { ChartWriter chartWriter = getChartWriter(pw); chartWriter.writeChartGenerators( htmls, this::writeChartGeneratorBody, "document.getElementById('simpleStatusGraph').outerHTML=''", TIME_PER_TEST_CHART_ID); } protected ChartWriter getChartWriter(PrintWriter pw) { return new ChartWriter(pw); } protected static List filterByStatus(List htmls, String desiredStatus) { return filterBy(htmls, x -> desiredStatus.equals(x.getStatus())); } protected static List filterBy(List list, Predicate predicate) { return list.stream().filter(predicate).collect(Collectors.toList()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy