/* MonkeyTalk - a cross-platform functional testing tool
Copyright (C) 2012 Gorilla Logic, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package com.gorillalogic.monkeytalk.processor.report;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import com.gorillalogic.monkeytalk.Command;
import com.gorillalogic.monkeytalk.processor.PlaybackResult;
/**
* JUnit-compatible XML report generator for TestCase.
*/
public class Test implements IReport {
private String name;
private TestResult result;
private long startTime;
private long stopTime;
private String type;
private String message;
private String userdata;
private String trace;
private ArrayList<String> screenshots;
private PlaybackResult playbackResult;
private static final String SCREENSHOTS_DIR = "screenshots";
private static final DecimalFormat decimalFmt = new DecimalFormat("0.000");
private static final SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
/**
* Instantiate a new test with the given name, typically the name of the MonkeyTalk script.
*
* @param name
* the test name
*/
public Test(String name) {
this.name = name;
result = TestResult.OK;
startTime = 0;
stopTime = 0;
}
/**
* Get the name of the test, typically the name of the MonkeyTalk script.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Get the screenshot (as a base64 encoded string).
*
* @return the screenshot
*/
public String getScreenshot() {
return playbackResult.getImage();
}
/**
* Get the screenshots (as a base64 encoded strings).
*
* @return the screenshots
*/
public ArrayList<String> getScreenshots() {
return screenshots;
}
/**
* Get the screenshot filename.
*
* @return the screenshot filename
*/
public String getScreenshotFilename() {
return "screenshot_" + dateFmt.format(stopTime) + ".png";
}
/**
* Get the screenshot filename for count.
*
* @return the screenshot filename
*/
public String getScreenshotFilename(int count) {
return "screenshot_" + dateFmt.format(stopTime) + "_" + count + ".png";
}
/**
* Get the test result of a completed test.
*
* @return the test result
*/
public TestResult getResult() {
return result;
}
public String getUserdata() {
return userdata;
}
public void setUserdata(String userdata) {
this.userdata = userdata;
}
/**
* Start the test timer.
*/
public void startTimer() {
startTime = System.currentTimeMillis();
}
/**
* Stop the test timer.
*/
public void stopTimer() {
stopTime = System.currentTimeMillis();
}
/**
* Set the test result from the given {@link Command}, and {@link PlaybackResult}.
*
* @param cmd
* the MonkeyTalk command
* @param result
* the playback result
*/
public void setResult(Command cmd, PlaybackResult result) {
if (cmd != null)
userdata = cmd.getModifiers().get("userdata");
if (result == null) {
this.result = TestResult.OK;
} else {
this.playbackResult = result;
this.result = TestResult.getTestResultFromPlaybackStatus(result);
message = result.getMessage();
screenshots = result.getImages();
}
if (cmd != null) {
type = cmd.getCommandName();
trace = " at " + cmd;
}
if (result != null && result.getScope() != null) {
trace = result.getScope().getScopeTrace();
}
}
/**
* Compute the duration (in milliseconds).
*
* @return the duration
*/
public long getDuration() {
long delta = stopTime - startTime;
return (delta > 0 ? delta : 0);
}
/**
* Return the start time (in milliseconds).
*
* @return the start time
*/
public long getStartTime() {
return startTime;
}
/**
* Return the stop time (in milliseconds).
*
* @return the stop time
*/
public long getStopTime() {
return stopTime;
}
/**
* Compute the duration (in seconds), format it into a string with three decimals, and return
* it.
*
* @return the duration
*/
public String getDurationAsString() {
return decimalFmt.format(getDuration() / 1000.0);
}
@Override
public String toString() {
return toXML("\t");
}
/**
* Output the <code><testcase></code> tag, including any child <code><error></code> or
* <code><failure></code> tags.
*
* @param indent
* the indent string for the {@code testcase}
* @return the testcase xml
*/
public String toXML(String indent) {
StringBuilder sb = new StringBuilder();
sb.append(indent).append("<testcase");
sb.append(" name=\"").append(escapeXML(name)).append("\"");
sb.append(" starttime=\"").append(getStartTime()).append("\"");
sb.append(" stoptime=\"").append(getStopTime()).append("\"");
sb.append(" time=\"").append(getDurationAsString()).append("\"");
if (userdata != null && !userdata.trim().equalsIgnoreCase(""))
sb.append(" userdata=\"").append(escapeXML(userdata)).append("\"");
if (result == TestResult.OK) {
sb.append(" />");
} else {
sb.append(">\n").append(indent).append(indent);
sb.append("<" + result);
if (result == TestResult.SKIPPED) {
sb.append(" />");
} else {
if (message != null) {
String msg = message.replaceAll("\"", "'").replaceAll("\n", ": ")
.replaceAll("<", "(").replaceAll(">", ")");
sb.append(" message=\"").append(escapeXML(msg)).append("\"");
}
if (type != null) {
sb.append(" type=\"").append(escapeXML(type)).append("\"");
}
if (trace != null) {
String msg=message!=null?message.replaceAll("\"", "'"):"";
sb.append("><![CDATA[").append(msg).append('\n')
.append(trace).append("]]></").append(result).append(">");
} else {
sb.append(" />");
}
}
sb.append("\n").append(indent).append("</testcase>");
}
return sb.toString();
}
public String toHTML(int idx) {
String htlmResult = "";
String screenshotTemplate = "<li id=\"screenshot\">screenshot:<br /><img src=\"%1$s/%2$s\" title=\"%2$s\" /></li>";
String screenshotText = "";
String htmlMessage = "";
TestReportTemplate report = new TestReportTemplate("TestHtmlTemplate.html",
"/templates/TestHtmlTemplate.html");
if (result == TestResult.OK && message != null) {
htmlMessage = message;
}
if (result != TestResult.OK && trace != null) {
if (message==null) {
message="";
}
htmlMessage = message.replaceAll("\"", "'") + '\n' + trace;
}
if (hasScreenshot()) {
screenshotText = String.format(screenshotTemplate, SCREENSHOTS_DIR,
getScreenshotFilename());
}
try {
htlmResult = report.getContents("" + idx, name, result.toString(),
getDurationAsString(), htmlMessage, screenshotText);
} catch (IOException e) {
e.printStackTrace();
}
return htlmResult;
}
private boolean hasScreenshot() {
return playbackResult != null && playbackResult.getImageFile() != null;
}
private String escapeXML(String s) {
return com.gorillalogic.monkeytalk.processor.report.detail.XmlUtils.escapeXml(s);
}
}