package org.exigencecorp.selenify; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringEscapeUtils; public class ResultsParser { private final Pattern rowPattern = Pattern.compile("(?s)<tr.*?</tr>", Pattern.CASE_INSENSITIVE); private final Pattern testCasePattern = Pattern.compile("(?s)<b>([\\w-_\\.]+/?[\\w-_\\.]+)</b>", Pattern.CASE_INSENSITIVE); private final Pattern statusPattern = Pattern.compile("class=\"?(#?\\w+)\"?", Pattern.CASE_INSENSITIVE); private final Pattern commandArgsPattern = Pattern.compile("(?s)<td.*?>(.*?)</td>", Pattern.CASE_INSENSITIVE); private final Pattern originalHtmlPattern = Pattern.compile("originalhtml=\"(.*?)\"", Pattern.CASE_INSENSITIVE); public String toXml(String webappName, Map<String, String[]> parameters) { // In case the request didn't really come from selenium, don't NPE out if (parameters.get("numTestPasses") == null) { return null; } StringBuilder sb = new StringBuilder(); sb.append("<webapp>\n"); this.appendStats(sb, webappName, parameters); sb.append(" <tests>\n"); for (int i = 1; parameters.get("testTable." + i) != null; i++) { String table = parameters.get("testTable." + i)[0]; this.appendTest(sb, table); } sb.append(" </tests>\n"); sb.append("</webapp>\n"); return sb.toString(); } private void appendStats(StringBuilder sb, String webappName, Map<String, String[]> parameters) { sb.append(" " + this.createTag("name", webappName)); int passes = 0, failures = 0, ignores = 0; for (int i = 1; parameters.get("testTable." + i) != null; i++) { boolean testFailed = parameters.get("testTable." + i)[0].contains("status_failed"); boolean isIgnored = parameters.get("testTable." + i)[0].contains(".ignore"); if (isIgnored) { ignores++; } else if (testFailed) { failures++; } else { passes++; } } String result = (failures == 0) ? "passed" : "failed"; sb.append(" " + this.createTag("result", result)); sb.append(" " + this.createTag("passes", String.valueOf(passes))); sb.append(" " + this.createTag("failures", String.valueOf(failures))); sb.append(" " + this.createTag("ignores", String.valueOf(ignores))); sb.append(" " + this.createTag("time", parameters.get("totalTime")[0])); } private void appendTest(StringBuilder sb, String table) { Matcher testCaseMatcher = this.testCasePattern.matcher(table); String name = "Unknown"; if (testCaseMatcher.find()) { name = testCaseMatcher.group(1); } sb.append(" <test>\n"); sb.append(" <name>" + StringEscapeUtils.escapeXml(name) + "</name>\n"); sb.append(" <commands>\n"); Matcher rowMatcher = this.rowPattern.matcher(table); while (rowMatcher.find()) { String row = rowMatcher.group(); if (this.testCasePattern.matcher(row).find()) { continue; } String status = this.getStatus(row); String[] commandAndArgs = this.getCommandAndArgs(row); sb.append(" <command>\n"); sb.append(" <status>" + status + "</status>\n"); sb.append(" <name>" + StringEscapeUtils.escapeXml(commandAndArgs[0]) + "</name>\n"); sb.append(" <arg1>" + StringEscapeUtils.escapeXml(commandAndArgs[1]) + "</arg1>\n"); sb.append(" <arg2>" + StringEscapeUtils.escapeXml(commandAndArgs[2]) + "</arg2>\n"); sb.append(" <message>" + StringEscapeUtils.escapeXml(commandAndArgs[3]) + "</message>\n"); sb.append(" </command>\n"); } sb.append(" </commands>\n"); sb.append(" </test>\n"); } private String getStatus(String row) { Matcher statusMatcher = this.statusPattern.matcher(row); if (statusMatcher.find()) { String status = statusMatcher.group(1); if ("status_failed".equalsIgnoreCase(status)) { return "fail"; } else if ("status_done".equalsIgnoreCase(status)) { return "success"; } else { return "none"; } } return "none"; } private String[] getCommandAndArgs(String row) { String commandName = null; String arg1 = null; String arg2 = null; String message = null; Matcher commandArgsMatcher = this.commandArgsPattern.matcher(row); if (commandArgsMatcher.find(0)) { commandName = commandArgsMatcher.group(1); if (commandArgsMatcher.find(commandArgsMatcher.end())) { arg1 = commandArgsMatcher.group(1); if (commandArgsMatcher.find(commandArgsMatcher.end())) { message = commandArgsMatcher.group(1); } } } Matcher originalHtmlMatcher = this.originalHtmlPattern.matcher(row); if (originalHtmlMatcher.find()) { arg2 = StringEscapeUtils.unescapeHtml(originalHtmlMatcher.group(1)); } if (arg2 != null && arg2.equals(message)) { message = ""; } return new String[] { commandName, arg1, arg2, message }; } private String createTag(String tagName, String tagValue) { return "<" + tagName + ">" + StringEscapeUtils.escapeXml(tagValue) + "</" + tagName + ">\n"; } }