package com.gorillalogic.monkeytalk.processor.report.detail;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.gorillalogic.monkeytalk.Command;
import com.gorillalogic.monkeytalk.CommandWorld;
import com.gorillalogic.monkeytalk.processor.PlaybackResult;
import com.gorillalogic.monkeytalk.processor.PlaybackStatus;
import com.gorillalogic.monkeytalk.processor.Scope;
import com.gorillalogic.monkeytalk.processor.ScriptType;
import com.gorillalogic.monkeytalk.processor.Step;
public class ScriptReportHelper {
public static String getXMLDetailReportFilename(String filename) {
return "DETAIL-" + filename + ".xml";
}
public static String getHTMLDetailReportFilename(String filename) {
return "DETAIL-" + filename + ".html";
}
public DetailReport createDetailReport(PlaybackResult result, Scope scope, File projectDir,
File reportDir) {
return createDetailReport(result, scope, projectDir, reportDir, null, null);
}
public DetailReport createDetailReport(PlaybackResult result, Scope scope, File projectDir,
File reportDir, String runnerVersion, String agentVersion) {
DetailReport report = new DetailReport();
report.setGenerated(new Date());
report.setRunner(runnerVersion);
report.setAgent(agentVersion);
if (projectDir != null) {
report.setProjectPath(projectDir.getAbsolutePath());
}
if (result != null) {
ReportTemplate contents = reportScriptSteps(result, scope, reportDir);
if (contents != null) {
List<ReportTemplate> steps = new ArrayList<ReportTemplate>();
steps.add(contents);
report.setSteps(steps);
} else {
String errMsg = "result: \'" + result + "' produced no detail report ";
System.out.println(errMsg);
// report.setMessage(errMsg);
}
} else {
String errMsg = "no detail report: no results were provided";
System.out.println(errMsg);
// report.setMessage(errMsg);
}
return report;
}
// only public for test use
public DetailReport createDetailReport(PlaybackResult result) {
return createDetailReport(result, null, null, null);
}
// only public for test use
public ReportTemplate reportScriptSteps(PlaybackResult scriptResult) {
return reportScriptSteps(scriptResult, null, null);
}
// only public for test use
public ReportTemplate reportScriptSteps(PlaybackResult scriptResult, Scope scope, File reportDir) {
if (scriptResult == null) {
return null;
}
if (scope == null) {
scope = scriptResult.getScope();
}
if (scriptResult.getSteps() == null || scriptResult.getSteps().size() == 0) {
// this was a single-step script
return reportSingleStepScript(scriptResult, scope, reportDir);
} else {
return reportSteps(new Step(createTopLevelCommand(scriptResult, scope), scriptResult,
scope, 0), reportDir);
}
}
protected Command createTopLevelCommand(PlaybackResult scriptResult, Scope scope) {
String monkeyId = "cannotDetermineScriptName";
String component = "Script";
if (scope != null) {
String filename = scope.getFilename();
if (filename != null && filename.length() > 0) {
monkeyId = filename;
if (filename.toLowerCase().endsWith(CommandWorld.SUITE_EXT)) {
component = "Suite";
} else if (scriptResult.getStatus().equals(PlaybackStatus.ERROR)
&& scriptResult.getMessage() != null
&& scriptResult.getMessage().contains(filename)
&& scriptResult.getMessage().contains(" as a suite")) {
component = "Suite";
}
}
}
return new Command(component + " \"" + monkeyId + "\" Run");
}
protected ReportTemplate reportSingleStepScript(PlaybackResult scriptResult, Scope scope,
File reportDir) {
PlaybackResult scriptInvocationResult = new PlaybackResult(scriptResult.getStatus());
scriptInvocationResult.setStartTime(scriptResult.getStartTime());
scriptInvocationResult.setStopTime(scriptResult.getStopTime());
scriptInvocationResult.setSteps(new ArrayList<Step>());
Command topLevelCommand = createTopLevelCommand(scriptResult, scope);
Command scriptCommand = null;
if (scope != null) {
scriptCommand = scope.getCurrentCommand();
}
if (scriptCommand == null) {
return reportSteps(new Step(topLevelCommand, scriptResult, scope, 0), reportDir);
} else {
Step topLevelStep = new Step(topLevelCommand, scriptInvocationResult, scope, 0);
scriptInvocationResult.getSteps().add(new Step(scriptCommand, scriptResult, scope, 0));
return reportSteps(topLevelStep, reportDir);
}
}
protected ReportTemplate reportSteps(Step step, File reportDir) {
return reportSteps(step, new Counter(), reportDir);
}
protected ReportTemplate reportSteps(Step step, Counter idx, File reportDir) {
ReportTemplate reportTemplate = null;
Command command = step.getCommand();
PlaybackResult result = step.getResult();
if (result == null || command == null) {
return null;
}
if (result.getSteps() == null || result.getSteps().size() == 0) {
if (isScriptCommand(command)) {
reportTemplate = new ScriptReport(command, result, idx.count++, reportDir);
} else {
// regular command
reportTemplate = new CommandReport(command, result, idx.count++, reportDir);
}
} else {
// Run or RunWith
ScriptReport scriptReport = new ScriptReport(step.getCommand(), step.getResult(),
idx.count++, reportDir);
List<ReportTemplate> subSteps = new ArrayList<ReportTemplate>();
scriptReport.setSteps(subSteps);
for (Step subStep : step.getResult().getSteps()) {
ReportTemplate report = reportSteps(subStep, idx, reportDir);
if (report != null) {
subSteps.add(report);
}
if (scriptReport.getType().equals(ScriptType.SUITE)) {
setSuiteCounts(scriptReport, subStep, report);
}
}
reportTemplate = scriptReport;
}
return reportTemplate;
}
protected boolean isScriptCommand(Command cmd) {
String comp = cmd.getComponentType();
if (comp != null) {
comp = comp.toLowerCase();
if (comp.equals(ScriptType.SCRIPT.toString())
|| comp.equals(ScriptType.SETUP.toString())
|| comp.equals(ScriptType.SUITE.toString())
|| comp.equals(ScriptType.TEARDOWN.toString())
|| comp.equals(ScriptType.TEST.toString())) {
return true;
}
}
return false;
}
private void setSuiteCounts(ScriptReport suiteReport, Step subStep, ReportTemplate report) {
if (suiteReport == null || subStep == null || report == null || subStep.getResult() == null
|| subStep.getCommand() == null) {
return;
}
PlaybackStatus status = subStep.getResult().getStatus();
try {
// capture results
if (status.equals(PlaybackStatus.FAILURE)) {
suiteReport
.setFailures(Integer.toString(Integer.parseInt(suiteReport.getFailures()) + 1));
} else if (status.equals(PlaybackStatus.ERROR)) {
suiteReport
.setErrors(Integer.toString(Integer.parseInt(suiteReport.getErrors()) + 1));
} else if (subStep.getCommand().isIgnored()) {
suiteReport
.setSkipped(Integer.toString(Integer.parseInt(suiteReport.getSkipped()) + 1));
}
// count tests
Command command = subStep.getCommand();
if (ScriptType.TEST.toString().toLowerCase()
.equals(command.getComponentType().toLowerCase())) {
if ("runwith".equals(command.getAction().toLowerCase())) {
// "Test script.mt RunWith data.csv", e.g.
if (command.getArgsAsString().matches(".*\\[@[0-9]+\\].*")) {
// an actual run
suiteReport.setTests(Integer.toString(Integer.parseInt(suiteReport
.getTests()) + 1));
} else {
if (subStep.getResult().getSteps() != null
&& subStep.getResult().getSteps().size() > 0) {
// get the nested Tests
CommandReport dummyReport = new CommandReport(null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null);
for (Step runWithStep : subStep.getResult().getSteps()) {
setSuiteCounts(suiteReport, runWithStep, dummyReport);
}
} else {
// a Test RunWith, but no sub-steps, probably an
// ERROR with the command
// itself
suiteReport.setTests(Integer.toString(Integer.parseInt(suiteReport
.getTests()) + 1));
}
}
} else {
// regular test
suiteReport
.setTests(Integer.toString(Integer.parseInt(suiteReport.getTests()) + 1));
}
}
// add counts from nested suites
if (report instanceof ScriptReport) {
ScriptReport nestedReport = (ScriptReport) report;
String comp = nestedReport.getComp().toLowerCase();
if (comp.equals(ScriptType.SUITE.toString().toLowerCase())) {
setSuiteCountsFromNestedSuite(suiteReport, nestedReport);
}
}
} catch (NumberFormatException e) {
System.out.println("SUITE report has non-integer test counts: "
+ suiteReport.getAttributes());
}
}
private void setSuiteCountsFromNestedSuite(ScriptReport suiteReport, ScriptReport nestedReport)
throws NumberFormatException {
suiteReport.setTests(Integer.toString(Integer.parseInt(suiteReport.getTests())
+ Integer.parseInt(nestedReport.getTests())));
suiteReport.setFailures(Integer.toString(Integer.parseInt(suiteReport.getFailures())
+ Integer.parseInt(nestedReport.getFailures())));
suiteReport.setErrors(Integer.toString(Integer.parseInt(suiteReport.getErrors())
+ Integer.parseInt(nestedReport.getErrors())));
suiteReport.setSkipped(Integer.toString(Integer.parseInt(suiteReport.getSkipped())
+ Integer.parseInt(nestedReport.getSkipped())));
}
private static class Counter {
public int count = 1;
}
}