// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved. // Released under the terms of the CPL Common Public License version 1.0. package fitnesse.responders.run.formatters; import static fitnesse.responders.run.ExecutionResult.getExecutionResult; import java.io.IOException; import util.TimeMeasurement; import fitnesse.FitNesseContext; import fitnesse.html.HtmlTag; import fitnesse.html.HtmlUtil; import fitnesse.responders.run.ExecutionReport; import fitnesse.responders.run.ExecutionResult; import fitnesse.responders.run.TestPage; import fitnesse.responders.run.TestSummary; import fitnesse.responders.run.TestSystem; import fitnesse.wiki.PageCrawler; import fitnesse.wiki.PathParser; import fitnesse.wiki.WikiPage; import fitnesse.wiki.WikiPagePath; public abstract class SuiteHtmlFormatter extends InteractiveFormatter { private TestSummary pageCounts = new TestSummary(); private static final String TEST_SUMMARIES_ID = "test-summaries"; private int currentTest = 0; private String testSystemFullName = null; private boolean printedTestOutput = false; private int totalTests = 1; private TimeMeasurement latestTestTime; private String testSummariesId = TEST_SUMMARIES_ID; public SuiteHtmlFormatter(FitNesseContext context, WikiPage page) { super(context, page); } public SuiteHtmlFormatter(FitNesseContext context) { super(context, null); } @Override public void announceNumberTestsToRun(int testsToRun) { super.announceNumberTestsToRun(testsToRun); totalTests = (testsToRun != 0) ? testsToRun : 1; } public void announceStartNewTest(String relativeName, String fullPathName) { currentTest++; updateSummaryDiv(getProgressHtml(relativeName)); maybeWriteTestOutputDiv(); maybeWriteTestSystem(); writeTestOuputDiv(relativeName, fullPathName); } private void writeTestOuputDiv(String relativeName, String fullPathName) { HtmlTag pageNameBar = HtmlUtil.makeDivTag("test_output_name"); HtmlTag anchor = HtmlUtil.makeLink(fullPathName, relativeName); anchor.addAttribute("id", relativeName + currentTest); anchor.addAttribute("class", "test_name"); HtmlTag title = new HtmlTag("h3", anchor); HtmlTag topLink = HtmlUtil.makeLink("#" + TEST_SUMMARIES_ID, "Top"); topLink.addAttribute("class", "top_of_page"); pageNameBar.add(title); pageNameBar.add(topLink); writeData(pageNameBar.html()); writeData("<div class=\"alternating_block\">"); } private void maybeWriteTestOutputDiv() { if (!printedTestOutput) { HtmlTag outputTitle = new HtmlTag("h2", "Test Output"); writeData(outputTitle.html()); printedTestOutput = true; } } private void maybeWriteTestSystem() { if (testSystemFullName != null) { HtmlTag systemTitle = new HtmlTag("h2", String.format("Test System: %s", testSystemFullName)); writeData(systemTitle.html()); // once we write it out we don't need it any more testSystemFullName = null; } } @Override public void newTestStarted(TestPage testPage, TimeMeasurement timeMeasurement) throws IOException { super.newTestStarted(testPage, timeMeasurement); PageCrawler pageCrawler = getPage().getPageCrawler(); WikiPagePath fullPath = pageCrawler.getFullPath(testPage.getSourcePage()); String fullPathName = PathParser.render(fullPath); announceStartNewTest(getRelativeName(), fullPathName); } private String getProgressHtml(String relativeName) { float percentFinished = (currentTest - 1) * 1000 / totalTests; percentFinished = percentFinished / 10; String text = "Running tests ... (" + currentTest + "/" + totalTests + ")"; text = text.replaceAll(" ", " "); HtmlTag progressDiv = new HtmlTag("div", text); // need some results before we can check pageCounts for results ExecutionResult cssClass = (currentTest == 1) ? ExecutionResult.PASS : getExecutionResult(relativeName, this.pageCounts); progressDiv.addAttribute("id", "progressBar"); progressDiv.addAttribute("class", cssClass.toString()); progressDiv.addAttribute("style", "width:" + percentFinished + "%"); return progressDiv.html(); } public void processTestResults(String relativeName, TestSummary testSummary) throws IOException { finishOutputForTest(); getAssertionCounts().add(testSummary); HtmlTag tag = new HtmlTag("li"); tag.add(HtmlUtil.makeSpanTag("results " + getExecutionResult(relativeName, testSummary), testSummary.toString())); HtmlTag link = HtmlUtil.makeLink("#" + relativeName + currentTest, relativeName); link.addAttribute("class", "link"); tag.add(link); if (latestTestTime != null) { tag.add(HtmlUtil.makeSpanTag("", String.format("(%.03f seconds)", latestTestTime.elapsedSeconds()))); } pageCounts.tallyPageCounts(getExecutionResult(relativeName, testSummary, wasInterupted())); HtmlTag insertScript = HtmlUtil.makeAppendElementScript(testSummariesId, tag.html()); writeData(insertScript.html()); } private void finishOutputForTest() { writeData("</div>" + HtmlTag.endl); } @Override public void allTestingComplete(TimeMeasurement totalTimeMeasurement) throws IOException { latestTestTime = totalTimeMeasurement; removeStopTestLink(); publishAndAddLog(); finishWritingOutput(); close(); super.allTestingComplete(totalTimeMeasurement); } @Override public void testOutputChunk(String output) throws IOException { writeData(output); } @Override public void testComplete(TestPage testPage, TestSummary testSummary, TimeMeasurement timeMeasurement) throws IOException { super.testComplete(testPage, testSummary, timeMeasurement); latestTestTime = timeMeasurement; processTestResults(getRelativeName(testPage), testSummary); } @Override public void errorOccured() { latestTestTime = null; super.errorOccured(); } @Override public void testSystemStarted(TestSystem testSystem, String testSystemName, String testRunner) { testSystemFullName = (testSystemName + ":" + testRunner).replaceAll("\\\\", "/"); testSummariesId = "test-system-" + testSystemName; String tag = String.format("<h3>%s</h3>\n<ul id=\"%s\"></ul>", testSystemFullName, testSummariesId); HtmlTag insertScript = HtmlUtil.makeAppendElementScript(TEST_SUMMARIES_ID, tag); writeData(insertScript.html()); } protected String makeSummaryContent() { String summaryContent = "<strong>Test Pages:</strong> " + pageCounts.toString() + "     "; if (latestTestTime != null) { summaryContent += String.format("<strong>Assertions:</strong> %s (%.03f seconds)", getAssertionCounts(), latestTestTime.elapsedSeconds()); } else { summaryContent += String.format("<strong>Assertions:</strong> %s ", getAssertionCounts()); } return summaryContent; } @Override public void finishWritingOutput() throws IOException { writeData(testSummary()); super.finishWritingOutput(); } }