Skip to content

Commit

Permalink
[breaking] change driver target interface to take scenario-runtime
Browse files Browse the repository at this point in the history
to be more future-proof and allow for any suite / config to be introspected
  • Loading branch information
ptrthomas committed Mar 12, 2021
1 parent 9344dd5 commit 44e40a8
Show file tree
Hide file tree
Showing 21 changed files with 83 additions and 83 deletions.
6 changes: 3 additions & 3 deletions karate-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,9 @@ The [`configure driver`](#configure-driver) options are fine for testing on "`lo
```java
public interface Target {

Map<String, Object> start(com.intuit.karate.Logger logger);
Map<String, Object> start(com.intuit.karate.core.ScenarioRuntime sr);

Map<String, Object> stop(com.intuit.karate.Logger logger);
Map<String, Object> stop(com.intuit.karate.core.ScenarioRuntime sr);

}
```
Expand All @@ -415,7 +415,7 @@ public interface Target {

* `stop()`: Karate will call this method at the end of every top-level `Scenario` (that has not been `call`-ed by another `Scenario`).

If you use the provided `Logger` instance in your `Target` code, any logging you perform will nicely appear in-line with test-steps in the HTML report, which is great for troubleshooting or debugging tests.
If you use the provided `ScenarioRuntime.logger` instance in your `Target` code, any logging you perform will nicely appear in-line with test-steps in the HTML report, which is great for troubleshooting or debugging tests.

Combined with Docker, headless Chrome and Karate's [parallel-execution capabilities](https://github.com/intuit/karate#parallel-execution) - this simple `start()` and `stop()` lifecycle can effectively run web UI automation tests in parallel on a single node.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ public void driver(String exp) {
if (v.isMap()) {
options.putAll(v.getValue());
}
setDriver(DriverOptions.start(options, logger, runtime.getLogAppender()));
setDriver(DriverOptions.start(options, runtime));
}
if (v.isString()) {
driver.setUrl(v.getAsString());
Expand Down Expand Up @@ -934,7 +934,7 @@ public void stop(StepResult lastStepResult) {
}
if (options.target != null) {
logger.debug("custom target configured, attempting stop()");
Map<String, Object> map = options.target.stop(logger);
Map<String, Object> map = options.target.stop(runtime);
String video = (String) map.get("video");
embedVideo(video);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.intuit.karate.Logger;
import com.intuit.karate.RuntimeHook;
import com.intuit.karate.ScenarioActions;
import com.intuit.karate.Suite;
import com.intuit.karate.debug.DebugThread;
import com.intuit.karate.http.ResourceType;
import com.intuit.karate.shell.StringLogAppender;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.intuit.karate.FileUtils;
import com.intuit.karate.Logger;
import com.intuit.karate.StringUtils;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.shell.Command;
import java.io.File;
import java.util.Collections;
Expand Down Expand Up @@ -91,12 +92,12 @@ public Function<Integer, String> getCommand() {
}

@Override
public Map<String, Object> start(Logger logger) {
public Map<String, Object> start(ScenarioRuntime sr) {
if (command == null) {
throw new RuntimeException("docker target command (function) not set");
}
if (imageId != null && pull) {
logger.debug("attempting to pull docker image: {}", imageId);
sr.logger.debug("attempting to pull docker image: {}", imageId);
Command.execLine(null, "docker pull " + imageId);
}
int port = Command.getFreePort(0);
Expand All @@ -111,26 +112,29 @@ public Map<String, Object> start(Logger logger) {
Command.waitForHttp("http://127.0.0.1:" + port + "/json");
return map;
}



@Override
public Map<String, Object> stop(Logger logger) {
public Map<String, Object> stop(ScenarioRuntime sr) {
Command.execLine(null, "docker stop " + containerId);
if (!karateChrome) { // no video
Command.execLine(null, "docker rm " + containerId);
return Collections.EMPTY_MAP;
}
String shortName = containerId.contains("_") ? containerId : StringUtils.truncate(containerId, 12, false);
String dirName = "karate-chrome_" + shortName;
String resultsDir = Command.getBuildDir() + File.separator + dirName;
String dirName = "karate-chrome_" + shortName;
String buildDir = sr.featureRuntime.suite.buildDir;
String resultsDir = buildDir + File.separator + dirName;
Command.execLine(null, "docker cp " + containerId + ":/tmp " + resultsDir);
Command.execLine(null, "docker rm " + containerId);
String video = resultsDir + File.separator + "karate.mp4";
File file = new File(video);
if (!file.exists()) {
logger.warn("video file missing: {}", file);
sr.logger.warn("video file missing: {}", file);
return Collections.EMPTY_MAP;
}
File copy = new File(Command.getBuildDir() + File.separator + dirName + ".mp4");
File copy = new File(buildDir + File.separator + dirName + ".mp4");
FileUtils.copy(file, copy);
return Collections.singletonMap("video", "../" + copy.getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
*/
package com.intuit.karate.driver;

import com.intuit.karate.LogAppender;
import com.intuit.karate.Logger;
import com.intuit.karate.core.AutoDef;
import com.intuit.karate.core.Plugin;
import com.intuit.karate.core.Config;
Expand Down Expand Up @@ -52,10 +50,9 @@ public static Driver start(String browserType) {
}

public static Driver start(Map<String, Object> options) {
Logger logger = new Logger();
ScenarioRuntime runtime = FeatureRuntime.forTempUse().scenarios.next();
ScenarioEngine.set(runtime.engine);
return DriverOptions.start(options, logger, LogAppender.NO_OP);
return DriverOptions.start(options, runtime);
}

@AutoDef
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import com.intuit.karate.driver.playwright.PlaywrightDriver;
import com.intuit.karate.core.Config;
import com.intuit.karate.core.ScenarioEngine;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.shell.Command;

import java.io.File;
Expand Down Expand Up @@ -134,9 +135,9 @@ private <T> T get(String key, T defaultValue) {
return temp == null ? defaultValue : temp;
}

public DriverOptions(Map<String, Object> options, LogAppender appender, int defaultPort, String defaultExecutable) {
public DriverOptions(Map<String, Object> options, ScenarioRuntime sr, int defaultPort, String defaultExecutable) {
this.options = options;
this.appender = appender;
this.appender = sr.logAppender;
logger = new Logger(getClass());
logger.setAppender(appender);
timeout = get("timeout", Config.DEFAULT_TIMEOUT);
Expand Down Expand Up @@ -271,56 +272,56 @@ public Command startProcess(Consumer<String> listener) {
return command;
}

public static Driver start(Map<String, Object> options, Logger logger, LogAppender appender) { // TODO unify logger
public static Driver start(Map<String, Object> options, ScenarioRuntime sr) { // TODO unify logger
Target target = (Target) options.get("target");
if (target != null) {
logger.debug("custom target configured, calling start()");
Map<String, Object> map = target.start(logger);
logger.trace("custom target returned options: {}", map);
sr.logger.debug("custom target configured, calling start()");
Map<String, Object> map = target.start(sr);
sr.logger.trace("custom target returned options: {}", map);
options.putAll(map);
}
String type = (String) options.get("type");
if (type == null) {
logger.warn("type was null, defaulting to 'chrome'");
sr.logger.warn("type was null, defaulting to 'chrome'");
type = "chrome";
options.put("type", type);
}
try { // to make troubleshooting errors easier
switch (type) {
case "chrome":
return Chrome.start(options, appender);
return Chrome.start(options, sr);
case "msedge":
return EdgeChromium.start(options, appender);
return EdgeChromium.start(options, sr);
case "chromedriver":
return ChromeWebDriver.start(options, appender);
return ChromeWebDriver.start(options, sr);
case "geckodriver":
return GeckoWebDriver.start(options, appender);
return GeckoWebDriver.start(options, sr);
case "safaridriver":
return SafariWebDriver.start(options, appender);
return SafariWebDriver.start(options, sr);
case "msedgedriver":
return MsEdgeDriver.start(options, appender);
return MsEdgeDriver.start(options, sr);
case "mswebdriver":
return MsWebDriver.start(options, appender);
return MsWebDriver.start(options, sr);
case "iedriver":
return IeWebDriver.start(options, appender);
return IeWebDriver.start(options, sr);
case "winappdriver":
return WinAppDriver.start(options, appender);
return WinAppDriver.start(options, sr);
case "android":
return AndroidDriver.start(options, appender);
return AndroidDriver.start(options, sr);
case "ios":
return IosDriver.start(options, appender);
return IosDriver.start(options, sr);
case "playwright":
return PlaywrightDriver.start(options, appender);
return PlaywrightDriver.start(options, sr);
default:
logger.warn("unknown driver type: {}, defaulting to 'chrome'", type);
sr.logger.warn("unknown driver type: {}, defaulting to 'chrome'", type);
options.put("type", "chrome");
return Chrome.start(options, appender);
return Chrome.start(options, sr);
}
} catch (Exception e) {
String message = "driver config / start failed: " + e.getMessage() + ", options: " + options;
logger.error(message, e);
sr.logger.error(message, e);
if (target != null) {
target.stop(logger);
target.stop(sr);
}
throw new RuntimeException(message, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
package com.intuit.karate.driver;

import com.intuit.karate.Logger;
import com.intuit.karate.core.ScenarioRuntime;
import java.util.Map;

/**
Expand All @@ -32,8 +32,8 @@
*/
public interface Target {

Map<String, Object> start(Logger logger);
Map<String, Object> start(ScenarioRuntime sr);

Map<String, Object> stop(Logger logger);
Map<String, Object> stop(ScenarioRuntime sr);

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.intuit.karate.driver.appium;

import com.intuit.karate.FileUtils;
import com.intuit.karate.LogAppender;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.driver.DriverOptions;
import java.util.Map;

Expand All @@ -14,8 +14,8 @@ protected AndroidDriver(DriverOptions options) {
super(options);
}

public static AndroidDriver start(Map<String, Object> map, LogAppender appender) {
DriverOptions options = new DriverOptions(map, appender, 4723, FileUtils.isOsWindows() ? "cmd.exe" : "appium");
public static AndroidDriver start(Map<String, Object> map, ScenarioRuntime sr) {
DriverOptions options = new DriverOptions(map, sr, 4723, FileUtils.isOsWindows() ? "cmd.exe" : "appium");
// additional commands needed to start appium on windows
if (FileUtils.isOsWindows()){
options.arg("/C");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.intuit.karate.driver.appium;

import com.intuit.karate.LogAppender;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.driver.DriverOptions;
import java.util.Map;

Expand All @@ -13,8 +13,8 @@ public IosDriver(DriverOptions options) {
super(options);
}

public static IosDriver start(Map<String, Object> map, LogAppender appender) {
DriverOptions options = new DriverOptions(map, appender, 4723, "appium");
public static IosDriver start(Map<String, Object> map, ScenarioRuntime sr) {
DriverOptions options = new DriverOptions(map, sr, 4723, "appium");
options.arg("--port=" + options.port);
return new IosDriver(options);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import com.intuit.karate.FileUtils;
import com.intuit.karate.Http;
import com.intuit.karate.LogAppender;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.shell.Command;
import com.intuit.karate.driver.DevToolsDriver;
import com.intuit.karate.driver.DriverOptions;
Expand All @@ -49,8 +49,8 @@ public Chrome(DriverOptions options, Command command, String webSocketUrl) {
super(options, command, webSocketUrl);
}

public static Chrome start(Map<String, Object> map, LogAppender appender) {
DriverOptions options = new DriverOptions(map, appender, 9222,
public static Chrome start(Map<String, Object> map, ScenarioRuntime sr) {
DriverOptions options = new DriverOptions(map, sr, 9222,
FileUtils.isOsWindows() ? DEFAULT_PATH_WIN : FileUtils.isOsMacOsX() ? DEFAULT_PATH_MAC : DEFAULT_PATH_LINUX);
options.arg("--remote-debugging-port=" + options.port);
options.arg("--no-first-run");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
package com.intuit.karate.driver.chrome;

import com.intuit.karate.FileUtils;
import com.intuit.karate.LogAppender;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.driver.DriverOptions;
import com.intuit.karate.driver.WebDriver;
import com.intuit.karate.http.Response;
Expand All @@ -40,8 +40,8 @@ public ChromeWebDriver(DriverOptions options) {
super(options);
}

public static ChromeWebDriver start(Map<String, Object> map, LogAppender appender) {
DriverOptions options = new DriverOptions(map, appender, 9515, "chromedriver");
public static ChromeWebDriver start(Map<String, Object> map, ScenarioRuntime sr) {
DriverOptions options = new DriverOptions(map, sr, 9515, "chromedriver");
options.arg("--port=" + options.port);
if (options.userDataDir != null) {
options.arg("--user-data-dir=" + options.userDataDir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
package com.intuit.karate.driver.firefox;

import com.intuit.karate.FileUtils;
import com.intuit.karate.LogAppender;
import com.intuit.karate.Json;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.driver.DriverOptions;
import com.intuit.karate.driver.WebDriver;
import java.util.Map;
Expand All @@ -40,8 +40,8 @@ public GeckoWebDriver(DriverOptions options) {
super(options);
}

public static GeckoWebDriver start(Map<String, Object> map, LogAppender appender) {
DriverOptions options = new DriverOptions(map, appender, 4444, "geckodriver");
public static GeckoWebDriver start(Map<String, Object> map, ScenarioRuntime sr) {
DriverOptions options = new DriverOptions(map, sr, 4444, "geckodriver");
options.arg("--port=" + options.port);
return new GeckoWebDriver(options);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import com.intuit.karate.FileUtils;
import com.intuit.karate.Http;
import com.intuit.karate.LogAppender;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.driver.DevToolsDriver;
import com.intuit.karate.driver.DriverOptions;
import com.intuit.karate.http.Response;
Expand All @@ -50,11 +50,11 @@ public EdgeChromium(DriverOptions options, Command command, String webSocketUrl)
super(options, command, webSocketUrl);
}

public static EdgeChromium start(Map<String, Object> map, LogAppender appender) {
public static EdgeChromium start(Map<String, Object> map, ScenarioRuntime sr) {
if (!FileUtils.isOsWindows() && !FileUtils.isOsMacOsX()) {
throw new UnsupportedOperationException("edge browser is not yet available on linux!");
}
DriverOptions options = new DriverOptions(map, appender, 9222,
DriverOptions options = new DriverOptions(map, sr, 9222,
FileUtils.isOsWindows() ? DEFAULT_PATH_WIN : FileUtils.isOsMacOsX() ? DEFAULT_PATH_MAC : DEFAULT_PATH_LINUX);
options.arg("--remote-debugging-port=" + options.port);
options.arg("--no-first-run");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
package com.intuit.karate.driver.microsoft;

import com.intuit.karate.LogAppender;
import com.intuit.karate.core.ScenarioRuntime;
import com.intuit.karate.driver.DriverOptions;
import com.intuit.karate.driver.WebDriver;
import java.util.Map;
Expand All @@ -38,8 +38,8 @@ public IeWebDriver(DriverOptions options) {
super(options);
}

public static IeWebDriver start(Map<String, Object> map, LogAppender appender) {
DriverOptions options = new DriverOptions(map, appender, 5555, "IEDriverServer");
public static IeWebDriver start(Map<String, Object> map, ScenarioRuntime sr) {
DriverOptions options = new DriverOptions(map, sr, 5555, "IEDriverServer");
options.arg("port=" + options.port);
return new IeWebDriver(options);
}
Expand Down
Loading

0 comments on commit 44e40a8

Please sign in to comment.