| diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java b/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java |
| index ac7da88826..7b251ed038 100644 |
| --- a/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java |
| +++ b/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java |
| @@ -77,6 +77,9 @@ |
| public static final String CAPABILITY = "goog:chromeOptions"; |
| |
| private String binary; |
| + private String androidPackage; |
| + private String androidActivity; |
| + private String androidProcess; |
| private List<String> args = new ArrayList<>(); |
| private List<File> extensionFiles = new ArrayList<>(); |
| private List<String> extensions = new ArrayList<>(); |
| @@ -116,6 +119,36 @@ public ChromeOptions setBinary(String path) { |
| return this; |
| } |
| |
| + /** |
| + * Sets the Android package name for Chrome or a WebView app. The package should already exist |
| + * on the Android device. |
| + * |
| + * @param package_name Package name for Chrome or a WebView app |
| + */ |
| + public void setAndroidPackage(String package_name) { |
| + androidPackage = checkNotNull(package_name); |
| + } |
| + |
| + /** |
| + * Sets the name of the Activity hosting the WebView under test. |
| + * |
| + * @param package_name Android Activity class name |
| + */ |
| + public void setAndroidActivity(String activity_name) { |
| + androidActivity = checkNotNull(activity_name); |
| + } |
| + |
| + /** |
| + * Sets the process name for the Activity hosting the WebView under test. |
| + * |
| + * @param package_name Android process name |
| + */ |
| + public void setAndroidProcess(String process_name) { |
| + androidProcess = checkNotNull(process_name); |
| + } |
| + |
| + /** |
| + |
| /** |
| * @param arguments The arguments to use when starting Chrome. |
| * @see #addArguments(java.util.List) |
| diff --git a/java/client/test/org/openqa/selenium/environment/webserver/JettyAppServer.java b/java/client/test/org/openqa/selenium/environment/webserver/JettyAppServer.java |
| index ddbb694986..94a7fc6ee1 100644 |
| --- a/java/client/test/org/openqa/selenium/environment/webserver/JettyAppServer.java |
| +++ b/java/client/test/org/openqa/selenium/environment/webserver/JettyAppServer.java |
| @@ -113,10 +113,6 @@ public JettyAppServer(String hostName, int httpPort, int httpsPort) { |
| |
| ServletContextHandler defaultContext = addResourceHandler( |
| DEFAULT_CONTEXT_PATH, locate("common/src/web")); |
| - ServletContextHandler jsContext = addResourceHandler( |
| - JS_SRC_CONTEXT_PATH, locate("javascript")); |
| - addResourceHandler(CLOSURE_CONTEXT_PATH, locate("third_party/closure/goog")); |
| - addResourceHandler(THIRD_PARTY_JS_CONTEXT_PATH, locate("third_party/js")); |
| |
| TemporaryFilesystem tempFs = TemporaryFilesystem.getDefaultTmpFS(); |
| tempPageDir = tempFs.createTempDir("pages", "test"); |
| diff --git a/java/client/test/org/openqa/selenium/testing/JUnit4TestBase.java b/java/client/test/org/openqa/selenium/testing/JUnit4TestBase.java |
| index a98433d608..7bcb1dd0eb 100644 |
| --- a/java/client/test/org/openqa/selenium/testing/JUnit4TestBase.java |
| +++ b/java/client/test/org/openqa/selenium/testing/JUnit4TestBase.java |
| @@ -36,6 +36,7 @@ |
| import org.junit.runners.model.Statement; |
| import org.openqa.selenium.Pages; |
| import org.openqa.selenium.WebDriver; |
| +import org.openqa.selenium.WebDriverException; |
| import org.openqa.selenium.environment.GlobalTestEnvironment; |
| import org.openqa.selenium.environment.InProcessTestEnvironment; |
| import org.openqa.selenium.environment.TestEnvironment; |
| @@ -241,6 +242,29 @@ private void createDriver() { |
| |
| public static WebDriver actuallyCreateDriver() { |
| WebDriver driver = storedDriver.get(); |
| + // If the driver is left in a bad state, create a new one. |
| + // This happens on Android after any test that creates its own driver. |
| + // Since only one instance of Chrome can run on Android at a time, the |
| + // stored driver's browser is destroyed. |
| + try |
| + { |
| + if (driver != null) |
| + { |
| + driver.getCurrentUrl(); |
| + } |
| + } |
| + catch (WebDriverException e) |
| + { |
| + try |
| + { |
| + driver.quit(); |
| + } |
| + catch (RuntimeException ignored) |
| + { |
| + System.exit(1); |
| + } |
| + driver = null; |
| + } |
| |
| if (driver == null || |
| (driver instanceof RemoteWebDriver && ((RemoteWebDriver)driver).getSessionId() == null)) { |
| diff --git a/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java b/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java |
| index 2e1cd280a7..8ff03146bd 100644 |
| --- a/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java |
| +++ b/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java |
| @@ -59,12 +59,9 @@ public TestChromeDriver(Capabilities capabilities) throws IOException { |
| |
| private static URL getServiceUrl() throws IOException { |
| if (service == null && !SauceDriver.shouldUseSauce()) { |
| - Path logFile = Files.createTempFile("chromedriver", ".log"); |
| service = new ChromeDriverService.Builder() |
| .withVerbose(true) |
| - .withLogFile(logFile.toFile()) |
| .build(); |
| - LOG.info("chromedriver will log to " + logFile); |
| try { |
| service.start(); |
| } catch (IOException e) { |
| @@ -80,15 +77,40 @@ private static URL getServiceUrl() throws IOException { |
| private static Capabilities chromeWithCustomCapabilities(Capabilities originalCapabilities) { |
| ChromeOptions options = new ChromeOptions(); |
| options.addArguments("disable-extensions", "disable-infobars", "disable-breakpad"); |
| - Map<String, Object> prefs = new HashMap<>(); |
| - prefs.put("exit_type", "None"); |
| - prefs.put("exited_cleanly", true); |
| - options.setExperimentalOption("prefs", prefs); |
| + String androidPackage = System.getProperty("webdriver.chrome.android_package"); |
| + |
| + if (androidPackage == null) { |
| + Map<String, Object> prefs = new HashMap<>(); |
| + prefs.put("exit_type", "None"); |
| + prefs.put("exited_cleanly", true); |
| + options.setExperimentalOption("prefs", prefs); |
| + } |
| + |
| String chromePath = System.getProperty("webdriver.chrome.binary"); |
| + |
| if (chromePath != null) { |
| options.setBinary(new File(chromePath)); |
| } |
| |
| + if (androidPackage != null) { |
| + options.setExperimentalOption("androidPackage", androidPackage); |
| + options.setAndroidPackage(androidPackage); |
| + } |
| + |
| + String androidActivity = System.getProperty("webdriver.chrome.android_activity"); |
| + |
| + if (androidActivity != null) { |
| + options.setExperimentalOption("androidActivity", androidActivity); |
| + options.setAndroidActivity(androidActivity); |
| + } |
| + |
| + String androidProcess = System.getProperty("webdriver.chrome.android_process"); |
| + |
| + if (androidProcess != null) { |
| + options.setExperimentalOption("androidProcess", androidProcess); |
| + options.setAndroidProcess(androidProcess); |
| + } |
| + |
| if (originalCapabilities != null) { |
| options.merge(originalCapabilities); |
| } |
| diff --git a/java/client/test/org/openqa/selenium/testing/drivers/TestIgnorance.java b/java/client/test/org/openqa/selenium/testing/drivers/TestIgnorance.java |
| index 5d72393134..31b18ecd80 100644 |
| --- a/java/client/test/org/openqa/selenium/testing/drivers/TestIgnorance.java |
| +++ b/java/client/test/org/openqa/selenium/testing/drivers/TestIgnorance.java |
| @@ -87,25 +87,36 @@ public TestIgnorance(Browser browser) { |
| } |
| |
| public boolean isIgnored(Description method) { |
| - boolean ignored = ignoreComparator.shouldIgnore(method.getTestClass().getAnnotation(IgnoreList.class)) || |
| - ignoreComparator.shouldIgnore(method.getTestClass().getAnnotation(Ignore.class)) || |
| - ignoreComparator.shouldIgnore(method.getAnnotation(IgnoreList.class)) || |
| - ignoreComparator.shouldIgnore(method.getAnnotation(Ignore.class)); |
| - |
| - ignored |= isIgnoredBecauseOfJUnit4Ignore(method.getTestClass().getAnnotation(org.junit.Ignore.class)); |
| - ignored |= isIgnoredBecauseOfJUnit4Ignore(method.getAnnotation(org.junit.Ignore.class)); |
| - if (Boolean.getBoolean("ignored_only")) { |
| - ignored = !ignored; |
| + String name = method.getTestClass().getSimpleName() + "." + method.getMethodName(); |
| + String filter = System.getProperty("filter", ".*"); |
| + String[] patternGroups = filter.split("-"); |
| + String[] positivePatterns = patternGroups[0].split(":"); |
| + String[] negativePatterns = new String[0]; |
| + |
| + if (patternGroups.length > 1) |
| + { |
| + negativePatterns = patternGroups[1].split(":"); |
| } |
| |
| - ignored |= isIgnoredBecauseOfNativeEvents(method.getTestClass().getAnnotation(NativeEventsRequired.class)); |
| - ignored |= isIgnoredBecauseOfNativeEvents(method.getAnnotation(NativeEventsRequired.class)); |
| + for (int i = 0; i < negativePatterns.length; i++) |
| + { |
| + if (name.matches(negativePatterns[i])) |
| + { |
| + return true; |
| + } |
| + } |
| |
| - ignored |= isIgnoredDueToEnvironmentVariables(method); |
| + for (int i = 0; i < positivePatterns.length; i++) |
| + { |
| + if (name.matches(positivePatterns[i])) |
| + { |
| + return false; |
| + } |
| |
| - ignored |= isIgnoredDueToBeingOnSauce(method); |
| + return true; |
| + } |
| |
| - return ignored; |
| + return true; |
| } |
| |
| private boolean isIgnoredBecauseOfJUnit4Ignore(org.junit.Ignore annotation) { |
| diff --git a/java/client/test/org/openqa/selenium/testing/drivers/WebDriverBuilder.java b/java/client/test/org/openqa/selenium/testing/drivers/WebDriverBuilder.java |
| index a84741cbca..7334f6a128 100644 |
| --- a/java/client/test/org/openqa/selenium/testing/drivers/WebDriverBuilder.java |
| +++ b/java/client/test/org/openqa/selenium/testing/drivers/WebDriverBuilder.java |
| @@ -45,7 +45,12 @@ |
| |
| private static Set<WebDriver> managedDrivers = new HashSet<>(); |
| static { |
| - Runtime.getRuntime().addShutdownHook(new Thread(() -> managedDrivers.forEach(WebDriver::quit))); |
| + Runtime.getRuntime().addShutdownHook(new Thread( () -> { |
| + try { |
| + managedDrivers.forEach(WebDriver::quit); |
| + } catch (Exception a ) { |
| + } |
| + })); |
| } |
| |
| private static Map<Browser, Supplier<Capabilities>> capabilitySuppliers = |