1package org.testng.reporters.jq; 2 3import org.testng.ISuite; 4import org.testng.ISuiteResult; 5import org.testng.ITestContext; 6import org.testng.ITestResult; 7import org.testng.collections.Lists; 8import org.testng.reporters.XMLStringBuffer; 9 10import java.util.Collections; 11import java.util.List; 12import java.util.Map; 13 14public class NavigatorPanel extends BasePanel { 15 16 private List<INavigatorPanel> m_panels; 17 18 public NavigatorPanel(Model model, List<INavigatorPanel> panels) { 19 super(model); 20 m_panels = panels; 21 } 22 23 @Override 24 public void generate(XMLStringBuffer main) { 25 main.push(D, C, "navigator-root"); 26 main.push(D, C, "navigator-suite-header"); 27 main.addRequired(S, "All suites"); 28 main.push("a", C, "collapse-all-link", "href", "#", "title", "Collapse/expand all the suites"); 29 main.push("img", "src", "collapseall.gif", C, "collapse-all-icon"); 30 main.pop("img"); 31 main.pop("a"); 32 main.pop(D); 33 for (ISuite suite : getSuites()) { 34 if (suite.getResults().size() == 0) { 35 continue; 36 } 37 38 String suiteName = "suite-" + suiteToTag(suite); 39 40 XMLStringBuffer header = new XMLStringBuffer(main.getCurrentIndent()); 41 42 Map<String, ISuiteResult> results = suite.getResults(); 43 int failed = 0; 44 int skipped = 0; 45 int passed = 0; 46 for (ISuiteResult result : results.values()) { 47 ITestContext context = result.getTestContext(); 48 failed += context.getFailedTests().size(); 49 skipped += context.getSkippedTests().size(); 50 passed += context.getPassedTests().size(); 51 } 52 53 // Suite name in big font 54 header.push(D, C, "suite"); 55 header.push(D, C, "rounded-window"); 56 // Extra div so the highlighting logic will only highlight this line and not 57 // the entire container 58 header.push(D, C, "suite-header light-rounded-window-top"); 59 header.push("a", "href", "#", 60 "panel-name", suiteName, 61 C, "navigator-link"); 62 header.addOptional(S, suite.getName(), 63 C, "suite-name border-" + getModel().getStatusForSuite(suite.getName())); 64 header.pop("a"); 65 header.pop(D); 66 67 header.push(D, C, "navigator-suite-content"); 68 69 generateInfo(header, suite); 70 generateResult(header, failed, skipped, passed, suite, suiteName); 71 72 header.pop("ul"); 73 74 header.pop(D); // suite-section-content 75 header.pop(D); // suite-header 76 header.pop(D); // suite 77 78 header.pop(D); // result-section 79 80 header.pop(D); // navigator-suite-content 81 82 main.addString(header.toXML()); 83 } 84 main.pop(D); 85 } 86 87 private void generateResult(XMLStringBuffer header, int failed, int skipped, int passed, 88 ISuite suite, String suiteName) { 89 // 90 // Results 91 // 92 header.push(D, C, "result-section"); 93 94 header.push(D, C, "suite-section-title"); 95 header.addRequired(S, "Results"); 96 header.pop(D); 97 98 // Method stats 99 int total = failed + skipped + passed; 100 String stats = String.format("%s, %s %s %s", 101 pluralize(total, "method"), 102 maybe(failed, "failed", ", "), 103 maybe(skipped, "skipped", ", "), 104 maybe(passed, "passed", "")); 105 header.push(D, C, "suite-section-content"); 106 header.push("ul"); 107 header.push("li"); 108 header.addOptional(S, stats, C, "method-stats"); 109 header.pop("li"); 110 111 generateMethodList("Failed methods", new ResultsByStatus(suite, "failed", ITestResult.FAILURE), 112 suiteName, header); 113 generateMethodList("Skipped methods", new ResultsByStatus(suite, "skipped", ITestResult.SKIP), 114 suiteName, header); 115 generateMethodList("Passed methods", new ResultsByStatus(suite, "passed", ITestResult.SUCCESS), 116 suiteName, header); 117 } 118 119 private void generateInfo(XMLStringBuffer header, ISuite suite) { 120 // 121 // Info 122 // 123 header.push(D, C, "suite-section-title"); 124 header.addRequired(S, "Info"); 125 header.pop(D); 126 127 header.push(D, C, "suite-section-content"); 128 129 header.push("ul"); 130 131 // All the panels 132 for (INavigatorPanel panel : m_panels) { 133 addLinkTo(header, panel, suite); 134 } 135 136 header.pop("ul"); 137 header.pop(D); // suite-section-content 138 } 139 140 private void addLinkTo(XMLStringBuffer header, INavigatorPanel panel, ISuite suite) { 141 String text = panel.getNavigatorLink(suite); 142 header.push("li"); 143 header.push("a", "href", "#", 144 "panel-name", panel.getPanelName(suite), 145 C, "navigator-link "); 146 String className = panel.getClassName(); 147 if (className != null) { 148 header.addOptional(S, text, C, className); 149 } else { 150 header.addOptional(S, text); 151 } 152 header.pop("a"); 153 header.pop("li"); 154 } 155 156 private static String maybe(int count, String s, String sep) { 157 return count > 0 ? count + " " + s + sep: ""; 158 } 159 160 private List<ITestResult> getMethodsByStatus(ISuite suite, int status) { 161 List<ITestResult> result = Lists.newArrayList(); 162 List<ITestResult> testResults = getModel().getTestResults(suite); 163 for (ITestResult tr : testResults) { 164 if (tr.getStatus() == status) { 165 result.add(tr); 166 } 167 } 168 Collections.sort(result, ResultsByClass.METHOD_NAME_COMPARATOR); 169 170 return result; 171 } 172 173 private static interface IResultProvider { 174 List<ITestResult> getResults(); 175 String getType(); 176 } 177 178 private abstract static class BaseResultProvider implements IResultProvider { 179 protected ISuite m_suite; 180 protected String m_type; 181 public BaseResultProvider(ISuite suite, String type) { 182 m_suite = suite; 183 m_type = type; 184 } 185 186 @Override 187 public String getType() { 188 return m_type; 189 } 190 } 191 192 private class ResultsByStatus extends BaseResultProvider { 193 private final int m_status; 194 195 public ResultsByStatus(ISuite suite, String type, int status) { 196 super(suite, type); 197 m_status = status; 198 } 199 200 @Override 201 public List<ITestResult> getResults() { 202 return getMethodsByStatus(m_suite, m_status); 203 } 204 } 205 206 private void generateMethodList(String name, IResultProvider provider, 207 String suiteName, XMLStringBuffer main) { 208 XMLStringBuffer xsb = new XMLStringBuffer(main.getCurrentIndent()); 209 String type = provider.getType(); 210 String image = Model.getImage(type); 211 212 xsb.push("li"); 213 214 // The methods themselves 215 xsb.addRequired(S, name, C, "method-list-title " + type); 216 217 // The mark up to show the (hide)/(show) links 218 xsb.push(S, C, "show-or-hide-methods " + type); 219 xsb.addRequired("a", " (hide)", "href", "#", C, "hide-methods " + type + " " + suiteName, 220 "panel-name", suiteName); 221 xsb.addRequired("a", " (show)", "href", "#",C, "show-methods " + type + " " + suiteName, 222 "panel-name", suiteName); 223 xsb.pop(S); 224 225 // List of methods 226 xsb.push(D, C, "method-list-content " + type + " " + suiteName); 227 int count = 0; 228 List<ITestResult> testResults = provider.getResults(); 229 if (testResults != null) { 230 Collections.sort(testResults, ResultsByClass.METHOD_NAME_COMPARATOR); 231 for (ITestResult tr : testResults) { 232 String testName = Model.getTestResultName(tr); 233 xsb.push(S); 234 xsb.addEmptyElement("img", "src", image, "width", "3%"); 235 xsb.addRequired("a", testName, "href", "#", 236 "hash-for-method", getModel().getTag(tr), 237 "panel-name", suiteName, 238 "title", tr.getTestClass().getName(), 239 C, "method navigator-link"); 240 xsb.pop(S); 241 xsb.addEmptyElement("br"); 242 count++; 243 } 244 } 245 xsb.pop(D); 246 xsb.pop("li"); 247 248 if (count > 0) { 249 main.addString(xsb.toXML()); 250 } 251 } 252 253} 254