/** * Copyright WebGate Consulting AG, 2014 * * 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 org.openntf.junit.xsp.renderkit.html_extended; import java.io.IOException; import javax.faces.FacesException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import org.openntf.junit.xsp.component.UITestsuite; import org.openntf.junit.xsp.junit4.XSPTestRunner; import org.openntf.junit.xsp.junit4.report.TestEntry; import org.openntf.junit.xsp.junit4.report.TestEntry.TestStatus; import org.openntf.junit.xsp.junit4.report.XSPResult; import org.openntf.junit.xsp.junit4.report.XSPTestSuite; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.component.UIScriptCollector; import com.ibm.xsp.renderkit.FacesRenderer; public class TestSuiteRenderer extends FacesRenderer { @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { if (component instanceof UITestsuite && component.isRendered()) { UIScriptCollector sc = UIScriptCollector.find(); sc.addScriptOnce(buildJSCode()); UITestsuite testsuite = (UITestsuite) component; XSPTestSuite testResult = runTests(testsuite); buildResultTable(context, testsuite, testResult); } } private XSPTestSuite runTests(UITestsuite testsuite) { try { return XSPTestRunner.testClassesAsSuite(testsuite.getAllTestClasses()); } catch (ClassNotFoundException e) { throw new FacesException("Errro during runTests", e); } } private void buildResultTable(FacesContext context, UITestsuite testsuite, XSPTestSuite testResult) throws IOException { ResponseWriter rw = context.getResponseWriter(); String id = testsuite.getClientId(context); rw.startElement("div", testsuite); rw.writeAttribute("id", id, null); writeSummary( rw, id, testsuite, testResult); writeResults(rw, id, testsuite, testResult); rw.endElement("div"); } private void writeSummary(ResponseWriter rw, String id, UITestsuite testsuite, XSPTestSuite testResult) throws IOException { rw.startElement("table", testsuite); rw.writeAttribute("id", id + "_summary", null); rw.writeAttribute("class", "lotusTable", null); rw.startElement("tr", testsuite); rw.writeAttribute("class", "lotusFirst", null); writeTD(rw, testsuite, "lotusFirstCell", "Tests: " + testResult.getTests(), "120px"); writeIconTD(rw, TestStatus.ERROR, ""); writeTD(rw, testsuite, null, "Errors: " + testResult.getErrros(), "120px"); writeIconTD(rw, TestStatus.FAILURE, ""); writeTD(rw, testsuite, null, "Failures: " + testResult.getFailures(), "120px"); if (testResult.getErrros() + testResult.getFailures() > 0) { writeTDRED(rw, testsuite, "lotusLastCell"); } else { writeTDGREEN(rw, testsuite, "lotusLastCell"); } rw.endElement("tr"); rw.endElement("table"); } private void writeTD(ResponseWriter rw, UITestsuite testsuite, String uiClass, String content, String width) throws IOException { rw.startElement("td", testsuite); if (!StringUtil.isEmpty(uiClass)) { rw.writeAttribute("class", uiClass, null); } if (!StringUtil.isEmpty(width)) { rw.writeAttribute("width", width, null); } rw.writeText(content, null); rw.endElement("td"); } private void writeTD(ResponseWriter rw, UITestsuite testsuite, String uiClass, String content) throws IOException { writeTD(rw, testsuite, uiClass, content, null); } private void writeTDRED(ResponseWriter rw, UITestsuite testsuite, String uiClass) throws IOException { rw.startElement("td", testsuite); if (!StringUtil.isEmpty(uiClass)) { rw.writeAttribute("class", uiClass, null); } rw.writeAttribute("bgcolor", "red", null); rw.endElement("td"); } private void writeTDGREEN(ResponseWriter rw, UITestsuite testsuite, String uiClass) throws IOException { rw.startElement("td", testsuite); if (!StringUtil.isEmpty(uiClass)) { rw.writeAttribute("class", uiClass, null); } rw.writeAttribute("bgcolor", "green", null); rw.endElement("td"); } private void writeResults( ResponseWriter rw, String id, UITestsuite testsuite, XSPTestSuite testResult) throws IOException { int nCounter = 0; for (XSPResult testcase : testResult.getResults()) { String idSub = id + "_tc_" + nCounter; writeResultSummary(rw, idSub + "_details", testsuite, testcase); writeDetailResults( rw, idSub + "_details", testcase); writeSystemOut( rw, idSub + "_sysout", testcase); nCounter++; } } private void writeResultSummary(ResponseWriter rw, String id, UITestsuite testsuite, XSPResult testcase) throws IOException { rw.startElement("table", null); rw.writeAttribute("style", "margin-top:44px;", null); rw.writeAttribute("class", "lotusTable", null); rw.startElement("tr", null); rw.writeAttribute("class", "lotusFirst", null); writeIconTD(rw, getTestStatus(testcase), "lotusFirstCell"); rw.startElement("td", null); rw.startElement("h2", null); rw.writeAttribute("class", "lotusTitle", null); rw.startElement("a", null); rw.writeAttribute("onclick", buildOnClickCall(id), null); rw.writeText(testcase.getTestClassName(), null); rw.endElement("a"); rw.endElement("h2"); rw.endElement("td"); writeTD(rw, testsuite, "lotusAlignRight lotusLastCell", "(Tests: " + testcase.getRunCount() + ", Errors: " + testcase.getErrorCount() + ", Failures: " + testcase.getFailureCount() + ", Time: " + testcase.getTime() + " ms)"); rw.endElement("tr"); rw.endElement("table"); } private TestStatus getTestStatus(XSPResult testcase) { if (testcase.getErrorCount() > 0) { return TestStatus.ERROR; } if (testcase.getFailureCount() > 0) { return TestStatus.FAILURE; } // TODO Auto-generated method stub return TestStatus.SUCCESS; } private void writeDetailResults(ResponseWriter rw, String idSub, XSPResult testcase) throws IOException { rw.startElement("div", null); if (getTestStatus(testcase) == TestStatus.SUCCESS) { rw.writeAttribute("style", "margin-left:20px;display:none", null); } else { rw.writeAttribute("style", "margin-left:20px", null); } rw.writeAttribute("id", idSub, null); rw.startElement("table", null); rw.writeAttribute("id", idSub + "_table", null); rw.writeAttribute("class", "lotusTable", null); int nCounter = 0; for (TestEntry entry : testcase.getTestEntries()) { String entryID = idSub + "_" + nCounter; rw.startElement("tr", null); writeIconTD(rw, entry.getStatus(), "lotusFirstCell"); writeTD(rw, null, "", entry.getMethodName()); writeTD(rw, null, "lotusAlignRight lotusLastCell", buildDurationString(entry)); rw.endElement("tr"); writeFailureInfos(rw, entryID, entry); nCounter++; } rw.endElement("table"); rw.endElement("div"); } private void writeFailureInfos(ResponseWriter rw, String entryID, TestEntry entry) throws IOException { if (entry.getStatus() != TestStatus.SUCCESS) { rw.startElement("tr", null); rw.writeAttribute("class", "lotusDetails", null); rw.startElement("td", null); rw.writeAttribute("width", "20px", null); rw.endElement("td"); rw.startElement("td", null); rw.writeAttribute("colspan", "2", null); rw.startElement("p", null); if (entry.getStatus() == TestStatus.ERROR) { rw.writeText(entry.getErrorType() + " / " + entry.getErrorMessage(), null); } else { rw.writeText(entry.getFailureType() + " / " + entry.getFailureMessage(), null); } rw.endElement("p"); rw.startElement("a", null); rw.writeAttribute("onclick", buildOnClickCall(entryID), null); rw.writeText("Details (show / hide)", null); rw.endElement("a"); rw.startElement("br", null); rw.endElement("br"); rw.startElement("div", null); rw.writeAttribute("id", entryID, null); rw.writeAttribute("style", "display:none", null); if (entry.getStatus() == TestStatus.ERROR) { rw.write(entry.getErrorTrace().replace(System.getProperty("line.separator"), "<br/>\n")); } else { rw.write(entry.getFailureTrace().replace(System.getProperty("line.separator"), "<br/>\n")); } rw.endElement("div"); rw.endElement("td"); rw.endElement("tr"); } } private String buildOnClickCall(String entryID) { return "junitDetailToggle('" + entryID + "')"; } private String buildDurationString(TestEntry entry) { return entry.getTestDuration() + " ms"; } private void writeIconTD(ResponseWriter rw, TestStatus status, String cssClass) throws IOException { rw.startElement("td", null); rw.writeAttribute("width", "20px", null); if (!StringUtil.isEmpty(cssClass)) { rw.writeAttribute("class", cssClass, null); } rw.startElement("img", null); rw.writeAttribute("src", status.getICONUrl(), null); rw.endElement("img"); rw.endElement("td"); } private void writeSystemOut(ResponseWriter rw, String idSub, XSPResult testcase) throws IOException { rw.startElement("div", null); rw.writeAttribute("style", "margin-left:20px", null); rw.startElement("a", null); rw.writeAttribute("onclick", buildOnClickCall(idSub), null); rw.writeText("SystemOut / SytemError (show / hide)", null); rw.endElement("a"); rw.startElement("br", null); rw.endElement("br"); rw.startElement("div", null); rw.writeAttribute("style", "display:none;margin-left:5px", null); rw.writeAttribute("id", idSub, null); rw.write("System.Out</br>"); rw.write(testcase.getSystemOut().replace(System.getProperty("line.separator"), "<br/>\n")); rw.write("<br/><br/>System.Err</br>"); rw.write(testcase.getSystemErr().replace(System.getProperty("line.separator"), "<br/>\n")); rw.endElement("div"); rw.endElement("div"); } private String buildJSCode() { StringBuilder sb = new StringBuilder(); sb.append("function junitDetailToggle( id ) {"); sb.append("var div = document.getElementById(id);"); sb.append("if (div.style.display !== 'none') {"); sb.append("div.style.display = 'none';"); sb.append("} else {"); sb.append(" div.style.display = 'block';"); sb.append("}"); sb.append("}"); return sb.toString(); } }