package com.mumux.androidtesting.runner;
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import com.mumux.androidtesting.actions.Action;
import com.mumux.androidtesting.scenario.*;
import java.io.File;
import java.io.PrintStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Run Scenario pure java
* indepdently of Android
*/
public class ScenarioRunner {
private UiAutomatorTestCase uiAutomatorTestCase = null;
private final Runtime runtime;
private boolean deviceRooted = false;
private File outputDir = null;
private ScenarioParser scenarioParser = new TextScenarioParser();
private PrintStream out = null;
private void debug(String message) {
if (out != null) {
out.println(new Date() + "|" + message);
}
}
public ScenarioRunner(UiAutomatorTestCase uiAutomatorTestCase, Runtime runtime, boolean deviceRooted, File outputDir) {
this.uiAutomatorTestCase = uiAutomatorTestCase;
this.runtime = runtime;
this.deviceRooted = deviceRooted;
this.outputDir = outputDir;
}
void setScenarioParser(ScenarioParser scenarioParser) {
this.scenarioParser = scenarioParser;
}
public void setPrintStream(PrintStream out) {
this.out = out;
}
public ScenarioTestCase run(Reader reader, int index) {
return run(reader, null, index);
}
private ScenarioTestCase run(Reader reader, PrintStream out, int index) {
Scenario scenario;
// Parsing Scenario
try {
scenario = scenarioParser.parse(reader);
} catch (ScenarioParsingException e) {
ScenarioTestCase testCase2 = new ScenarioTestCase(e.scenarioName, TestStatus.ERROR);
testCase2.message = "Invalid Scenario - " + e.getMessage();
return testCase2;
}
// Pre-Run Check
if (scenario.isRootRequired() && !deviceRooted) {
ScenarioTestCase testCase2 = new ScenarioTestCase(scenario.name, TestStatus.ERROR);
testCase2.message = "Scenario requires a rooted device";
return testCase2;
}
// Run Scenario
TestStatus testStatus = TestStatus.SUCCESS;
List<ActionTestCase> actions = new ArrayList<>();
for (Action action : scenario.getActions()) {
actions.add(new ActionTestCase(action.toString()));
}
Long start = System.currentTimeMillis();
boolean continueTest = true;
File screenshotsDir = new File(outputDir, "scenario/" + index);
boolean status = screenshotsDir.mkdirs();
if (out != null && !status) {
out.println("Can not create directory " + screenshotsDir);
}
takeScreenshot(uiAutomatorTestCase.getUiDevice(), screenshotsDir, 0);
for (int i = 0; i < actions.size() && continueTest; i++) {
debug("Running " + scenario.getActions().get(i));
String error = scenario.getActions().get(i).run(uiAutomatorTestCase, runtime);
if (error == null) {
actions.get(i).status = TestStatus.SUCCESS;
debug("success");
uiAutomatorTestCase.getUiDevice().waitForIdle();
takeScreenshot(uiAutomatorTestCase.getUiDevice(), screenshotsDir, i + 1);
} else {
actions.get(i).message = error;
actions.get(i).status = TestStatus.FAILURE;
debug("failure - " + error);
if (!(scenario.getActions().get(i) instanceof OptionalAction)) {
continueTest = false;
testStatus = TestStatus.FAILURE;
}
}
}
ScenarioTestCase testCase = new ScenarioTestCase(scenario.name, testStatus);
testCase.actionTestCases = actions;
testCase.duration = System.currentTimeMillis() - start;
return testCase;
}
private static void takeScreenshot(UiDevice uiDevice, File outputDir, int step) {
File file = new File(outputDir, String.format("%03d.png", step));
System.err.println("take screenshot " + file);
uiDevice.takeScreenshot(file);
}
}