/* * Copyright (c) 2010-2011 Ardesco Solutions - http://www.ardescosolutions.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lazerycode.ebselen; import com.lazerycode.ebselen.handlers.FileHandler; import com.lazerycode.ebselen.handlers.XMLHandler; import com.lazerycode.ebselen.exceptions.InvalidReportFormatException; import com.lazerycode.ebselen.SeleniumTestAnnotations.suiteStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.net.URI; import java.net.URL; import java.util.*; import java.util.concurrent.TimeUnit; public class TestReports { public enum reportFormat { HTML, DOCX, ODF, DB } ResourceBundle _reporting = ResourceBundle.getBundle("ebselen"); private static final Logger logger = LoggerFactory.getLogger(TestReports.class); // Configuration settings private String outputDirectory; private reportFormat format; private final URI htmlTestTemplate = this.getClass().getResource("/templates/reportTemplate.html").toURI(); private final URI htmlCSSFile = this.getClass().getResource("/templates/testStyle.css").toURI(); // Data used to create report private String testSuiteName; private long suiteRunTime; private suiteStatus testSuiteStatus; // Not used in current revision, for CI really. private String testSuiteAuthor; private String[] associatedStories; private SortedMap<Integer, TestData> testData = new TreeMap<Integer, TestData>(); public TestReports() throws Exception { this.outputDirectory = _reporting.getString("outputDirectory"); setReportFormat(_reporting.getString("reportFormat")); } public final void setSuiteStatus(String value) { this.testSuiteStatus = suiteStatus.valueOf(value.toUpperCase()); } public final void setSuiteStatus(suiteStatus value) { this.testSuiteStatus = value; } public void setAssociatedStories(String[] value) { this.associatedStories = value; } public void setTestSuiteAuthor(String value) { this.testSuiteAuthor = value; } public void setTestSuiteName(String value) { this.testSuiteName = value; } public void setTestSuiteTime(long value) { this.suiteRunTime = value; } public void addTestData(int order, TestData data) { this.testData.put(order, data); } public final void setReportFormat(String value) throws InvalidReportFormatException { try { this.format = reportFormat.valueOf(value.toUpperCase()); } catch (Exception ex) { throw new InvalidReportFormatException("Report format '" + value + "' not recognised!"); } } public final void setReportFormat(reportFormat value) { this.format = value; } public final void setOutputDirectory(String value) { this.outputDirectory = value; } /** * Format time as "x min, x sec" * * @param timestamp - Timestamp to format as a String * @return String - Formatted as "x min, x sec" */ public String formattedTime(long timestamp) { return String.format("%d min(s), %d sec(s)", TimeUnit.MILLISECONDS.toMinutes(timestamp), TimeUnit.MILLISECONDS.toSeconds(timestamp) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timestamp))); } /** * Create test reports * * @throws Exception */ public boolean createReport() { try { switch (this.format) { case HTML: { createHTMLReport(); break; } case DOCX: { createDOCXReport(); break; } case ODF: { createODFReport(); break; } case DB: { createODFReport(); break; } } } catch (Exception e) { logger.error("Failed to create report: " + e); return false; } return true; } /** * Create an DOCX format report of the test run */ private void createDOCXReport() { logger.info("Not implemented yet!"); } /** * Create an ODF format report of the test run */ private void createODFReport() { logger.info("Not implemented yet!"); } /** * Create an HTML format report of the test run * * @throws Exception */ private void createHTMLReport() throws Exception { String overallResult = "Pass"; XMLHandler testResults = new XMLHandler(new File(this.htmlTestTemplate)); // Populate the "test name" field testResults.addTextToElement(this.testSuiteName, "//p[@id='name']/span"); // Populate the "Author(s)" field testResults.addTextToElement(this.testSuiteAuthor, "//p[@id='author']/span"); // Populate "stories covered" field String stories = ""; for (String story : this.associatedStories) { stories = stories.concat(story).concat(", "); } stories = stories.trim().substring(0, stories.length() - 2); testResults.addTextToElement(stories, "//p[@id='story']/span"); // Populate "total suite time" field testResults.addTextToElement(formattedTime(this.suiteRunTime), "//p[@id='time']/span"); // Build the test results table Iterator test = this.testData.entrySet().iterator(); int rowNumber = 0; while (test.hasNext()) { Map.Entry pairs = (Map.Entry) test.next(); testResults.addChildElement("tr", "//table[@id='testResults']/tbody"); rowNumber++; TestData individualTestResults = (TestData) pairs.getValue(); testResults.addChildElement("td", "//table[@id='testResults']/tbody/tr[" + rowNumber + "]"); testResults.addTextToElement(individualTestResults.getTestName(), "//table[@id='testResults']/tbody/tr[" + rowNumber + "]/td[1]"); testResults.addChildElement("td", "//table[@id='testResults']/tbody/tr[" + rowNumber + "]"); testResults.addTextToElement(Integer.valueOf(individualTestResults.getFailures()).toString(), "//table[@id='testResults']/tbody/tr[" + rowNumber + "]/td[2]"); String result = ""; if (individualTestResults.getFailures() == 0) { result = "Pass"; } else { result = "Fail"; overallResult = "Fail"; } testResults.addAttribute("class", result.toLowerCase(), "//table[@id='testResults']/tbody/tr[" + rowNumber + "]"); testResults.addChildElement("td", "//table[@id='testResults']/tbody/tr[" + rowNumber + "]"); testResults.addTextToElement(result, "//table[@id='testResults']/tbody/tr[" + rowNumber + "]/td[3]"); testResults.addChildElement("td", "//table[@id='testResults']/tbody/tr[" + rowNumber + "]"); testResults.addTextToElement(formattedTime(individualTestResults.getTimeTaken()), "//table[@id='testResults']/tbody/tr[" + rowNumber + "]/td[4]"); } // Populate the "overall result" field testResults.addTextToElement(overallResult, "//h2[@id='overallResult']/span"); testResults.addAttribute("class", overallResult.toLowerCase(), "//h2[@id='overallResult']/span"); // Print HTML results page location logger.info("Test report available at {}", testResults.writeXMLFile(this.outputDirectory + this.testSuiteName.concat(".html"))); FileHandler cssStyle = new FileHandler(new File(this.htmlCSSFile)); cssStyle.copyFileTo(this.outputDirectory + cssStyle.getFileName()); } }