From aa546c58a0147f80b28fa5deda65ef0b2279151d Mon Sep 17 00:00:00 2001 From: Long Ly <50008897+loly89@users.noreply.github.com> Date: Fri, 31 May 2019 03:14:38 -0700 Subject: [PATCH] Add new WebDriver support for Edge - JAVA (#7164) * Extract chromium package from chrome: both Edge and Chrome inherited from Chromium package. * Moved edgehtml to its own package. * Integrate ChromiumEdge under EdgeDriver We can run the test by calling 'go test_edge'. Also, all tests skipped by CHROME will also be skipped by CHROMIUMEDGE. --- README.md | 3 + Rakefile | 6 + .../client/src/com/thoughtworks/selenium/BUCK | 2 +- java/client/src/org/openqa/selenium/BUCK | 2 +- .../src/org/openqa/selenium/chrome/BUCK | 1 + .../openqa/selenium/chrome/ChromeDriver.java | 122 +-------- .../selenium/chrome/ChromeDriverInfo.java | 8 +- .../openqa/selenium/chrome/ChromeOptions.java | 201 +------------- .../src/org/openqa/selenium/chromium/BUCK | 28 ++ .../ChromiumDevToolsLocator.java} | 34 +-- .../selenium/chromium/ChromiumDriver.java | 165 ++++++++++++ .../ChromiumDriverCommand.java} | 8 +- .../ChromiumDriverCommandExecutor.java} | 18 +- .../selenium/chromium/ChromiumDriverInfo.java | 31 +++ .../selenium/chromium/ChromiumOptions.java | 247 ++++++++++++++++++ .../openqa/selenium/chromium/module-info.txt | 28 ++ java/client/src/org/openqa/selenium/edge/BUCK | 1 + .../selenium/edge/ChromiumEdgeDriverInfo.java | 44 ++++ .../edge/ChromiumEdgeDriverService.java | 182 +++++++++++++ .../org/openqa/selenium/edge/EdgeDriver.java | 203 +++++++------- .../openqa/selenium/edge/EdgeDriverInfo.java | 20 +- .../selenium/edge/EdgeDriverService.java | 114 ++------ .../org/openqa/selenium/edge/EdgeOptions.java | 27 +- .../org/openqa/selenium/edge/edgehtml/BUCK | 29 ++ .../edge/edgehtml/EdgeHtmlDriverInfo.java | 38 +++ .../edge/edgehtml/EdgeHtmlDriverService.java | 131 ++++++++++ .../selenium/edge/edgehtml/module-info.txt | 33 +++ .../org/openqa/selenium/edge/module-info.txt | 5 +- .../test/com/thoughtworks/selenium/BUCK | 2 +- .../selenium/InternalSelenseTestBase.java | 1 + .../test/org/openqa/selenium/AlertsTest.java | 8 + .../test/org/openqa/selenium/ClearTest.java | 2 + .../openqa/selenium/ClickScrollingTest.java | 4 +- .../test/org/openqa/selenium/ClickTest.java | 2 + .../openqa/selenium/ContentEditableTest.java | 4 + .../selenium/CookieImplementationTest.java | 3 + .../selenium/CorrectEventFiringTest.java | 3 + .../openqa/selenium/ElementAttributeTest.java | 2 + .../openqa/selenium/ElementFindingTest.java | 2 + .../ExecutingAsyncJavascriptTest.java | 7 + .../selenium/ExecutingJavascriptTest.java | 5 + .../openqa/selenium/FrameSwitchingTest.java | 3 + .../test/org/openqa/selenium/I18nTest.java | 4 + .../test/org/openqa/selenium/MiscTest.java | 2 + .../org/openqa/selenium/PageLoadingTest.java | 7 + .../openqa/selenium/PositionAndSizeTest.java | 2 + .../openqa/selenium/SlowLoadingPageTest.java | 2 + .../org/openqa/selenium/SvgDocumentTest.java | 2 + .../openqa/selenium/TakesScreenshotTest.java | 8 + .../org/openqa/selenium/TextHandlingTest.java | 2 + .../org/openqa/selenium/TextPagesTest.java | 2 + .../selenium/UnexpectedAlertBehaviorTest.java | 7 + .../test/org/openqa/selenium/UploadTest.java | 2 + .../openqa/selenium/WindowSwitchingTest.java | 2 + .../client/test/org/openqa/selenium/edge/BUCK | 47 ++++ .../openqa/selenium/edge/EdgeDriverTests.java | 31 +++ .../edge/EdgeOptionsFunctionalTest.java | 117 +++++++++ .../selenium/html5/LocationContextTest.java | 2 + .../interactions/BasicMouseInterfaceTest.java | 5 +- .../interactions/DragAndDropTest.java | 2 + .../logging/PerformanceLoggingTest.java | 2 + .../test/org/openqa/selenium/remote/BUCK | 1 + .../org/openqa/selenium/testing/drivers/BUCK | 2 +- .../selenium/testing/drivers/Browser.java | 8 + .../drivers/DefaultDriverSupplier.java | 2 +- .../testing/drivers/TestEdgeDriver.java | 139 ++++++++++ .../testing/drivers/WebDriverBuilder.java | 1 + .../com/thoughtworks/selenium/webdriven/BUCK | 2 +- .../src/org/openqa/grid/selenium/node/BUCK | 1 + java/server/src/org/openqa/selenium/grid/BUCK | 2 +- .../org/openqa/selenium/remote/server/BUCK | 2 +- .../openqa/selenium/server/htmlrunner/BUCK | 2 +- java/server/test/org/openqa/grid/e2e/BUCK | 1 + .../test/org/openqa/grid/selenium/node/BUCK | 1 + .../remote/server/DriverFactoryTest.java | 4 + .../remote/server/SessionLogsTest.java | 2 + javascript/atoms/BUCK | 2 +- javascript/ie-driver/BUCK | 2 +- javascript/remote/BUCK | 2 +- javascript/selenium-atoms/BUCK | 2 +- javascript/selenium-core/BUCK | 2 +- javascript/webdriver/BUCK | 2 +- rake-tasks/browsers.rb | 8 + rake-tasks/checks.rb | 4 + 84 files changed, 1617 insertions(+), 604 deletions(-) create mode 100644 java/client/src/org/openqa/selenium/chromium/BUCK rename java/client/src/org/openqa/selenium/{chrome/ChromeDevToolsLocator.java => chromium/ChromiumDevToolsLocator.java} (75%) create mode 100644 java/client/src/org/openqa/selenium/chromium/ChromiumDriver.java rename java/client/src/org/openqa/selenium/{chrome/ChromeDriverCommand.java => chromium/ChromiumDriverCommand.java} (87%) rename java/client/src/org/openqa/selenium/{chrome/ChromeDriverCommandExecutor.java => chromium/ChromiumDriverCommandExecutor.java} (78%) create mode 100644 java/client/src/org/openqa/selenium/chromium/ChromiumDriverInfo.java create mode 100644 java/client/src/org/openqa/selenium/chromium/ChromiumOptions.java create mode 100644 java/client/src/org/openqa/selenium/chromium/module-info.txt create mode 100644 java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverInfo.java create mode 100644 java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverService.java create mode 100644 java/client/src/org/openqa/selenium/edge/edgehtml/BUCK create mode 100644 java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverInfo.java create mode 100644 java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverService.java create mode 100644 java/client/src/org/openqa/selenium/edge/edgehtml/module-info.txt create mode 100644 java/client/test/org/openqa/selenium/edge/BUCK create mode 100644 java/client/test/org/openqa/selenium/edge/EdgeDriverTests.java create mode 100644 java/client/test/org/openqa/selenium/edge/EdgeOptionsFunctionalTest.java create mode 100644 java/client/test/org/openqa/selenium/testing/drivers/TestEdgeDriver.java diff --git a/README.md b/README.md index 3ccc88ddbfdd4..18dc091ca9abc 100644 --- a/README.md +++ b/README.md @@ -184,12 +184,15 @@ really be able to run the tests too. Try: ./go test_firefox ./go test_htmlunit ./go test_ie +./go test_edge ``` Note that the `test_chrome` target requires that you have the separate [Chrome Driver](https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver) binary available on your `PATH`. +`test_edge` target requires that you have separated [Edge Driver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver) binary available on your `PATH`. + If you are interested in a single language binding, try one of: ```sh diff --git a/Rakefile b/Rakefile index acfebd5c39c09..b6ba22683c8fb 100644 --- a/Rakefile +++ b/Rakefile @@ -114,6 +114,7 @@ JAVA_RELEASE_TARGETS = [ '//java/client/src/org/openqa/selenium/support:support', '//java/client/src/org/openqa/selenium/chrome:chrome', '//java/client/src/org/openqa/selenium/edge:edge', + '//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml', '//java/client/src/org/openqa/selenium/firefox:firefox', '//java/client/src/org/openqa/selenium/firefox/xpi:firefox-xpi', '//java/client/src/org/openqa/selenium/ie:ie', @@ -145,6 +146,7 @@ task :tests => [ "//java/client/test/org/openqa/selenium/firefox:test-synthesized", "//java/client/test/org/openqa/selenium/ie:ie", "//java/client/test/org/openqa/selenium/chrome:chrome", + "//java/client/test/org/openqa/selenium/edge:edge", "//java/client/test/org/openqa/selenium/opera:opera", "//java/client/test/org/openqa/selenium/support:small-tests", "//java/client/test/org/openqa/selenium/support:large-tests", @@ -177,6 +179,7 @@ task :test_javascript => [ '//javascript/selenium-atoms:selenium-atoms-chrome:run', '//javascript/selenium-core:selenium-core-chrome:run'] task :test_chrome => [ "//java/client/test/org/openqa/selenium/chrome:chrome:run" ] +task :test_edge => [ "//java/client/test/org/openqa/selenium/edge:edge:run" ] task :test_chrome_atoms => [ '//javascript/atoms:test_chrome:run', '//javascript/chrome-driver:test:run', @@ -236,6 +239,9 @@ end if (present?("chromedriver")) task :test_java_webdriver => [:test_chrome] end +if (present?("msedgedriver")) + task :test_java_webdriver => [:test_edge] +end if (opera?) task :test_java_webdriver => [:test_opera] end diff --git a/java/client/src/com/thoughtworks/selenium/BUCK b/java/client/src/com/thoughtworks/selenium/BUCK index 24f854a6bf694..c535f59d27822 100644 --- a/java/client/src/com/thoughtworks/selenium/BUCK +++ b/java/client/src/com/thoughtworks/selenium/BUCK @@ -31,7 +31,7 @@ java_library( ":api", ], deps = [ - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//third_party/java/guava:guava", "//third_party/java/junit:junit", "//third_party/java/testng:testng", diff --git a/java/client/src/org/openqa/selenium/BUCK b/java/client/src/org/openqa/selenium/BUCK index de7af0d92aca9..5c920b637db23 100644 --- a/java/client/src/org/openqa/selenium/BUCK +++ b/java/client/src/org/openqa/selenium/BUCK @@ -56,7 +56,7 @@ java_library( "//java/client/src/org/openqa/selenium/chrome:chrome", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/firefox/xpi:firefox-xpi", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/opera:opera", "//java/client/src/org/openqa/selenium/remote:remote", diff --git a/java/client/src/org/openqa/selenium/chrome/BUCK b/java/client/src/org/openqa/selenium/chrome/BUCK index 4104f61d7c2a5..5d6e098d130f5 100644 --- a/java/client/src/org/openqa/selenium/chrome/BUCK +++ b/java/client/src/org/openqa/selenium/chrome/BUCK @@ -8,6 +8,7 @@ java_library( module_info = "module-info.txt", srcs = glob(["*.java"]), exported_deps = [ + "//java/client/src/org/openqa/selenium/chromium:chromium", "//java/client/src/org/openqa/selenium/remote:remote", ], provided_deps = [ diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java b/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java index bdbbdc6367e86..ea13fa1c9a8ce 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java +++ b/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java @@ -17,32 +17,13 @@ package org.openqa.selenium.chrome; -import com.google.common.collect.ImmutableMap; - import org.openqa.selenium.Capabilities; import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.devtools.Connection; -import org.openqa.selenium.devtools.DevTools; -import org.openqa.selenium.html5.LocalStorage; -import org.openqa.selenium.html5.Location; +import org.openqa.selenium.chromium.ChromiumDriver; +import org.openqa.selenium.chromium.ChromiumDriverCommandExecutor; import org.openqa.selenium.html5.LocationContext; -import org.openqa.selenium.html5.SessionStorage; import org.openqa.selenium.html5.WebStorage; -import org.openqa.selenium.interactions.HasTouchScreen; -import org.openqa.selenium.interactions.TouchScreen; -import org.openqa.selenium.mobile.NetworkConnection; -import org.openqa.selenium.remote.FileDetector; -import org.openqa.selenium.remote.RemoteTouchScreen; import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.remote.html5.RemoteLocationContext; -import org.openqa.selenium.remote.html5.RemoteWebStorage; -import org.openqa.selenium.remote.http.HttpClient; -import org.openqa.selenium.remote.mobile.RemoteNetworkConnection; - -import java.util.Map; -import java.util.Objects; -import java.util.Optional; /** * A {@link WebDriver} implementation that controls a Chrome browser running on the local machine. @@ -112,14 +93,7 @@ * * @see ChromeDriverService#createDefaultService */ -public class ChromeDriver extends RemoteWebDriver - implements LocationContext, WebStorage, HasTouchScreen, NetworkConnection { - - private final RemoteLocationContext locationContext; - private final RemoteWebStorage webStorage; - private final TouchScreen touchScreen; - private final RemoteNetworkConnection networkConnection; - private final Optional connection; +public class ChromeDriver extends ChromiumDriver { /** * Creates a new ChromeDriver using the {@link ChromeDriverService#createDefaultService default} @@ -186,95 +160,7 @@ public ChromeDriver(ChromeDriverService service, ChromeOptions options) { */ @Deprecated public ChromeDriver(ChromeDriverService service, Capabilities capabilities) { - super(new ChromeDriverCommandExecutor(service), capabilities); - locationContext = new RemoteLocationContext(getExecuteMethod()); - webStorage = new RemoteWebStorage(getExecuteMethod()); - touchScreen = new RemoteTouchScreen(getExecuteMethod()); - networkConnection = new RemoteNetworkConnection(getExecuteMethod()); - - HttpClient.Factory factory = HttpClient.Factory.createDefault(); - connection = ChromeDevToolsLocator.getChromeConnector( - factory, - getCapabilities()); - } - - @Override - public void setFileDetector(FileDetector detector) { - throw new WebDriverException( - "Setting the file detector only works on remote webdriver instances obtained " + - "via RemoteWebDriver"); - } - - @Override - public LocalStorage getLocalStorage() { - return webStorage.getLocalStorage(); - } - - @Override - public SessionStorage getSessionStorage() { - return webStorage.getSessionStorage(); - } - - @Override - public Location location() { - return locationContext.location(); - } - - @Override - public void setLocation(Location location) { - locationContext.setLocation(location); - } - - @Override - public TouchScreen getTouch() { - return touchScreen; - } - - @Override - public ConnectionType getNetworkConnection() { - return networkConnection.getNetworkConnection(); - } - - @Override - public ConnectionType setNetworkConnection(ConnectionType type) { - return networkConnection.setNetworkConnection(type); + super(new ChromiumDriverCommandExecutor(service), capabilities, ChromeOptions.CAPABILITY); } - /** - * Launches Chrome app specified by id. - * - * @param id Chrome app id. - */ - public void launchApp(String id) { - execute(ChromeDriverCommand.LAUNCH_APP, ImmutableMap.of("id", id)); - } - - /** - * Execute a Chrome Devtools Protocol command and get returned result. The - * command and command args should follow - * chrome - * devtools protocol domains/commands. - */ - public Map executeCdpCommand(String commandName, Map parameters) { - Objects.requireNonNull(commandName, "Command name must be set."); - Objects.requireNonNull(parameters, "Parameters for command must be set."); - - @SuppressWarnings("unchecked") - Map toReturn = (Map) getExecuteMethod().execute( - ChromeDriverCommand.EXECUTE_CDP_COMMAND, - ImmutableMap.of("cmd", commandName, "params", parameters)); - - return ImmutableMap.copyOf(toReturn); - } - - public DevTools getDevTools() { - return connection.map(DevTools::new) - .orElseThrow(() -> new WebDriverException("Unable to create DevTools connection")); - } - - @Override - public void quit() { - connection.ifPresent(Connection::close); - super.quit(); - } } diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDriverInfo.java b/java/client/src/org/openqa/selenium/chrome/ChromeDriverInfo.java index a462ffb49895e..843881961c173 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeDriverInfo.java +++ b/java/client/src/org/openqa/selenium/chrome/ChromeDriverInfo.java @@ -25,13 +25,14 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.WebDriverInfo; +import org.openqa.selenium.chromium.ChromiumDriverInfo; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.CapabilityType; import java.util.Optional; @AutoService(WebDriverInfo.class) -public class ChromeDriverInfo implements WebDriverInfo { +public class ChromeDriverInfo extends ChromiumDriverInfo { @Override public String getDisplayName() { @@ -60,11 +61,6 @@ public boolean isAvailable() { } } - @Override - public int getMaximumSimultaneousSessions() { - return Runtime.getRuntime().availableProcessors() + 1; - } - @Override public Optional createDriver(Capabilities capabilities) throws SessionNotCreatedException { diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java b/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java index f6c9071d23a7a..38592c9405b3b 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java +++ b/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java @@ -17,30 +17,11 @@ package org.openqa.selenium.chrome; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.collect.ImmutableList; -import com.google.common.io.Files; - -import org.openqa.selenium.remote.AbstractDriverOptions; import org.openqa.selenium.Capabilities; -import org.openqa.selenium.SessionNotCreatedException; +import org.openqa.selenium.chromium.ChromiumOptions; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.CapabilityType; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.TreeMap; -import java.util.stream.Stream; - /** * Class to manage options specific to {@link ChromeDriver}. * @@ -61,7 +42,7 @@ * * @since Since chromedriver v17.0.963.0 */ -public class ChromeOptions extends AbstractDriverOptions { +public class ChromeOptions extends ChromiumOptions { /** * Key used to store a set of ChromeOptions in a {@link Capabilities} @@ -69,184 +50,8 @@ public class ChromeOptions extends AbstractDriverOptions { */ public static final String CAPABILITY = "goog:chromeOptions"; - private String binary; - private List args = new ArrayList<>(); - private List extensionFiles = new ArrayList<>(); - private List extensions = new ArrayList<>(); - private Map experimentalOptions = new HashMap<>(); - public ChromeOptions() { - setCapability(CapabilityType.BROWSER_NAME, BrowserType.CHROME); - } - - @Override - public ChromeOptions merge(Capabilities extraCapabilities) { - super.merge(extraCapabilities); - return this; - } - - /** - * Sets the path to the Chrome executable. This path should exist on the - * machine which will launch Chrome. The path should either be absolute or - * relative to the location of running ChromeDriver server. - * - * @param path Path to Chrome executable. - */ - public ChromeOptions setBinary(File path) { - binary = checkNotNull(path).getPath(); - return this; - } - - /** - * Sets the path to the Chrome executable. This path should exist on the - * machine which will launch Chrome. The path should either be absolute or - * relative to the location of running ChromeDriver server. - * - * @param path Path to Chrome executable. - */ - public ChromeOptions setBinary(String path) { - binary = checkNotNull(path); - return this; + super(CapabilityType.BROWSER_NAME, BrowserType.CHROME, CAPABILITY); } - /** - * @param arguments The arguments to use when starting Chrome. - * @see #addArguments(java.util.List) - */ - public ChromeOptions addArguments(String... arguments) { - addArguments(ImmutableList.copyOf(arguments)); - return this; - } - - /** - * Adds additional command line arguments to be used when starting Chrome. - * For example: - *

-   *   options.setArguments(
-   *       "load-extension=/path/to/unpacked_extension",
-   *       "allow-outdated-plugins");
-   * 
- * - *

Each argument may contain an option "--" prefix: "--foo" or "foo". - * Arguments with an associated value should be delimited with an "=": - * "foo=bar". - * - * @param arguments The arguments to use when starting Chrome. - */ - public ChromeOptions addArguments(List arguments) { - args.addAll(arguments); - return this; - } - - /** - * @param paths Paths to the extensions to install. - * @see #addExtensions(java.util.List) - */ - public ChromeOptions addExtensions(File... paths) { - addExtensions(ImmutableList.copyOf(paths)); - return this; - } - - /** - * Adds a new Chrome extension to install on browser startup. Each path should - * specify a packed Chrome extension (CRX file). - * - * @param paths Paths to the extensions to install. - */ - public ChromeOptions addExtensions(List paths) { - for (File path : paths) { - checkNotNull(path); - checkArgument(path.exists(), "%s does not exist", path.getAbsolutePath()); - checkArgument(!path.isDirectory(), "%s is a directory", - path.getAbsolutePath()); - } - extensionFiles.addAll(paths); - return this; - } - - /** - * @param encoded Base64 encoded data of the extensions to install. - * @see #addEncodedExtensions(java.util.List) - */ - public ChromeOptions addEncodedExtensions(String... encoded) { - addEncodedExtensions(ImmutableList.copyOf(encoded)); - return this; - } - - /** - * Adds a new Chrome extension to install on browser startup. Each string data should - * specify a Base64 encoded string of packed Chrome extension (CRX file). - * - * @param encoded Base64 encoded data of the extensions to install. - */ - public ChromeOptions addEncodedExtensions(List encoded) { - for (String extension : encoded) { - checkNotNull(extension); - } - extensions.addAll(encoded); - return this; - } - - /** - * Sets an experimental option. Useful for new ChromeDriver options not yet - * exposed through the {@link ChromeOptions} API. - * - * @param name Name of the experimental option. - * @param value Value of the experimental option, which must be convertible - * to JSON. - */ - public ChromeOptions setExperimentalOption(String name, Object value) { - experimentalOptions.put(checkNotNull(name), value); - return this; - } - - public ChromeOptions setHeadless(boolean headless) { - args.remove("--headless"); - if (headless) { - args.add("--headless"); - } - return this; - } - - @Override - protected int amendHashCode() { - return Objects.hash( - args, - binary, - experimentalOptions, - extensionFiles, - extensions); - } - - @Override - public Map asMap() { - Map toReturn = new TreeMap<>(super.asMap()); - - Map options = new TreeMap<>(); - experimentalOptions.forEach(options::put); - - if (binary != null) { - options.put("binary", binary); - } - - options.put("args", ImmutableList.copyOf(args)); - - options.put( - "extensions", - Stream.concat( - extensionFiles.stream() - .map(file -> { - try { - return Base64.getEncoder().encodeToString(Files.toByteArray(file)); - } catch (IOException e) { - throw new SessionNotCreatedException(e.getMessage(), e); - } - }), - extensions.stream() - ).collect(ImmutableList.toImmutableList())); - - toReturn.put(CAPABILITY, options); - - return Collections.unmodifiableMap(toReturn); - } } diff --git a/java/client/src/org/openqa/selenium/chromium/BUCK b/java/client/src/org/openqa/selenium/chromium/BUCK new file mode 100644 index 0000000000000..921d24609218b --- /dev/null +++ b/java/client/src/org/openqa/selenium/chromium/BUCK @@ -0,0 +1,28 @@ +load("//java:version.bzl", "SE_VERSION") +load("//java:rules.bzl", "java_library") + +java_library( + name = "chromium", + maven_coords = "org.seleniumhq.selenium:selenium-chromium-driver:" + SE_VERSION, + maven_pom_template = "//java/client/src/org/openqa/selenium:template-pom", + module_info = "module-info.txt", + srcs = glob(["*.java"]), + exported_deps = [ + "//java/client/src/org/openqa/selenium/remote:remote", + ], + provided_deps = [ + "//third_party/java/service:auto-service", + ], + annotation_processor_deps = [ + "//third_party/java/auto:auto-common", + "//third_party/java/service:auto-service", + "//third_party/java/guava:guava", + ], + annotation_processors = [ + "com.google.auto.service.processor.AutoServiceProcessor", + ], + deps = [ + "//third_party/java/guava:guava", + ], + visibility = ["PUBLIC"], +) diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDevToolsLocator.java b/java/client/src/org/openqa/selenium/chromium/ChromiumDevToolsLocator.java similarity index 75% rename from java/client/src/org/openqa/selenium/chrome/ChromeDevToolsLocator.java rename to java/client/src/org/openqa/selenium/chromium/ChromiumDevToolsLocator.java index aa43e1387a6cc..244aa26bec64b 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeDevToolsLocator.java +++ b/java/client/src/org/openqa/selenium/chromium/ChromiumDevToolsLocator.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.openqa.selenium.chrome; +package org.openqa.selenium.chromium; import static java.net.HttpURLConnection.HTTP_OK; import static org.openqa.selenium.json.Json.MAP_TYPE; @@ -24,9 +24,6 @@ import org.openqa.selenium.Capabilities; import org.openqa.selenium.devtools.Connection; -import org.openqa.selenium.devtools.Console; -import org.openqa.selenium.devtools.DevTools; -import org.openqa.selenium.devtools.Log; import org.openqa.selenium.json.Json; import org.openqa.selenium.json.JsonException; import org.openqa.selenium.remote.http.HttpClient; @@ -38,14 +35,15 @@ import java.util.Map; import java.util.Optional; -class ChromeDevToolsLocator { +class ChromiumDevToolsLocator { private static final Json JSON = new Json(); public static Optional getChromeConnector( HttpClient.Factory clientFactory, - Capabilities caps) { - Object raw = caps.getCapability(ChromeOptions.CAPABILITY); + Capabilities caps, + String capabilityKey) { + Object raw = caps.getCapability(capabilityKey); if (!(raw instanceof Map)) { return Optional.empty(); } @@ -84,26 +82,4 @@ public static Optional getChromeConnector( return Optional.empty(); } } - - public static void main(String[] args) throws Exception { - ChromeDriver driver = new ChromeDriver(); - - DevTools devTools = driver.getDevTools(); - - devTools.createSession(); - devTools.send(Log.enable()); - - devTools.addListener(Log.entryAdded(), entry -> System.out.println(entry.asSeleniumLogEntry())); - - devTools.send(Console.enable()); - devTools.addListener(Console.messageAdded(), System.out::println); - - driver.get("http://www.google.com"); - driver.executeScript("console.log('Hello, World!');"); - - Thread.sleep(2000); - - driver.quit(); - } - } diff --git a/java/client/src/org/openqa/selenium/chromium/ChromiumDriver.java b/java/client/src/org/openqa/selenium/chromium/ChromiumDriver.java new file mode 100644 index 0000000000000..807aec908b619 --- /dev/null +++ b/java/client/src/org/openqa/selenium/chromium/ChromiumDriver.java @@ -0,0 +1,165 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.openqa.selenium.chromium; + +import com.google.common.collect.ImmutableMap; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.devtools.Connection; +import org.openqa.selenium.devtools.DevTools; +import org.openqa.selenium.html5.LocalStorage; +import org.openqa.selenium.html5.Location; +import org.openqa.selenium.html5.LocationContext; +import org.openqa.selenium.html5.SessionStorage; +import org.openqa.selenium.html5.WebStorage; +import org.openqa.selenium.interactions.HasTouchScreen; +import org.openqa.selenium.interactions.TouchScreen; +import org.openqa.selenium.mobile.NetworkConnection; +import org.openqa.selenium.remote.CommandExecutor; +import org.openqa.selenium.remote.FileDetector; +import org.openqa.selenium.remote.RemoteTouchScreen; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.remote.html5.RemoteLocationContext; +import org.openqa.selenium.remote.html5.RemoteWebStorage; +import org.openqa.selenium.remote.http.HttpClient; +import org.openqa.selenium.remote.mobile.RemoteNetworkConnection; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** + * A {@link WebDriver} implementation that controls a Chromium browser running on the local machine. + * This class is provided as a convenience for easily testing the Chromium browser. The control server + * which each instance communicates with will live and die with the instance. + * + * To avoid unnecessarily restarting the ChromiumDriver server with each instance, use a + * {@link RemoteWebDriver} coupled with the desired WebDriverService, which is managed + * separately. + * + * Note that unlike ChromiumDriver, RemoteWebDriver doesn't directly implement + * role interfaces such as {@link LocationContext} and {@link WebStorage}. + * Therefore, to access that functionality, it needs to be + * {@link org.openqa.selenium.remote.Augmenter augmented} and then cast + * to the appropriate interface. + */ +public class ChromiumDriver extends RemoteWebDriver + implements LocationContext, WebStorage, HasTouchScreen, NetworkConnection { + + private final RemoteLocationContext locationContext; + private final RemoteWebStorage webStorage; + private final TouchScreen touchScreen; + private final RemoteNetworkConnection networkConnection; + private final Optional connection; + + protected ChromiumDriver(CommandExecutor commandExecutor, Capabilities capabilities, String capabilityKey) { + super(commandExecutor, capabilities); + locationContext = new RemoteLocationContext(getExecuteMethod()); + webStorage = new RemoteWebStorage(getExecuteMethod()); + touchScreen = new RemoteTouchScreen(getExecuteMethod()); + networkConnection = new RemoteNetworkConnection(getExecuteMethod()); + + HttpClient.Factory factory = HttpClient.Factory.createDefault(); + connection = ChromiumDevToolsLocator.getChromeConnector( + factory, + getCapabilities(), + capabilityKey); + } + + @Override + public void setFileDetector(FileDetector detector) { + throw new WebDriverException( + "Setting the file detector only works on remote webdriver instances obtained " + + "via RemoteWebDriver"); + } + + @Override + public LocalStorage getLocalStorage() { + return webStorage.getLocalStorage(); + } + + @Override + public SessionStorage getSessionStorage() { + return webStorage.getSessionStorage(); + } + + @Override + public Location location() { + return locationContext.location(); + } + + @Override + public void setLocation(Location location) { + locationContext.setLocation(location); + } + + @Override + public TouchScreen getTouch() { + return touchScreen; + } + + @Override + public ConnectionType getNetworkConnection() { + return networkConnection.getNetworkConnection(); + } + + @Override + public ConnectionType setNetworkConnection(ConnectionType type) { + return networkConnection.setNetworkConnection(type); + } + + /** + * Launches Chrome app specified by id. + * + * @param id Chrome app id. + */ + public void launchApp(String id) { + execute(ChromiumDriverCommand.LAUNCH_APP, ImmutableMap.of("id", id)); + } + + /** + * Execute a Chrome Devtools Protocol command and get returned result. The + * command and command args should follow + * chrome + * devtools protocol domains/commands. + */ + public Map executeCdpCommand(String commandName, Map parameters) { + Objects.requireNonNull(commandName, "Command name must be set."); + Objects.requireNonNull(parameters, "Parameters for command must be set."); + + @SuppressWarnings("unchecked") + Map toReturn = (Map) getExecuteMethod().execute( + ChromiumDriverCommand.EXECUTE_CDP_COMMAND, + ImmutableMap.of("cmd", commandName, "params", parameters)); + + return ImmutableMap.copyOf(toReturn); + } + + public DevTools getDevTools() { + return connection.map(DevTools::new) + .orElseThrow(() -> new WebDriverException("Unable to create DevTools connection")); + } + + @Override + public void quit() { + connection.ifPresent(Connection::close); + super.quit(); + } +} diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDriverCommand.java b/java/client/src/org/openqa/selenium/chromium/ChromiumDriverCommand.java similarity index 87% rename from java/client/src/org/openqa/selenium/chrome/ChromeDriverCommand.java rename to java/client/src/org/openqa/selenium/chromium/ChromiumDriverCommand.java index df038012b1808..461af53d40e1e 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeDriverCommand.java +++ b/java/client/src/org/openqa/selenium/chromium/ChromiumDriverCommand.java @@ -15,13 +15,13 @@ // specific language governing permissions and limitations // under the License. -package org.openqa.selenium.chrome; +package org.openqa.selenium.chromium; /** - * Constants for the ChromeDriver specific command IDs. + * Constants for the ChromiumDriver specific command IDs. */ -final class ChromeDriverCommand { - private ChromeDriverCommand() {} +final class ChromiumDriverCommand { + private ChromiumDriverCommand() {} static final String LAUNCH_APP = "launchApp"; static final String GET_NETWORK_CONDITIONS = "getNetworkConditions"; diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDriverCommandExecutor.java b/java/client/src/org/openqa/selenium/chromium/ChromiumDriverCommandExecutor.java similarity index 78% rename from java/client/src/org/openqa/selenium/chrome/ChromeDriverCommandExecutor.java rename to java/client/src/org/openqa/selenium/chromium/ChromiumDriverCommandExecutor.java index 47b0dc5b78a06..917767de8bd3b 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeDriverCommandExecutor.java +++ b/java/client/src/org/openqa/selenium/chromium/ChromiumDriverCommandExecutor.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.openqa.selenium.chrome; +package org.openqa.selenium.chromium; import com.google.common.collect.ImmutableMap; @@ -25,25 +25,25 @@ import org.openqa.selenium.remote.service.DriverService; /** - * {@link DriverCommandExecutor} that understands ChromeDriver specific commands. + * {@link DriverCommandExecutor} that understands ChromiumDriver specific commands. * * @see List of ChromeWebdriver commands */ -class ChromeDriverCommandExecutor extends DriverCommandExecutor { +public class ChromiumDriverCommandExecutor extends DriverCommandExecutor { private static final ImmutableMap CHROME_COMMAND_NAME_TO_URL = ImmutableMap.of( - ChromeDriverCommand.LAUNCH_APP, + ChromiumDriverCommand.LAUNCH_APP, new CommandInfo("/session/:sessionId/chromium/launch_app", HttpMethod.POST), - ChromeDriverCommand.GET_NETWORK_CONDITIONS, + ChromiumDriverCommand.GET_NETWORK_CONDITIONS, new CommandInfo("/session/:sessionId/chromium/network_conditions", HttpMethod.GET), - ChromeDriverCommand.SET_NETWORK_CONDITIONS, + ChromiumDriverCommand.SET_NETWORK_CONDITIONS, new CommandInfo("/session/:sessionId/chromium/network_conditions", HttpMethod.POST), - ChromeDriverCommand.DELETE_NETWORK_CONDITIONS, + ChromiumDriverCommand.DELETE_NETWORK_CONDITIONS, new CommandInfo("/session/:sessionId/chromium/network_conditions", HttpMethod.DELETE), - ChromeDriverCommand.EXECUTE_CDP_COMMAND, + ChromiumDriverCommand.EXECUTE_CDP_COMMAND, new CommandInfo("/session/:sessionId/goog/cdp/execute", HttpMethod.POST)); - public ChromeDriverCommandExecutor(DriverService service) { + public ChromiumDriverCommandExecutor(DriverService service) { super(service, CHROME_COMMAND_NAME_TO_URL); } } diff --git a/java/client/src/org/openqa/selenium/chromium/ChromiumDriverInfo.java b/java/client/src/org/openqa/selenium/chromium/ChromiumDriverInfo.java new file mode 100644 index 0000000000000..885aa4055b888 --- /dev/null +++ b/java/client/src/org/openqa/selenium/chromium/ChromiumDriverInfo.java @@ -0,0 +1,31 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.openqa.selenium.chromium; + +import com.google.auto.service.AutoService; + +import org.openqa.selenium.WebDriverInfo; + +@AutoService(WebDriverInfo.class) +public abstract class ChromiumDriverInfo implements WebDriverInfo { + + @Override + public int getMaximumSimultaneousSessions() { + return Runtime.getRuntime().availableProcessors() + 1; + } +} diff --git a/java/client/src/org/openqa/selenium/chromium/ChromiumOptions.java b/java/client/src/org/openqa/selenium/chromium/ChromiumOptions.java new file mode 100644 index 0000000000000..04e04686747b8 --- /dev/null +++ b/java/client/src/org/openqa/selenium/chromium/ChromiumOptions.java @@ -0,0 +1,247 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.openqa.selenium.chromium; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.Files; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.SessionNotCreatedException; +import org.openqa.selenium.remote.AbstractDriverOptions; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; +import java.util.stream.Stream; + +/** + * Class to manage options specific to {@link ChromiumDriver}. + * + *

Example usage: + *


+ * ChromeOptions options = new ChromeOptions()
+ * options.addExtensions(new File("/path/to/extension.crx"))
+ * options.setBinary(new File("/path/to/chrome"));
+ *
+ * // For use with ChromeDriver:
+ * ChromeDriver driver = new ChromeDriver(options);
+ *
+ * // For use with RemoteWebDriver:
+ * RemoteWebDriver driver = new RemoteWebDriver(
+ *     new URL("http://localhost:4444/wd/hub"),
+ *     new ChromeOptions());
+ * 
+ * + * @since Since chromedriver v17.0.963.0 + */ +public class ChromiumOptions extends AbstractDriverOptions { + + private String binary; + private List args = new ArrayList<>(); + private List extensionFiles = new ArrayList<>(); + private List extensions = new ArrayList<>(); + private Map experimentalOptions = new HashMap<>(); + + private final String CAPABILITY; + + public ChromiumOptions(String capabilityType, String browserType, String capability) { + this.CAPABILITY = capability; + setCapability(capabilityType, browserType); + } + + @Override + public T merge(Capabilities extraCapabilities) { + super.merge(extraCapabilities); + return (T) this; + } + + /** + * Sets the path to the Chrome executable. This path should exist on the + * machine which will launch Chrome. The path should either be absolute or + * relative to the location of running ChromeDriver server. + * + * @param path Path to Chrome executable. + */ + public T setBinary(File path) { + binary = checkNotNull(path).getPath(); + return (T) this; + } + + /** + * Sets the path to the Chrome executable. This path should exist on the + * machine which will launch Chrome. The path should either be absolute or + * relative to the location of running ChromeDriver server. + * + * @param path Path to Chrome executable. + */ + public T setBinary(String path) { + binary = checkNotNull(path); + return (T) this; + } + + /** + * @param arguments The arguments to use when starting Chrome. + * @see #addArguments(List) + */ + public T addArguments(String... arguments) { + addArguments(ImmutableList.copyOf(arguments)); + return (T) this; + } + + /** + * Adds additional command line arguments to be used when starting Chrome. + * For example: + *

+   *   options.setArguments(
+   *       "load-extension=/path/to/unpacked_extension",
+   *       "allow-outdated-plugins");
+   * 
+ * + *

Each argument may contain an option "--" prefix: "--foo" or "foo". + * Arguments with an associated value should be delimited with an "=": + * "foo=bar". + * + * @param arguments The arguments to use when starting Chrome. + */ + public T addArguments(List arguments) { + args.addAll(arguments); + return (T) this; + } + + /** + * @param paths Paths to the extensions to install. + * @see #addExtensions(List) + */ + public T addExtensions(File... paths) { + addExtensions(ImmutableList.copyOf(paths)); + return (T) this; + } + + /** + * Adds a new Chrome extension to install on browser startup. Each path should + * specify a packed Chrome extension (CRX file). + * + * @param paths Paths to the extensions to install. + */ + public T addExtensions(List paths) { + for (File path : paths) { + checkNotNull(path); + checkArgument(path.exists(), "%s does not exist", path.getAbsolutePath()); + checkArgument(!path.isDirectory(), "%s is a directory", + path.getAbsolutePath()); + } + extensionFiles.addAll(paths); + return (T) this; + } + + /** + * @param encoded Base64 encoded data of the extensions to install. + * @see #addEncodedExtensions(List) + */ + public T addEncodedExtensions(String... encoded) { + addEncodedExtensions(ImmutableList.copyOf(encoded)); + return (T) this; + } + + /** + * Adds a new Chrome extension to install on browser startup. Each string data should + * specify a Base64 encoded string of packed Chrome extension (CRX file). + * + * @param encoded Base64 encoded data of the extensions to install. + */ + public T addEncodedExtensions(List encoded) { + for (String extension : encoded) { + checkNotNull(extension); + } + extensions.addAll(encoded); + return (T) this; + } + + /** + * Sets an experimental option. Useful for new ChromeDriver options not yet + * exposed through the {@link ChromiumOptions} API. + * + * @param name Name of the experimental option. + * @param value Value of the experimental option, which must be convertible + * to JSON. + */ + public T setExperimentalOption(String name, Object value) { + experimentalOptions.put(checkNotNull(name), value); + return (T) this; + } + + public T setHeadless(boolean headless) { + args.remove("--headless"); + if (headless) { + args.add("--headless"); + } + return (T) this; + } + + @Override + protected int amendHashCode() { + return Objects.hash( + args, + binary, + experimentalOptions, + extensionFiles, + extensions); + } + + @Override + public Map asMap() { + Map toReturn = new TreeMap<>(super.asMap()); + + Map options = new TreeMap<>(); + experimentalOptions.forEach(options::put); + + if (binary != null) { + options.put("binary", binary); + } + + options.put("args", ImmutableList.copyOf(args)); + + options.put( + "extensions", + Stream.concat( + extensionFiles.stream() + .map(file -> { + try { + return Base64.getEncoder().encodeToString(Files.toByteArray(file)); + } catch (IOException e) { + throw new SessionNotCreatedException(e.getMessage(), e); + } + }), + extensions.stream() + ).collect(ImmutableList.toImmutableList())); + + toReturn.put(CAPABILITY, options); + + return Collections.unmodifiableMap(toReturn); + } +} diff --git a/java/client/src/org/openqa/selenium/chromium/module-info.txt b/java/client/src/org/openqa/selenium/chromium/module-info.txt new file mode 100644 index 0000000000000..bca358512dfad --- /dev/null +++ b/java/client/src/org/openqa/selenium/chromium/module-info.txt @@ -0,0 +1,28 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +module org.openqa.selenium.chromium { + requires transitive com.google.common; + requires transitive org.openqa.selenium.core; + requires transitive org.openqa.selenium.remote; + + exports org.openqa.selenium.chromium; + + provides org.openqa.selenium.WebDriverInfo with + org.openqa.selenium.chromium.ChromiumDriverInfo; + +} diff --git a/java/client/src/org/openqa/selenium/edge/BUCK b/java/client/src/org/openqa/selenium/edge/BUCK index 8c6a610d8fb70..6e15280e69c50 100644 --- a/java/client/src/org/openqa/selenium/edge/BUCK +++ b/java/client/src/org/openqa/selenium/edge/BUCK @@ -8,6 +8,7 @@ java_library( module_info = "module-info.txt", srcs = glob(["*.java"]), exported_deps = [ + "//java/client/src/org/openqa/selenium/chromium:chromium", "//java/client/src/org/openqa/selenium/remote:remote", ], provided_deps = [ diff --git a/java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverInfo.java b/java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverInfo.java new file mode 100644 index 0000000000000..d1ad710ca6c71 --- /dev/null +++ b/java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverInfo.java @@ -0,0 +1,44 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.openqa.selenium.edge; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.remote.BrowserType; + +public class ChromiumEdgeDriverInfo extends EdgeDriverInfo { + + @Override + public boolean isSupporting(Capabilities capabilities) { + return BrowserType.EDGE.equals(capabilities.getBrowserName()); + } + + @Override + public boolean isAvailable() { + try { + ChromiumEdgeDriverService.createDefaultService(); + return true; + } catch (IllegalStateException | WebDriverException e) { + return false; + } + } + + @Override + public int getMaximumSimultaneousSessions() { + return Runtime.getRuntime().availableProcessors() + 1; + } +} diff --git a/java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverService.java b/java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverService.java new file mode 100644 index 0000000000000..98133784ec93b --- /dev/null +++ b/java/client/src/org/openqa/selenium/edge/ChromiumEdgeDriverService.java @@ -0,0 +1,182 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.openqa.selenium.edge; + +import com.google.auto.service.AutoService; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.remote.BrowserType; +import org.openqa.selenium.remote.service.DriverService; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class ChromiumEdgeDriverService extends EdgeDriverService { + + /** + * Boolean system property that defines whether the MSEdgeDriver executable should be started + * in silent mode. + */ + public static final String EDGE_DRIVER_SILENT_OUTPUT_PROPERTY = "webdriver.edge.silentOutput"; + + /** + * System property that defines comma-separated list of remote IPv4 addresses which are + * allowed to connect to MSEdgeDriver. + */ + public final static String EDGE_DRIVER_ALLOWED_IPS_PROPERTY = "webdriver.edge.withAllowedIps"; + + public ChromiumEdgeDriverService( + File executable, + int port, + List args, + Map environment) throws IOException { + super(executable, port, args, environment); + } + + /** + * Configures and returns a new {@link ChromiumEdgeDriverService} using the default configuration. In + * this configuration, the service will use the MSEdgeDriver executable identified by the + * {@link #EDGE_DRIVER_EXE_PROPERTY} system property. Each service created by this method will + * be configured to use a free port on the current system. + * + * @return A new ChromiumEdgeDriverService using the default configuration. + */ + public static ChromiumEdgeDriverService createDefaultService() { + return new ChromiumEdgeDriverService.Builder().build(); + } + + /** + * Builder used to configure new {@link ChromiumEdgeDriverService} instances. + */ + @AutoService(DriverService.Builder.class) + public static class Builder extends EdgeDriverService.Builder< + ChromiumEdgeDriverService, ChromiumEdgeDriverService.Builder> { + + private boolean verbose = Boolean.getBoolean(EDGE_DRIVER_VERBOSE_LOG_PROPERTY); + private boolean silent = Boolean.getBoolean(EDGE_DRIVER_SILENT_OUTPUT_PROPERTY); + private String allowedListIps = System.getProperty(EDGE_DRIVER_ALLOWED_IPS_PROPERTY); + + @Override + public boolean isLegacy() { + return false; + } + + @Override + public int score(Capabilities capabilities) { + int score = 0; + + if (BrowserType.EDGE.equals(capabilities.getBrowserName())) { + score++; + } + + if (capabilities.getCapability(EdgeOptions.CAPABILITY) != null) { + score++; + } + + return score; + } + + /** + * Configures the driver server verbosity. + * + * @param verbose whether verbose output is used + * @return A self reference. + */ + @Override + public EdgeDriverService.Builder withVerbose(boolean verbose) { + this.verbose = verbose; + return this; + } + + /** + * Configures the driver server for silent output. + * + * @param silent whether silent output is used + * @return A self reference. + */ + public ChromiumEdgeDriverService.Builder withSilent(boolean silent) { + this.silent = silent; + return this; + } + + /** + * Configures the comma-separated list of remote IPv4 addresses which are allowed to connect + * to the driver server. + * + * @param allowedListIps Comma-separated list of remote IPv4 addresses. + * @return A self reference. + */ + public ChromiumEdgeDriverService.Builder withAllowedListIps(String allowedListIps) { + this.allowedListIps = allowedListIps; + return this; + } + + @Override + protected File findDefaultExecutable() { + return findExecutable( + "msedgedriver", EDGE_DRIVER_EXE_PROPERTY, + "https://github.com/SeleniumHQ/selenium/wiki/MicrosoftWebDriver", + "https://msedgecdn.azurewebsites.net/webdriver/index.html"); + } + + @Override + protected ImmutableList createArgs() { + if (getLogFile() == null) { + String logFilePath = System.getProperty(EDGE_DRIVER_LOG_PROPERTY); + if (logFilePath != null) { + withLogFile(new File(logFilePath)); + } + } + + ImmutableList.Builder argsBuilder = ImmutableList.builder(); + argsBuilder.add(String.format("--port=%d", getPort())); + if (getLogFile() != null) { + argsBuilder.add(String.format("--log-path=%s", getLogFile().getAbsolutePath())); + } + if (verbose) { + argsBuilder.add("--verbose"); + } + if (silent) { + argsBuilder.add("--silent"); + } + if (allowedListIps != null) { + argsBuilder.add(String.format("--whitelisted-ips=%s", allowedListIps)); + } + + return argsBuilder.build(); + } + + @Override + protected ChromiumEdgeDriverService createDriverService( + File exe, + int port, + ImmutableList args, + ImmutableMap environment) { + try { + return new ChromiumEdgeDriverService(exe, port, args, environment); + } catch (IOException e) { + throw new WebDriverException(e); + } + } + } + +} diff --git a/java/client/src/org/openqa/selenium/edge/EdgeDriver.java b/java/client/src/org/openqa/selenium/edge/EdgeDriver.java index ed96067f363f6..66dc0d59e22ac 100644 --- a/java/client/src/org/openqa/selenium/edge/EdgeDriver.java +++ b/java/client/src/org/openqa/selenium/edge/EdgeDriver.java @@ -18,139 +18,128 @@ import org.openqa.selenium.Capabilities; import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.chromium.ChromiumDriver; +import org.openqa.selenium.chromium.ChromiumDriverCommandExecutor; +import org.openqa.selenium.remote.CommandExecutor; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.service.DriverCommandExecutor; +import org.openqa.selenium.remote.service.DriverService; + +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.stream.StreamSupport; /** * A {@link WebDriver} implementation that controls an Edge browser running on the local machine. * This class is provided as a convenience for easily testing the Edge browser. The control server * which each instance communicates with will live and die with the instance. * - * To avoid unnecessarily restarting the MicrosoftEdgeDriver server with each instance, use a + * To avoid unnecessarily restarting the Microsoft WebDriver server with each instance, use a * {@link RemoteWebDriver} coupled with the desired {@link EdgeDriverService}, which is managed * separately. For example:

{@code
  *
- * import static org.junit.Assert.assertEquals;
- *
- * import org.junit.*;
- * import org.junit.runner.RunWith;
- * import org.junit.runners.JUnit4;
+ * import org.junit.jupiter.api.*;
+ * import org.openqa.selenium.By;
+ * import org.openqa.selenium.WebDriver;
+ * import org.openqa.selenium.WebDriverException;
+ * import org.openqa.selenium.WebElement;
  * import org.openqa.selenium.edge.EdgeDriverService;
- * import org.openqa.selenium.remote.DesiredCapabilities;
+ * import org.openqa.selenium.edge.EdgeOptions;
  * import org.openqa.selenium.remote.RemoteWebDriver;
+ * import org.openqa.selenium.remote.service.DriverService;
  *
- * {@literal @RunWith(JUnit4.class)}
- * public class EdgeTest extends TestCase {
+ * import java.io.IOException;
+ * import java.util.ServiceLoader;
+ * import java.util.stream.StreamSupport;
  *
- *   private static EdgeDriverService service;
- *   private WebDriver driver;
+ * import static org.junit.jupiter.api.Assertions.assertEquals;
  *
- *   {@literal @BeforeClass}
- *   public static void createAndStartService() {
- *     service = new EdgeDriverService.Builder()
- *         .usingDriverExecutable(new File("path/to/my/MicrosoftWebDriver.exe"))
- *         .usingAnyFreePort()
- *         .build();
- *     service.start();
- *   }
+ * public class EdgeTest {
  *
- *   {@literal @AfterClass}
- *   public static void createAndStopService() {
- *     service.stop();
- *   }
+ *     private static EdgeDriverService service;
+ *     private WebDriver driver;
  *
- *   {@literal @Before}
- *   public void createDriver() {
- *     driver = new RemoteWebDriver(service.getUrl(),
- *         DesiredCapabilities.edge());
- *   }
+ *     {@Literal @BeforeAll}
+ *     public static void createAndStartService() {
+ *         // Setting this property to false in order to launch Chromium Edge
+ *         // Otherwise, old Edge will be launched by default
+ *         System.setProperty("webdriver.edge.edgehtml", "false");
+ *         EdgeDriverService.Builder builder =
+ *                 StreamSupport.stream(ServiceLoader.load(DriverService.Builder.class).spliterator(), false)
+ *                         .filter(b -> b instanceof EdgeDriverService.Builder)
+ *                         .map(b -> (EdgeDriverService.Builder) b)
+ *                         .filter(b -> b.isLegacy() == Boolean.getBoolean("webdriver.edge.edgehtml"))
+ *                         .findFirst().orElseThrow(WebDriverException::new);
+ *         service = builder.build();
+ *         try {
+ *             service.start();
+ *         }
+ *         catch (IOException e) {
+ *             throw new RuntimeException(e);
+ *         }
+ *     }
  *
- *   {@literal @After}
- *   public void quitDriver() {
- *     driver.quit();
- *   }
+ *     {@Literal @AfterAll}
+ *     public static void createAndStopService() {
+ *         service.stop();
+ *     }
  *
- *   {@literal @Test}
- *   public void testGoogleSearch() {
- *     driver.get("http://www.google.com");
- *     WebElement searchBox = driver.findElement(By.name("q"));
- *     searchBox.sendKeys("webdriver");
- *     searchBox.quit();
- *     assertEquals("webdriver - Google Search", driver.getTitle());
- *   }
- * }
- * }
+ * {@Literal @BeforeEach} + * public void createDriver() { + * driver = new RemoteWebDriver(service.getUrl(), + * new EdgeOptions()); + * } * + * {@Literal @AfterEach} + * public void quitDriver() { + * driver.quit(); + * } * - * @see EdgeDriverService#createDefaultService + * {@Literal @Test} + * public void testBingSearch() { + * driver.get("http://www.bing.com"); + * WebElement searchBox = driver.findElement(By.name("q")); + * searchBox.sendKeys("webdriver"); + * searchBox.submit(); + * assertEquals("webdriver - Bing", driver.getTitle()); + * } + * }} */ -public class EdgeDriver extends RemoteWebDriver { +public class EdgeDriver extends ChromiumDriver { + + /** + * Boolean system property that defines whether the msedgedriver executable (Chromium Edge) + * should be used. + */ + public static final String DRIVER_USE_EDGE_EDGEHTML = "webdriver.edge.edgehtml"; + + public EdgeDriver() { this(new EdgeOptions()); } + + public EdgeDriver(EdgeOptions options) { + super(toExecutor(options), options, EdgeOptions.CAPABILITY); + } + + @Deprecated + public EdgeDriver(Capabilities capabilities) { + super(toExecutor(new EdgeOptions()), capabilities, EdgeOptions.CAPABILITY); + } - /** - * Creates a new EdgeDriver using the {@link EdgeDriverService#createDefaultService default} - * server configuration. - * - * @see #EdgeDriver(EdgeDriverService, EdgeOptions) - */ - public EdgeDriver() { - this(EdgeDriverService.createDefaultService(), new EdgeOptions()); - } + private static CommandExecutor toExecutor(EdgeOptions options) { + Objects.requireNonNull(options, "No options to construct executor from"); - /** - * Creates a new EdgeDriver instance. The {@code service} will be started along with the driver, - * and shutdown upon calling {@link #quit()}. - * - * @param service The service to use. - * @see #EdgeDriver(EdgeDriverService, EdgeOptions) - */ - public EdgeDriver(EdgeDriverService service) { - this(service, new EdgeOptions()); - } + boolean isLegacy = System.getProperty(DRIVER_USE_EDGE_EDGEHTML) == null || Boolean.getBoolean(DRIVER_USE_EDGE_EDGEHTML); - /** - * Creates a new EdgeDriver instance. The {@code capabilities} will be passed to the - * EdgeDriver service. - * - * @param capabilities The capabilities required from the EdgeDriver. - * @see #EdgeDriver(EdgeDriverService, Capabilities) - * @deprecated Use {@link EdgeDriver(EdgeOptions)} - */ - @Deprecated - public EdgeDriver(Capabilities capabilities) { - this(EdgeDriverService.createDefaultService(), capabilities); - } + EdgeDriverService.Builder builder = + StreamSupport.stream(ServiceLoader.load(DriverService.Builder.class).spliterator(), false) + .filter(b -> b instanceof EdgeDriverService.Builder) + .map(b -> (EdgeDriverService.Builder) b) + .filter(b -> b.isLegacy() == isLegacy) + .findFirst().orElseThrow(WebDriverException::new); - /** - * Creates a new EdgeDriver instance with the specified options. - * - * @param options The options to use. - * @see #EdgeDriver(EdgeDriverService, EdgeOptions) - */ - public EdgeDriver(EdgeOptions options) { - this(EdgeDriverService.createDefaultService(), options); - } + if (isLegacy) + return new DriverCommandExecutor(builder.build()); - /** - * Creates a new EdgeDriver instance with the specified options. The {@code service} will be - * started along with the driver, and shutdown upon calling {@link #quit()}. - * - * @param service The service to use. - * @param options The options to use. - */ - public EdgeDriver(EdgeDriverService service, EdgeOptions options) { - super(new DriverCommandExecutor(service), options); - } - - /** - * Creates a new EdgeDriver instance. The {@code service} will be started along with the - * driver, and shutdown upon calling {@link #quit()}. - * - * @param service The service to use. - * @param capabilities The capabilities required from the EdgeDriver. - * @deprecated Use {@link #EdgeDriver(EdgeDriverService, EdgeOptions)} - */ - @Deprecated - public EdgeDriver(EdgeDriverService service, Capabilities capabilities) { - super(new DriverCommandExecutor(service), capabilities); - } + return new ChromiumDriverCommandExecutor(builder.build()); + } } diff --git a/java/client/src/org/openqa/selenium/edge/EdgeDriverInfo.java b/java/client/src/org/openqa/selenium/edge/EdgeDriverInfo.java index 56ad88c4826c8..c4ef132d4c49e 100644 --- a/java/client/src/org/openqa/selenium/edge/EdgeDriverInfo.java +++ b/java/client/src/org/openqa/selenium/edge/EdgeDriverInfo.java @@ -14,25 +14,20 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. - package org.openqa.selenium.edge; import static org.openqa.selenium.remote.CapabilityType.BROWSER_NAME; -import com.google.auto.service.AutoService; - import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.SessionNotCreatedException; import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.WebDriverInfo; +import org.openqa.selenium.chromium.ChromiumDriverInfo; import org.openqa.selenium.remote.BrowserType; import java.util.Optional; -@AutoService(WebDriverInfo.class) -public class EdgeDriverInfo implements WebDriverInfo { +public abstract class EdgeDriverInfo extends ChromiumDriverInfo { @Override public String getDisplayName() { @@ -51,18 +46,11 @@ public boolean isSupporting(Capabilities capabilities) { } @Override - public boolean isAvailable() { - try { - EdgeDriverService.createDefaultService(); - return true; - } catch (IllegalStateException | WebDriverException e) { - return false; - } - } + public abstract boolean isAvailable(); @Override public int getMaximumSimultaneousSessions() { - return 1; + return Runtime.getRuntime().availableProcessors() + 1; } @Override diff --git a/java/client/src/org/openqa/selenium/edge/EdgeDriverService.java b/java/client/src/org/openqa/selenium/edge/EdgeDriverService.java index a51ccf6aca974..6915422a0dab5 100644 --- a/java/client/src/org/openqa/selenium/edge/EdgeDriverService.java +++ b/java/client/src/org/openqa/selenium/edge/EdgeDriverService.java @@ -16,114 +16,58 @@ // under the License. package org.openqa.selenium.edge; -import com.google.auto.service.AutoService; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import org.openqa.selenium.Capabilities; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.service.DriverService; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; - +import java.util.List; +import java.util.Map; /** -* Manages the life and death of a MicrosoftWebDriver server. -* -*/ -public class EdgeDriverService extends DriverService{ + * Manages the life and death of the EdgeDriver (MicrosoftWebDriver or MSEdgeDriver). + */ +public abstract class EdgeDriverService extends DriverService { /** - * System property that defines the location of the MicrosoftWebDriver executable that will be used by - * the {@link #createDefaultService() default service}. - */ + * System property that defines the location of the EdgeDriver executable that will be used by + * the default service. + */ public static final String EDGE_DRIVER_EXE_PROPERTY = "webdriver.edge.driver"; /** - * System property that defines the default location where MicrosoftWebDriver output is logged. - */ + * System property that defines the default location where MicrosoftWebDriver output is logged. + */ public static final String EDGE_DRIVER_LOG_PROPERTY = "webdriver.edge.logfile"; /** - * Boolean system property that defines whether the MicrosoftWebDriver executable should be started - * with verbose logging. - */ + * Boolean system property that defines whether the MicrosoftWebDriver executable should be started + * with verbose logging. + */ public static final String EDGE_DRIVER_VERBOSE_LOG_PROPERTY = "webdriver.edge.verboseLogging"; - public EdgeDriverService(File executable, int port, ImmutableList args, - ImmutableMap environment) throws IOException { - super(executable, port, args, environment); - } - /** - * Configures and returns a new {@link EdgeDriverService} using the default configuration. In - * this configuration, the service will use the MicrosoftWebDriver executable identified by the - * {@link #EDGE_DRIVER_EXE_PROPERTY} system property. Each service created by this method will - * be configured to use a free port on the current system. - * - * @return A new EdgeDriverService using the default configuration. - */ - public static EdgeDriverService createDefaultService() { - return new Builder().build(); + * @param executable The EdgeDriver executable. + * @param port Which port to start the EdgeDriver on. + * @param args The arguments to the launched server. + * @param environment The environment for the launched server. + * @throws IOException If an I/O error occurs. + */ + public EdgeDriverService( + File executable, + int port, + List args, + Map environment) throws IOException { + super(executable, port, ImmutableList.copyOf(args), ImmutableMap.copyOf(environment)); } - @AutoService(DriverService.Builder.class) - public static class Builder extends DriverService.Builder< - EdgeDriverService, EdgeDriverService.Builder> { - - @Override - public int score(Capabilities capabilities) { - int score = 0; - - if (BrowserType.EDGE.equals(capabilities.getBrowserName())) { - score++; - } - - return score; - } - - @Override - protected File findDefaultExecutable() { - return findExecutable("MicrosoftWebDriver", EDGE_DRIVER_EXE_PROPERTY, - "https://github.com/SeleniumHQ/selenium/wiki/MicrosoftWebDriver", - "http://go.microsoft.com/fwlink/?LinkId=619687"); - } - - @Override - protected ImmutableList createArgs() { - ImmutableList.Builder argsBuilder = ImmutableList.builder(); - argsBuilder.add(String.format("--port=%d", getPort())); - - if (Boolean.getBoolean(EDGE_DRIVER_VERBOSE_LOG_PROPERTY)) { - argsBuilder.add("--verbose"); - } - - return argsBuilder.build(); - } - - @Override - protected EdgeDriverService createDriverService(File exe, int port, - ImmutableList args, - ImmutableMap environment) { - try { - EdgeDriverService service = new EdgeDriverService(exe, port, args, environment); + public static abstract class Builder> + extends DriverService.Builder { - if (getLogFile() != null) { - service.sendOutputTo(new FileOutputStream(getLogFile())); - } else { - String logFile = System.getProperty(EDGE_DRIVER_LOG_PROPERTY); - if (logFile != null) { - service.sendOutputTo(new FileOutputStream(logFile)); - } - } + public abstract boolean isLegacy(); + public abstract EdgeDriverService.Builder withVerbose(boolean verbose); - return service; - } catch (IOException e) { - throw new WebDriverException(e); - } - } } } diff --git a/java/client/src/org/openqa/selenium/edge/EdgeOptions.java b/java/client/src/org/openqa/selenium/edge/EdgeOptions.java index 71deb91f1df9b..3a4e01772c920 100644 --- a/java/client/src/org/openqa/selenium/edge/EdgeOptions.java +++ b/java/client/src/org/openqa/selenium/edge/EdgeOptions.java @@ -14,40 +14,41 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. - package org.openqa.selenium.edge; -import org.openqa.selenium.remote.AbstractDriverOptions; import org.openqa.selenium.Capabilities; +import org.openqa.selenium.chromium.ChromiumOptions; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.CapabilityType; - /** * Class to manage options specific to {@link EdgeDriver}. * *

Example usage: *


  * EdgeOptions options = new EdgeOptions()
+ * options.addExtensions(new File("/path/to/extension.crx"))
+ * options.setBinary(new File("/path/to/edge"));
  *
  * // For use with EdgeDriver:
  * EdgeDriver driver = new EdgeDriver(options);
  *
  * // For use with RemoteWebDriver:
- * EdgeOptions options = new EdgeOptions();
  * RemoteWebDriver driver = new RemoteWebDriver(
- *     new URL("http://localhost:4444/wd/hub"), options);
+ *     new URL("http://localhost:4444/wd/hub"),
+ *     new EdgeOptions());
  * 
+ * */ -public class EdgeOptions extends AbstractDriverOptions { +public class EdgeOptions extends ChromiumOptions { - public EdgeOptions() { - setCapability(CapabilityType.BROWSER_NAME, BrowserType.EDGE); - } + /** + * Key used to store a set of ChromeOptions in a {@link Capabilities} + * object. + */ + public static final String CAPABILITY = "goog:chromeOptions"; - @Override - public EdgeOptions merge(Capabilities extraCapabilities) { - super.merge(extraCapabilities); - return this; + public EdgeOptions() { + super(CapabilityType.BROWSER_NAME, BrowserType.EDGE, CAPABILITY); } } diff --git a/java/client/src/org/openqa/selenium/edge/edgehtml/BUCK b/java/client/src/org/openqa/selenium/edge/edgehtml/BUCK new file mode 100644 index 0000000000000..ebc2196dfef14 --- /dev/null +++ b/java/client/src/org/openqa/selenium/edge/edgehtml/BUCK @@ -0,0 +1,29 @@ +load("//java:version.bzl", "SE_VERSION") +load("//java:rules.bzl", "java_library") + +java_library( + name = "edgehtml", + maven_coords = "org.seleniumhq.selenium:selenium-edgehtml-driver:" + SE_VERSION, + maven_pom_template = "//java/client/src/org/openqa/selenium:template-pom", + module_info = "module-info.txt", + srcs = glob(["*.java"]), + exported_deps = [ + "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/remote:remote", + ], + provided_deps = [ + "//third_party/java/service:auto-service", + ], + annotation_processor_deps = [ + "//third_party/java/auto:auto-common", + "//third_party/java/service:auto-service", + "//third_party/java/guava:guava", + ], + annotation_processors = [ + "com.google.auto.service.processor.AutoServiceProcessor", + ], + deps = [ + "//third_party/java/guava:guava", + ], + visibility = ["PUBLIC"], +) diff --git a/java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverInfo.java b/java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverInfo.java new file mode 100644 index 0000000000000..5d76615e1870d --- /dev/null +++ b/java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverInfo.java @@ -0,0 +1,38 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.openqa.selenium.edge.edgehtml; + +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.edge.EdgeDriverInfo; + +public class EdgeHtmlDriverInfo extends EdgeDriverInfo { + + @Override + public boolean isAvailable() { + try { + EdgeHtmlDriverService.createDefaultService(); + return true; + } catch (IllegalStateException | WebDriverException e) { + return false; + } + } + + @Override + public int getMaximumSimultaneousSessions() { + return 1; + } +} diff --git a/java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverService.java b/java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverService.java new file mode 100644 index 0000000000000..e32a0bedc2f9a --- /dev/null +++ b/java/client/src/org/openqa/selenium/edge/edgehtml/EdgeHtmlDriverService.java @@ -0,0 +1,131 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.openqa.selenium.edge.edgehtml; + +import com.google.auto.service.AutoService; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.edge.EdgeDriverService; +import org.openqa.selenium.remote.BrowserType; +import org.openqa.selenium.remote.service.DriverService; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class EdgeHtmlDriverService extends EdgeDriverService { + + public EdgeHtmlDriverService(File executable, int port, + List args, + Map environment) throws IOException { + super(executable, port, args, environment); + } + + /** + * Configures and returns a new {@link EdgeHtmlDriverService} using the default configuration. In + * this configuration, the service will use the MicrosoftWebDriver executable identified by the + * {@link #EDGE_DRIVER_EXE_PROPERTY} system property. Each service created by this method will + * be configured to use a free port on the current system. + * + * @return A new EdgeDriverService using the default configuration. + */ + public static EdgeHtmlDriverService createDefaultService() { + return new Builder().build(); + } + + @AutoService(DriverService.Builder.class) + public static class Builder extends EdgeDriverService.Builder< + EdgeHtmlDriverService, EdgeHtmlDriverService.Builder> { + + private boolean verbose = Boolean.getBoolean(EDGE_DRIVER_VERBOSE_LOG_PROPERTY); + + @Override + public boolean isLegacy() { + return true; + } + + @Override + public int score(Capabilities capabilities) { + int score = 0; + + if (BrowserType.EDGE.equals(capabilities.getBrowserName())) { + score++; + } + + return score; + } + + /** + * Configures the driver server verbosity. + * + * @param verbose whether verbose output is used + */ + @Override + public EdgeDriverService.Builder withVerbose(boolean verbose) { + this.verbose = verbose; + return this; + } + + @Override + protected File findDefaultExecutable() { + return findExecutable("MicrosoftWebDriver", EDGE_DRIVER_EXE_PROPERTY, + "https://github.com/SeleniumHQ/selenium/wiki/MicrosoftWebDriver", + "http://go.microsoft.com/fwlink/?LinkId=619687"); + } + + @Override + protected ImmutableList createArgs() { + ImmutableList.Builder argsBuilder = ImmutableList.builder(); + argsBuilder.add(String.format("--port=%d", getPort())); + + if (verbose) { + argsBuilder.add("--verbose"); + } + + return argsBuilder.build(); + } + + @Override + protected EdgeHtmlDriverService createDriverService(File exe, int port, + ImmutableList args, + ImmutableMap environment) { + try { + EdgeHtmlDriverService + service = new EdgeHtmlDriverService(exe, port, args, environment); + + if (getLogFile() != null) { + service.sendOutputTo(new FileOutputStream(getLogFile())); + } else { + String logFile = System.getProperty(EDGE_DRIVER_LOG_PROPERTY); + if (logFile != null) { + service.sendOutputTo(new FileOutputStream(logFile)); + } + } + + return service; + } catch (IOException e) { + throw new WebDriverException(e); + } + } + } + +} diff --git a/java/client/src/org/openqa/selenium/edge/edgehtml/module-info.txt b/java/client/src/org/openqa/selenium/edge/edgehtml/module-info.txt new file mode 100644 index 0000000000000..99209b196146a --- /dev/null +++ b/java/client/src/org/openqa/selenium/edge/edgehtml/module-info.txt @@ -0,0 +1,33 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +module org.openqa.selenium.edge.edgehtml { + requires transitive com.google.common; + requires transitive org.openqa.selenium.core; + requires transitive org.openqa.selenium.remote; + requires transitive org.openqa.seleniun.chromium; + requires transitive org.openqa.selenium.edge; + + exports org.openqa.selenium.edge.edgehtml; + + provides org.openqa.selenium.WebDriverInfo with + org.openqa.selenium.edge.edgehtml.EdgeHtmlDriverInfo; + + provides org.openqa.selenium.remote.service.DriverService$Builder with + org.openqa.selenium.edge.edgehtml.EdgeHtmlDriverService$Builder; + +} diff --git a/java/client/src/org/openqa/selenium/edge/module-info.txt b/java/client/src/org/openqa/selenium/edge/module-info.txt index 20dc311d09ef3..2155f36ce8daa 100644 --- a/java/client/src/org/openqa/selenium/edge/module-info.txt +++ b/java/client/src/org/openqa/selenium/edge/module-info.txt @@ -23,9 +23,10 @@ module org.openqa.selenium.edge { exports org.openqa.selenium.edge; provides org.openqa.selenium.WebDriverInfo with - org.openqa.selenium.edge.EdgeDriverInfo; + org.openqa.selenium.edge.ChromiumEdgeDriverInfo; provides org.openqa.selenium.remote.service.DriverService$Builder with - org.openqa.selenium.edge.EdgeDriverService$Builder; + org.openqa.selenium.edge.ChromiumEdgeDriverService$Builder; + } diff --git a/java/client/test/com/thoughtworks/selenium/BUCK b/java/client/test/com/thoughtworks/selenium/BUCK index 2f4c3728a3fd4..8907483041a00 100644 --- a/java/client/test/com/thoughtworks/selenium/BUCK +++ b/java/client/test/com/thoughtworks/selenium/BUCK @@ -55,7 +55,7 @@ java_library( "//java/client/src/com/thoughtworks/selenium:leg-rc", "//java/client/src/org/openqa/selenium:selenium", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/opera:opera", diff --git a/java/client/test/com/thoughtworks/selenium/InternalSelenseTestBase.java b/java/client/test/com/thoughtworks/selenium/InternalSelenseTestBase.java index 67dd4feb7a56e..c6ff90f95107e 100644 --- a/java/client/test/com/thoughtworks/selenium/InternalSelenseTestBase.java +++ b/java/client/test/com/thoughtworks/selenium/InternalSelenseTestBase.java @@ -171,6 +171,7 @@ private Capabilities createCapabilities() { return new ChromeOptions(); case EDGE: + case CHROMIUMEDGE: return new EdgeOptions(); case IE: diff --git a/java/client/test/org/openqa/selenium/AlertsTest.java b/java/client/test/org/openqa/selenium/AlertsTest.java index e63e57473f55e..ab11b85d083b5 100644 --- a/java/client/test/org/openqa/selenium/AlertsTest.java +++ b/java/client/test/org/openqa/selenium/AlertsTest.java @@ -25,6 +25,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated; import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -190,6 +191,7 @@ public void testShouldAllowAUserToSetTheValueOfAPrompt() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) public void testSettingTheValueOfAnAlertThrows() { driver.get(alertPage("cheese")); @@ -358,6 +360,7 @@ public void testHandlesTwoAlertsFromOneInteraction() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) public void testShouldHandleAlertOnPageLoad() { String pageWithOnLoad = appServer.create(new Page() .withOnLoad("javascript:alert(\"onload\")") @@ -390,6 +393,7 @@ public void testShouldHandleAlertOnPageLoadUsingGet() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(FIREFOX) @Ignore(value = IE, reason = "Fails in versions 6 and 7") @Ignore(SAFARI) @@ -423,6 +427,7 @@ public void testShouldNotHandleAlertInAnotherWindow() { @Test @Ignore(value = CHROME, reason = "Chrome does not trigger alerts on unload") + @Ignore(value = CHROMIUMEDGE, reason = "Edge does not trigger alerts on unload") @NotYetImplemented(HTMLUNIT) @Ignore(SAFARI) @NotYetImplemented(EDGE) @@ -451,6 +456,7 @@ public void testShouldHandleAlertOnPageUnload() { @Ignore(value = FIREFOX, reason = "Non W3C conformant") @Ignore(value = HTMLUNIT, reason = "Non W3C conformant") @Ignore(value = CHROME, reason = "Non W3C conformant") + @Ignore(value = CHROMIUMEDGE, reason = "Non W3C conformant") @Ignore(EDGE) public void testShouldImplicitlyHandleAlertOnPageBeforeUnload() { String blank = appServer.create(new Page().withTitle("Success")); @@ -467,6 +473,7 @@ public void testShouldImplicitlyHandleAlertOnPageBeforeUnload() { @Test @Ignore(value = CHROME, reason = "Chrome does not trigger alerts on unload") + @Ignore(value = CHROMIUMEDGE, reason = "Chrome does not trigger alerts on unload") @NotYetImplemented(HTMLUNIT) @Ignore(SAFARI) @Ignore(value = IE, reason = "IE driver automatically dismisses alerts on window close") @@ -502,6 +509,7 @@ public void testShouldHandleAlertOnWindowClose() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(value = HTMLUNIT, reason = "https://github.com/SeleniumHQ/htmlunit-driver/issues/57") @NotYetImplemented(value = MARIONETTE, reason = "https://bugzilla.mozilla.org/show_bug.cgi?id=1279211") diff --git a/java/client/test/org/openqa/selenium/ClearTest.java b/java/client/test/org/openqa/selenium/ClearTest.java index e3dcb6c516fd2..737567fc201a2 100644 --- a/java/client/test/org/openqa/selenium/ClearTest.java +++ b/java/client/test/org/openqa/selenium/ClearTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -138,6 +139,7 @@ public void shouldBeAbleToClearRangeInput() { @Test @NotYetImplemented(CHROME) + @NotYetImplemented(CHROMIUMEDGE) @NotYetImplemented(FIREFOX) @NotYetImplemented(MARIONETTE) @NotYetImplemented(IE) diff --git a/java/client/test/org/openqa/selenium/ClickScrollingTest.java b/java/client/test/org/openqa/selenium/ClickScrollingTest.java index 3605ea321589e..e435a25e3557d 100644 --- a/java/client/test/org/openqa/selenium/ClickScrollingTest.java +++ b/java/client/test/org/openqa/selenium/ClickScrollingTest.java @@ -24,6 +24,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.testing.drivers.Browser.ALL; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -62,7 +63,7 @@ public void testClickingOnAnchorScrollsPage() { // the link will scroll it in to view, which is a few pixels further than 0 // According to documentation at https://developer.mozilla.org/en-US/docs/Web/API/Window/pageYOffset // window.pageYOffset may not return integer value. - // With the following changes in below we are checking the type of returned object and assigning respectively + // With the following changes in below we are checking the type of returned object and assigning respectively // the value of 'yOffset' if ( x instanceof Long ) { @@ -134,6 +135,7 @@ public void testShouldNotScrollOverflowElementsWhichAreVisible() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(MARIONETTE) @NotYetImplemented(EDGE) public void testShouldNotScrollIfAlreadyScrolledAndElementIsInView() { diff --git a/java/client/test/org/openqa/selenium/ClickTest.java b/java/client/test/org/openqa/selenium/ClickTest.java index 1c188d23dbd10..cf0408469ac86 100644 --- a/java/client/test/org/openqa/selenium/ClickTest.java +++ b/java/client/test/org/openqa/selenium/ClickTest.java @@ -24,6 +24,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.testing.drivers.Browser.ALL; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -348,6 +349,7 @@ public void testShouldBeAbleToClickOnASpanThatWrapsToTheNextLine() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(MARIONETTE) @NotYetImplemented(SAFARI) diff --git a/java/client/test/org/openqa/selenium/ContentEditableTest.java b/java/client/test/org/openqa/selenium/ContentEditableTest.java index d0e4a9a2d857c..99d6a7ed070f4 100644 --- a/java/client/test/org/openqa/selenium/ContentEditableTest.java +++ b/java/client/test/org/openqa/selenium/ContentEditableTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assume.assumeFalse; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.MARIONETTE; @@ -86,6 +87,7 @@ public void testShouldBeAbleToTypeIntoEmptyContentEditableElement() { @Test @NotYetImplemented(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2743") + @NotYetImplemented(value = CHROMIUMEDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2743") @NotYetImplemented(SAFARI) @NotYetImplemented(EDGE) @NotYetImplemented(value = MARIONETTE, reason = "https://github.com/mozilla/geckodriver/issues/667") @@ -114,6 +116,7 @@ public void testShouldBeAbleToTypeIntoTinyMCE() { @Test @NotYetImplemented(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2743") + @NotYetImplemented(value = CHROMIUMEDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2743") @NotYetImplemented(value = IE, reason = "Prepends text") @NotYetImplemented(value = SAFARI, reason = "Prepends text") @NotYetImplemented(value = MARIONETTE, reason = "https://github.com/mozilla/geckodriver/issues/667") @@ -131,6 +134,7 @@ public void testShouldAppendToTinyMCE() { @Test @NotYetImplemented(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2743") + @NotYetImplemented(value = CHROMIUMEDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2743") @NotYetImplemented(value = MARIONETTE, reason = "Doesn't write anything") @NotYetImplemented(value = SAFARI, reason = "Prepends text") public void appendsTextToEndOfContentEditableWithMultipleTextNodes() { diff --git a/java/client/test/org/openqa/selenium/CookieImplementationTest.java b/java/client/test/org/openqa/selenium/CookieImplementationTest.java index 10ebf0bc1e6d5..b6a883708f75f 100644 --- a/java/client/test/org/openqa/selenium/CookieImplementationTest.java +++ b/java/client/test/org/openqa/selenium/CookieImplementationTest.java @@ -21,6 +21,7 @@ import static org.junit.Assume.assumeTrue; import static org.openqa.selenium.testing.drivers.Browser.ALL; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.MARIONETTE; @@ -197,6 +198,7 @@ public void testAddCookiesWithDifferentPathsThatAreRelatedToOurs() { @SwitchToTopAfterTest @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(SAFARI) @NotYetImplemented(MARIONETTE) public void testGetCookiesInAFrame() { @@ -471,6 +473,7 @@ public void testDeleteNotExistedCookie() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(FIREFOX) @Ignore(IE) @Ignore(SAFARI) diff --git a/java/client/test/org/openqa/selenium/CorrectEventFiringTest.java b/java/client/test/org/openqa/selenium/CorrectEventFiringTest.java index d45201cd3801f..59f858c2e66d8 100644 --- a/java/client/test/org/openqa/selenium/CorrectEventFiringTest.java +++ b/java/client/test/org/openqa/selenium/CorrectEventFiringTest.java @@ -26,6 +26,7 @@ import static org.openqa.selenium.WaitingConditions.elementValueToEqual; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -477,6 +478,7 @@ public void testClickOverlappingElements() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(MARIONETTE) @NotYetImplemented(SAFARI) @@ -502,6 +504,7 @@ public void testClickPartiallyOverlappingElements() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(FIREFOX) @Ignore(SAFARI) @Ignore(HTMLUNIT) diff --git a/java/client/test/org/openqa/selenium/ElementAttributeTest.java b/java/client/test/org/openqa/selenium/ElementAttributeTest.java index 33b283de5bfe2..cac15a4b4cce8 100644 --- a/java/client/test/org/openqa/selenium/ElementAttributeTest.java +++ b/java/client/test/org/openqa/selenium/ElementAttributeTest.java @@ -22,6 +22,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.Assume.assumeFalse; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -415,6 +416,7 @@ public void shouldTreatContenteditableAsEnumeratedButNotBoolean() { @Test @NotYetImplemented(IE) @NotYetImplemented(CHROME) + @NotYetImplemented(CHROMIUMEDGE) @NotYetImplemented(MARIONETTE) @Ignore(FIREFOX) @NotYetImplemented(HTMLUNIT) diff --git a/java/client/test/org/openqa/selenium/ElementFindingTest.java b/java/client/test/org/openqa/selenium/ElementFindingTest.java index 65b431479c8c6..4a3345b1e29a8 100644 --- a/java/client/test/org/openqa/selenium/ElementFindingTest.java +++ b/java/client/test/org/openqa/selenium/ElementFindingTest.java @@ -21,6 +21,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.Assume.assumeFalse; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.MARIONETTE; @@ -443,6 +444,7 @@ public void testShouldBeAbleToFindElementByXPathWithNamespace() { @Ignore(IE) @NotYetImplemented(SAFARI) @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @NotYetImplemented(EDGE) public void testShouldBeAbleToFindElementByXPathInXmlDocument() { driver.get(pages.simpleXmlDocument); diff --git a/java/client/test/org/openqa/selenium/ExecutingAsyncJavascriptTest.java b/java/client/test/org/openqa/selenium/ExecutingAsyncJavascriptTest.java index 0d08b46971bb4..2cb9da29e5b65 100644 --- a/java/client/test/org/openqa/selenium/ExecutingAsyncJavascriptTest.java +++ b/java/client/test/org/openqa/selenium/ExecutingAsyncJavascriptTest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.Assume.assumeTrue; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -211,6 +212,7 @@ public void shouldNotTimeoutWithMultipleCallsTheFirstOneBeingSynchronous() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @NotYetImplemented(SAFARI) @Ignore(MARIONETTE) @@ -305,6 +307,7 @@ public void shouldBeAbleToMakeXMLHttpRequestsAndWaitForTheResponse() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(EDGE) @Ignore(MARIONETTE) @@ -322,6 +325,7 @@ public void throwsIfScriptTriggersAlert() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(EDGE) @Ignore(MARIONETTE) @@ -338,6 +342,7 @@ public void throwsIfAlertHappensDuringScript() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(EDGE) @Ignore(MARIONETTE) @@ -356,6 +361,7 @@ public void throwsIfScriptTriggersAlertWhichTimesOut() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(EDGE) @Ignore(MARIONETTE) @@ -372,6 +378,7 @@ public void throwsIfAlertHappensDuringScriptWhichTimesOut() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(MARIONETTE) @Ignore(value = SAFARI, reason = "Does not support alerts yet") diff --git a/java/client/test/org/openqa/selenium/ExecutingJavascriptTest.java b/java/client/test/org/openqa/selenium/ExecutingJavascriptTest.java index 31f0c3a28e93e..4056063cc2271 100644 --- a/java/client/test/org/openqa/selenium/ExecutingJavascriptTest.java +++ b/java/client/test/org/openqa/selenium/ExecutingJavascriptTest.java @@ -25,6 +25,7 @@ import static org.junit.Assume.assumeTrue; import static org.openqa.selenium.By.id; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -244,6 +245,7 @@ public void testShouldThrowAnExceptionWhenTheJavascriptIsBad() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @NotYetImplemented(SAFARI) @Ignore(MARIONETTE) @@ -484,6 +486,7 @@ public void testShouldThrowAnExceptionWhenArgumentsWithStaleElementPassed() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) public void testShouldBeAbleToReturnADateObject() { driver.get(pages.simpleTestPage); @@ -499,6 +502,7 @@ public void testShouldBeAbleToReturnADateObject() { @Test(timeout = 10000) @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @NotYetImplemented(SAFARI) @NotYetImplemented(value = MARIONETTE, reason = "https://bugzilla.mozilla.org/show_bug.cgi?id=1502656") @@ -525,6 +529,7 @@ public void shouldHandleObjectThatThatHaveToJSONMethod() { @Test(timeout = 10000) @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(value = IE, issue = "540") @Ignore(HTMLUNIT) public void shouldHandleRecursiveStructures() { diff --git a/java/client/test/org/openqa/selenium/FrameSwitchingTest.java b/java/client/test/org/openqa/selenium/FrameSwitchingTest.java index 7256a6e5bfc5a..f4e5726b15859 100644 --- a/java/client/test/org/openqa/selenium/FrameSwitchingTest.java +++ b/java/client/test/org/openqa/selenium/FrameSwitchingTest.java @@ -25,6 +25,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.textToBe; import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -453,6 +454,7 @@ public void testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUsWithWe @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(value = MARIONETTE, issue = "https://github.com/mozilla/geckodriver/issues/614") @NotYetImplemented(HTMLUNIT) @@ -487,6 +489,7 @@ public void testJavaScriptShouldExecuteInTheContextOfTheCurrentFrame() { @Test @Ignore(value = CHROME, reason = "Unstable") + @Ignore(value = CHROMIUMEDGE, reason = "Unstable") public void testShouldNotSwitchMagicallyToTheTopWindow() { String baseUrl = appServer.whereIs("frame_switching_tests/"); driver.get(baseUrl + "bug4876.html"); diff --git a/java/client/test/org/openqa/selenium/I18nTest.java b/java/client/test/org/openqa/selenium/I18nTest.java index 702ea1ec4d7fa..9d81a2079ae36 100644 --- a/java/client/test/org/openqa/selenium/I18nTest.java +++ b/java/client/test/org/openqa/selenium/I18nTest.java @@ -21,6 +21,7 @@ import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -87,6 +88,7 @@ public void testEnteringHebrewTextFromRightToLeft() { @Test @Ignore(value = CHROME, reason = "ChromeDriver only supports characters in the BMP") + @Ignore(value = CHROMIUMEDGE, reason = "EdgeDriver only supports characters in the BMP") public void testEnteringSupplementaryCharacters() { assumeFalse("IE: versions less thank 10 have issue 5069", TestUtilities.isInternetExplorer(driver) && @@ -121,6 +123,7 @@ public void testShouldBeAbleToReturnTheTextInAPage() { @Test @Ignore(IE) @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(FIREFOX) @Ignore(MARIONETTE) @NotYetImplemented(HTMLUNIT) @@ -172,6 +175,7 @@ public void testShouldBeAbleToActivateIMEEngine() throws InterruptedException { @Test @Ignore(IE) @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(FIREFOX) public void testShouldBeAbleToInputJapanese() { assumeTrue("IME is supported on Linux only.", diff --git a/java/client/test/org/openqa/selenium/MiscTest.java b/java/client/test/org/openqa/selenium/MiscTest.java index eba3827050cb0..9c6d8dd701295 100644 --- a/java/client/test/org/openqa/selenium/MiscTest.java +++ b/java/client/test/org/openqa/selenium/MiscTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.openqa.selenium.testing.drivers.Browser.ALL; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE;; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.SAFARI; @@ -68,6 +69,7 @@ public void testShouldReturnTheSourceOfAPage() { @Test @Ignore(value = CHROME, reason = "returns XML content formatted for display as HTML document") + @Ignore(value = CHROMIUMEDGE, reason = "returns XML content formatted for display as HTML document") @NotYetImplemented(value = SAFARI, reason = "returns XML content formatted for display as HTML document") @Ignore(IE) @NotYetImplemented(EDGE) diff --git a/java/client/test/org/openqa/selenium/PageLoadingTest.java b/java/client/test/org/openqa/selenium/PageLoadingTest.java index b48c8d52932d9..a914303eddb5e 100644 --- a/java/client/test/org/openqa/selenium/PageLoadingTest.java +++ b/java/client/test/org/openqa/selenium/PageLoadingTest.java @@ -30,6 +30,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE;; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -81,6 +82,7 @@ public void testNoneStrategyShouldNotWaitForPageToLoad() { @NoDriverBeforeTest @NoDriverAfterTest @Ignore(value = CHROME, reason = "Flaky") + @Ignore(value = CHROMIUMEDGE, reason = "Flaky") public void testNoneStrategyShouldNotWaitForPageToRefresh() { initDriverWithLoadStrategy("none"); @@ -102,6 +104,7 @@ public void testNoneStrategyShouldNotWaitForPageToRefresh() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @NeedsLocalEnvironment @NoDriverBeforeTest @NoDriverAfterTest @@ -125,6 +128,7 @@ public void testEagerStrategyShouldNotWaitForResources() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @NeedsLocalEnvironment @NoDriverBeforeTest @NoDriverAfterTest @@ -151,6 +155,7 @@ public void testEagerStrategyShouldNotWaitForResourcesOnRefresh() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @NoDriverBeforeTest @NoDriverAfterTest public void testEagerStrategyShouldWaitForDocumentToBeLoaded() { @@ -413,6 +418,7 @@ public void testShouldTimeoutIfAPageTakesTooLongToLoadAfterClick() { @Test @NeedsLocalEnvironment @Ignore(value = CHROME, reason = "Flaky") + @Ignore(value = CHROMIUMEDGE, reason = "Flaky") public void testShouldTimeoutIfAPageTakesTooLongToRefresh() { // Get the sleeping servlet with a pause of 5 seconds String slowPage = appServer.whereIs("sleep?time=5"); @@ -444,6 +450,7 @@ public void testShouldTimeoutIfAPageTakesTooLongToRefresh() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @NotYetImplemented(value = SAFARI) @NotYetImplemented(HTMLUNIT) @NeedsLocalEnvironment diff --git a/java/client/test/org/openqa/selenium/PositionAndSizeTest.java b/java/client/test/org/openqa/selenium/PositionAndSizeTest.java index e46801428e6a3..cd3b902530c63 100644 --- a/java/client/test/org/openqa/selenium/PositionAndSizeTest.java +++ b/java/client/test/org/openqa/selenium/PositionAndSizeTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assume.assumeFalse; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -165,6 +166,7 @@ public void testShouldCorrectlyIdentifyThatAnElementHasWidthAndHeight() { @Test @Ignore(IE) @Ignore(value = CHROME, reason = "WebKit bug 28804") + @Ignore(value = CHROMIUMEDGE, reason = "WebKit bug 28804") @NotYetImplemented(SAFARI) @Ignore(MARIONETTE) public void testShouldHandleNonIntegerPositionAndSize() { diff --git a/java/client/test/org/openqa/selenium/SlowLoadingPageTest.java b/java/client/test/org/openqa/selenium/SlowLoadingPageTest.java index c49b1a25c0d9e..d6185d4146ea1 100644 --- a/java/client/test/org/openqa/selenium/SlowLoadingPageTest.java +++ b/java/client/test/org/openqa/selenium/SlowLoadingPageTest.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import org.junit.Test; import org.openqa.selenium.testing.Ignore; @@ -45,6 +46,7 @@ public void testShouldBlockUntilIFramesAreLoaded() { @Test @Ignore(value = CHROME, travis = true) + @Ignore(value = CHROMIUMEDGE) public void testRefreshShouldBlockUntilPageLoads() { long start = System.currentTimeMillis(); driver.get(pages.sleepingPage + "?time=" + LOAD_TIME_IN_SECONDS); diff --git a/java/client/test/org/openqa/selenium/SvgDocumentTest.java b/java/client/test/org/openqa/selenium/SvgDocumentTest.java index 1248acefbce7a..2496d1f3c36b5 100644 --- a/java/client/test/org/openqa/selenium/SvgDocumentTest.java +++ b/java/client/test/org/openqa/selenium/SvgDocumentTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assume.assumeFalse; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.SAFARI; import static org.openqa.selenium.testing.TestUtilities.getFirefoxVersion; @@ -35,6 +36,7 @@ public class SvgDocumentTest extends JUnit4TestBase { @Test @Ignore(value = CHROME, reason = "chromedriver needs to update atoms for latest SVG support") + @Ignore(value = CHROMIUMEDGE, reason = "msedgedriver needs to update atoms for latest SVG support") @Ignore(value = HTMLUNIT, reason = "test should enable JavaScript") @NotYetImplemented(SAFARI) public void testClickOnSvgElement() { diff --git a/java/client/test/org/openqa/selenium/TakesScreenshotTest.java b/java/client/test/org/openqa/selenium/TakesScreenshotTest.java index 8a6b9bf797377..56b3e65bb1303 100644 --- a/java/client/test/org/openqa/selenium/TakesScreenshotTest.java +++ b/java/client/test/org/openqa/selenium/TakesScreenshotTest.java @@ -24,6 +24,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfAllElementsLocatedBy; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -154,6 +155,7 @@ public void testShouldCaptureScreenshotOfAnElement() throws Exception { @Test @Ignore(value = CHROME, reason = "takes only visible viewport") + @Ignore(value = CHROMIUMEDGE, reason = "takes only visible viewport") @Ignore(MARIONETTE) @Ignore(value = IE, reason = "takes only visible viewport") @NotYetImplemented(SAFARI) @@ -177,6 +179,7 @@ public void testShouldCaptureScreenshotOfPageWithLongX() { @Test @Ignore(value = CHROME, reason = "takes only visible viewport") + @Ignore(value = CHROMIUMEDGE, reason = "takes only visible viewport") @Ignore(MARIONETTE) @Ignore(value = IE, reason = "takes only visible viewport") @NotYetImplemented(SAFARI) @@ -202,6 +205,7 @@ public void testShouldCaptureScreenshotOfPageWithLongY() { @Ignore(value = IE, reason = "cuts captured image at driver level") @Ignore(value = FIREFOX, reason = "captured image is cut at driver level") @Ignore(value = CHROME, reason = "takes only visible viewport") + @Ignore(value = CHROMIUMEDGE, reason = "takes only visible viewport") @Ignore(MARIONETTE) @NotYetImplemented(SAFARI) @Ignore(EDGE) @@ -226,6 +230,7 @@ public void testShouldCaptureScreenshotOfPageWithTooLongX() { @Ignore(value = IE, reason = "cuts captured image at driver level") @Ignore(value = FIREFOX, reason = "captured image is cut at driver level") @Ignore(value = CHROME, reason = "takes only visible viewport") + @Ignore(value = CHROMIUMEDGE, reason = "takes only visible viewport") @Ignore(MARIONETTE) @NotYetImplemented(SAFARI) @Ignore(EDGE) @@ -251,6 +256,7 @@ public void testShouldCaptureScreenshotOfPageWithTooLongY() { @Ignore(value = FIREFOX, reason = "failed due NS_ERROR_FAILURE at context.drawWindow") @NotYetImplemented(value = SAFARI, reason = "An unknown server-side error") @Ignore(value = CHROME, reason = "takes only visible viewport") + @Ignore(value = CHROMIUMEDGE, reason = "takes only visible viewport") @Ignore(MARIONETTE) @Ignore(EDGE) public void testShouldCaptureScreenshotOfPageWithTooLongXandY() { @@ -304,6 +310,7 @@ public void testShouldCaptureScreenshotAtFramePage() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) public void testShouldCaptureScreenshotAtIFramePage() { driver.get(appServer.whereIs("screen/screen_iframes.html")); @@ -359,6 +366,7 @@ public void testShouldCaptureScreenshotAtFramePageAfterSwitching() { @SwitchToTopAfterTest @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(MARIONETTE) public void testShouldCaptureScreenshotAtIFramePageAfterSwitching() { driver.get(appServer.whereIs("screen/screen_iframes.html")); diff --git a/java/client/test/org/openqa/selenium/TextHandlingTest.java b/java/client/test/org/openqa/selenium/TextHandlingTest.java index 4b4a8bb7b1082..ee470a0b37fbf 100644 --- a/java/client/test/org/openqa/selenium/TextHandlingTest.java +++ b/java/client/test/org/openqa/selenium/TextHandlingTest.java @@ -21,6 +21,7 @@ import static org.junit.Assume.assumeFalse; import static org.openqa.selenium.testing.drivers.Browser.ALL; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -412,6 +413,7 @@ public void canHandleTextThatLooksLikeANumber() { @Test @NotYetImplemented(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2155") + @NotYetImplemented(value = CHROMIUMEDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=2155") @NotYetImplemented(HTMLUNIT) @NotYetImplemented(value = SAFARI, reason = "getText does not normalize spaces") @NotYetImplemented(EDGE) diff --git a/java/client/test/org/openqa/selenium/TextPagesTest.java b/java/client/test/org/openqa/selenium/TextPagesTest.java index 033e7f7c6554f..44f0016b59e05 100644 --- a/java/client/test/org/openqa/selenium/TextPagesTest.java +++ b/java/client/test/org/openqa/selenium/TextPagesTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.MARIONETTE; @@ -52,6 +53,7 @@ public void testShouldBeAbleToLoadASimplePageOfText() { @Ignore(value = IE, reason = "creates DOM for displaying text pages") @Ignore(value = SAFARI, reason = "creates DOM for displaying text pages") @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(MARIONETTE) @NotYetImplemented(EDGE) public void testShouldThrowExceptionWhenAddingCookieToAPageThatIsNotHtml() { diff --git a/java/client/test/org/openqa/selenium/UnexpectedAlertBehaviorTest.java b/java/client/test/org/openqa/selenium/UnexpectedAlertBehaviorTest.java index 3e7fe51ef85cd..fcf6a95bd0d91 100644 --- a/java/client/test/org/openqa/selenium/UnexpectedAlertBehaviorTest.java +++ b/java/client/test/org/openqa/selenium/UnexpectedAlertBehaviorTest.java @@ -22,6 +22,7 @@ import static org.openqa.selenium.WaitingConditions.elementTextToEqual; import static org.openqa.selenium.remote.CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.SAFARI; @@ -41,6 +42,7 @@ public class UnexpectedAlertBehaviorTest extends JUnit4TestBase { @Test @Ignore(value = FIREFOX, reason = "Legacy behaviour, not W3C conformant") @Ignore(value = CHROME, reason = "Legacy behaviour, not W3C conformant") + @Ignore(value = CHROMIUMEDGE, reason = "Legacy behaviour, not W3C conformant") @Ignore(value = HTMLUNIT, reason = "Legacy behaviour, not W3C conformant") @NoDriverBeforeTest public void canAcceptUnhandledAlert() { @@ -50,6 +52,7 @@ public void canAcceptUnhandledAlert() { @Test @Ignore(value = FIREFOX, reason = "Legacy behaviour, not W3C conformant") @Ignore(value = CHROME, reason = "Legacy behaviour, not W3C conformant") + @Ignore(value = CHROMIUMEDGE, reason = "Legacy behaviour, not W3C conformant") @Ignore(value = HTMLUNIT, reason = "Legacy behaviour, not W3C conformant") @NoDriverBeforeTest public void canSilentlyAcceptUnhandledAlert() { @@ -58,6 +61,7 @@ public void canSilentlyAcceptUnhandledAlert() { @Test @Ignore(value = CHROME, reason = "Unstable Chrome behavior") + @Ignore(value = CHROMIUMEDGE, reason = "Unstable Chrome behavior") @Ignore(value = HTMLUNIT, reason = "Legacy behaviour, not W3C conformant") @NoDriverBeforeTest public void canDismissUnhandledAlert() { @@ -67,6 +71,7 @@ public void canDismissUnhandledAlert() { @Test @Ignore(value = FIREFOX, reason = "Legacy behaviour, not W3C conformant") @Ignore(value = CHROME, reason = "Legacy behaviour, not W3C conformant") + @Ignore(value = CHROMIUMEDGE, reason = "Legacy behaviour, not W3C conformant") @Ignore(value = HTMLUNIT, reason = "Legacy behaviour, not W3C conformant") @NoDriverBeforeTest public void canSilentlyDismissUnhandledAlert() { @@ -75,6 +80,7 @@ public void canSilentlyDismissUnhandledAlert() { @Test @Ignore(value = CHROME, reason = "Chrome uses IGNORE mode by default") + @Ignore(value = CHROMIUMEDGE, reason = "Edge uses IGNORE mode by default") @NoDriverBeforeTest public void canDismissUnhandledAlertsByDefault() { runScenarioWithUnhandledAlert(null, "null", false); @@ -82,6 +88,7 @@ public void canDismissUnhandledAlertsByDefault() { @Test @Ignore(value = CHROME, reason = "Unstable Chrome behavior") + @Ignore(value = CHROMIUMEDGE, reason = "Unstable Chrome behavior") @NoDriverBeforeTest public void canIgnoreUnhandledAlert() { assertThatExceptionOfType(UnhandledAlertException.class).isThrownBy( diff --git a/java/client/test/org/openqa/selenium/UploadTest.java b/java/client/test/org/openqa/selenium/UploadTest.java index 9624c61951970..1a958379b3459 100644 --- a/java/client/test/org/openqa/selenium/UploadTest.java +++ b/java/client/test/org/openqa/selenium/UploadTest.java @@ -25,6 +25,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.not; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOf; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -96,6 +97,7 @@ public void testCleanFileInput() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(HTMLUNIT) public void testClickFileInput() { driver.get(pages.uploadPage); diff --git a/java/client/test/org/openqa/selenium/WindowSwitchingTest.java b/java/client/test/org/openqa/selenium/WindowSwitchingTest.java index 076d3f0b22a49..54bec2fcb8b6b 100644 --- a/java/client/test/org/openqa/selenium/WindowSwitchingTest.java +++ b/java/client/test/org/openqa/selenium/WindowSwitchingTest.java @@ -26,6 +26,7 @@ import static org.openqa.selenium.WaitingConditions.windowHandleCountToBeGreaterThan; import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -363,6 +364,7 @@ public void testShouldFocusOnTheTopMostFrameAfterSwitchingToAWindow() { @NoDriverAfterTest(failedOnly = true) @Test @NotYetImplemented(CHROME) + @NotYetImplemented(CHROMIUMEDGE) @NotYetImplemented(HTMLUNIT) @NotYetImplemented(SAFARI) // actually not tested in this browser @NotYetImplemented(OPERABLINK) diff --git a/java/client/test/org/openqa/selenium/edge/BUCK b/java/client/test/org/openqa/selenium/edge/BUCK new file mode 100644 index 0000000000000..8a6a463b0ed3b --- /dev/null +++ b/java/client/test/org/openqa/selenium/edge/BUCK @@ -0,0 +1,47 @@ +java_test( + name = "edge", + srcs = [ + "EdgeDriverTests.java", + ], + vm_args = [ + "-Dselenium.browser=edge", + "-Dwebdriver.edge.edgehtml=false" + ], + deps = [ + ":tests", + "//java/client/test/org/openqa/selenium:large-tests", + "//third_party/java/junit:junit", + ], +) + +java_test( + name = "edgehtml", + srcs = [ + "EdgeDriverTests.java", + ], + vm_args = [ + "-Dselenium.browser=edge" + ], + deps = [ + ":tests", + "//java/client/test/org/openqa/selenium:large-tests", + "//third_party/java/junit:junit", + ], +) + +java_library( + name = "tests", + srcs = glob(["*Test.java"]), + deps = [ + "//java/client/src/org/openqa/selenium:selenium", + "//java/client/src/org/openqa/selenium/chrome:chrome", + "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/remote:remote", + "//java/client/src/org/openqa/selenium/support/ui:wait", + "//java/client/test/org/openqa/selenium/build:build", + "//java/client/test/org/openqa/selenium/testing:test-base", + "//third_party/java/assertj:assertj", + "//third_party/java/guava:guava", + "//third_party/java/junit:junit", + ], +) diff --git a/java/client/test/org/openqa/selenium/edge/EdgeDriverTests.java b/java/client/test/org/openqa/selenium/edge/EdgeDriverTests.java new file mode 100644 index 0000000000000..e2e21a495939f --- /dev/null +++ b/java/client/test/org/openqa/selenium/edge/EdgeDriverTests.java @@ -0,0 +1,31 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.openqa.selenium.edge; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.openqa.selenium.StandardSeleniumTests; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + StandardSeleniumTests.class, + EdgeOptionsFunctionalTest.class +}) +public class EdgeDriverTests { + +} \ No newline at end of file diff --git a/java/client/test/org/openqa/selenium/edge/EdgeOptionsFunctionalTest.java b/java/client/test/org/openqa/selenium/edge/EdgeOptionsFunctionalTest.java new file mode 100644 index 0000000000000..c63630aa8a76b --- /dev/null +++ b/java/client/test/org/openqa/selenium/edge/EdgeOptionsFunctionalTest.java @@ -0,0 +1,117 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.openqa.selenium.edge; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openqa.selenium.remote.CapabilityType.ACCEPT_INSECURE_CERTS; +import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; +import static org.openqa.selenium.testing.drivers.Browser.EDGE; + +import org.junit.After; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.build.InProject; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.openqa.selenium.testing.Ignore; +import org.openqa.selenium.testing.JUnit4TestBase; + +import java.io.IOException; +import java.nio.file.Files; +import java.util.Base64; + +public class EdgeOptionsFunctionalTest extends JUnit4TestBase { + + private static final String EXT_PATH = "third_party/chrome_ext/backspace.crx"; + + private EdgeDriver edgeDriver = null; + + @After + public void tearDown() { + if (edgeDriver != null) { + edgeDriver.quit(); + } + } + + @Test + @Ignore(EDGE) + public void canStartChromeWithCustomOptions() { + EdgeOptions options = new EdgeOptions(); + options.addArguments("user-agent=foo;bar"); + edgeDriver = new EdgeDriver(options); + + edgeDriver.get(pages.clickJacker); + Object userAgent = edgeDriver.executeScript("return window.navigator.userAgent"); + assertThat(userAgent).isEqualTo("foo;bar"); + } + + @Test + @Ignore(EDGE) + public void optionsStayEqualAfterSerialization() { + EdgeOptions options1 = new EdgeOptions(); + EdgeOptions options2 = new EdgeOptions(); + assertThat(options2).isEqualTo(options1); + options1.asMap(); + assertThat(options2).isEqualTo(options1); + } + + @Test + @Ignore(EDGE) + public void canSetAcceptInsecureCerts() { + EdgeOptions options = new EdgeOptions(); + options.setAcceptInsecureCerts(true); + edgeDriver = new EdgeDriver(options); + System.out.println(edgeDriver.getCapabilities()); + + assertThat(edgeDriver.getCapabilities().getCapability(ACCEPT_INSECURE_CERTS)).isEqualTo(true); + } + + @Test + @Ignore(EDGE) + public void canAddExtensionFromFile() { + EdgeOptions options = new EdgeOptions(); + options.addExtensions(InProject.locate(EXT_PATH).toFile()); + edgeDriver = new EdgeDriver(options); + + edgeDriver.get(pages.clicksPage); + + edgeDriver.findElement(By.id("normal")).click(); + new WebDriverWait(edgeDriver, 10).until(titleIs("XHTML Test Page")); + + edgeDriver.findElement(By.tagName("body")).sendKeys(Keys.BACK_SPACE); + new WebDriverWait(edgeDriver, 10).until(titleIs("clicks")); + } + + @Test + @Ignore(EDGE) + public void canAddExtensionFromStringEncodedInBase64() throws IOException { + EdgeOptions options = new EdgeOptions(); + options.addEncodedExtensions(Base64.getEncoder().encodeToString( + Files.readAllBytes(InProject.locate(EXT_PATH)))); + edgeDriver = new EdgeDriver(options); + + edgeDriver.get(pages.clicksPage); + + edgeDriver.findElement(By.id("normal")).click(); + new WebDriverWait(edgeDriver, 10).until(titleIs("XHTML Test Page")); + + edgeDriver.findElement(By.tagName("body")).sendKeys(Keys.BACK_SPACE); + new WebDriverWait(edgeDriver, 10).until(titleIs("clicks")); + } + +} diff --git a/java/client/test/org/openqa/selenium/html5/LocationContextTest.java b/java/client/test/org/openqa/selenium/html5/LocationContextTest.java index b245b1299f625..4e587d3e6eb70 100644 --- a/java/client/test/org/openqa/selenium/html5/LocationContextTest.java +++ b/java/client/test/org/openqa/selenium/html5/LocationContextTest.java @@ -21,6 +21,7 @@ import static org.assertj.core.api.Assertions.byLessThan; import static org.junit.Assume.assumeTrue; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import org.junit.Before; import org.junit.Test; @@ -56,6 +57,7 @@ public void testShouldSetAndGetLongitude() { @Test @NotYetImplemented(CHROME) + @NotYetImplemented(CHROMIUMEDGE) public void testShouldSetAndGetAltitude() { driver.get(pages.html5Page); diff --git a/java/client/test/org/openqa/selenium/interactions/BasicMouseInterfaceTest.java b/java/client/test/org/openqa/selenium/interactions/BasicMouseInterfaceTest.java index e52e8f46cbb85..76d3028af6075 100644 --- a/java/client/test/org/openqa/selenium/interactions/BasicMouseInterfaceTest.java +++ b/java/client/test/org/openqa/selenium/interactions/BasicMouseInterfaceTest.java @@ -28,6 +28,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; import static org.openqa.selenium.testing.drivers.Browser.ALL; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -222,6 +223,7 @@ public void testCannotMoveToANullLocator() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(FIREFOX) @Ignore(MARIONETTE) @@ -262,6 +264,7 @@ public void testMovingIntoAnImageEnclosedInALink() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(IE) @Ignore(FIREFOX) @Ignore(MARIONETTE) @@ -396,7 +399,7 @@ public void testMovingMouseToRelativeZeroElementOffset() { wait.until(fuzzyMatchingOfCoordinates(reporter, 0, 0)); } - @NeedsFreshDriver({IE, CHROME, MARIONETTE}) + @NeedsFreshDriver({IE, CHROME, MARIONETTE, CHROMIUMEDGE}) @Test @NotYetImplemented(HTMLUNIT) @NotYetImplemented(SAFARI) diff --git a/java/client/test/org/openqa/selenium/interactions/DragAndDropTest.java b/java/client/test/org/openqa/selenium/interactions/DragAndDropTest.java index 2454d47a01370..ffd77e9bc265f 100644 --- a/java/client/test/org/openqa/selenium/interactions/DragAndDropTest.java +++ b/java/client/test/org/openqa/selenium/interactions/DragAndDropTest.java @@ -22,6 +22,7 @@ import static org.junit.Assume.assumeFalse; import static org.openqa.selenium.WaitingConditions.elementLocationToBe; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; @@ -131,6 +132,7 @@ public void testElementInDiv() { @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) @Ignore(FIREFOX) public void testDragTooFar() { driver.get(pages.dragAndDropPage); diff --git a/java/client/test/org/openqa/selenium/logging/PerformanceLoggingTest.java b/java/client/test/org/openqa/selenium/logging/PerformanceLoggingTest.java index 7d1157fc4b6ee..7df45f156bfd0 100644 --- a/java/client/test/org/openqa/selenium/logging/PerformanceLoggingTest.java +++ b/java/client/test/org/openqa/selenium/logging/PerformanceLoggingTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.openqa.selenium.remote.CapabilityType.ENABLE_PROFILING_CAPABILITY; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.IE; @@ -102,6 +103,7 @@ private boolean containsExpectedEntries(ImmutableList entries, String[ @Test @Ignore(CHROME) + @Ignore(CHROMIUMEDGE) public void testGetsYieldToPageLoadLogEntries() { startLoggingDriver(); loggingDriver.get(pages.formPage); diff --git a/java/client/test/org/openqa/selenium/remote/BUCK b/java/client/test/org/openqa/selenium/remote/BUCK index 88ce0113f265c..1fab3ad82a513 100644 --- a/java/client/test/org/openqa/selenium/remote/BUCK +++ b/java/client/test/org/openqa/selenium/remote/BUCK @@ -30,6 +30,7 @@ java_test( "//third_party/java/junit:junit", "//java/client/src/org/openqa/selenium:selenium", "//java/client/src/org/openqa/selenium/chrome:chrome", + "//java/client/src/org/openqa/selenium/edge:edge", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/firefox/xpi:firefox-xpi", "//java/client/src/org/openqa/selenium/ie:ie", diff --git a/java/client/test/org/openqa/selenium/testing/drivers/BUCK b/java/client/test/org/openqa/selenium/testing/drivers/BUCK index fe020af0913d2..424e7971417c4 100644 --- a/java/client/test/org/openqa/selenium/testing/drivers/BUCK +++ b/java/client/test/org/openqa/selenium/testing/drivers/BUCK @@ -19,7 +19,7 @@ java_library( ":browser", "//java/client/src/org/openqa/selenium:selenium", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/opera:opera", diff --git a/java/client/test/org/openqa/selenium/testing/drivers/Browser.java b/java/client/test/org/openqa/selenium/testing/drivers/Browser.java index 1f09a7cceb88c..4c2c48015a6d1 100644 --- a/java/client/test/org/openqa/selenium/testing/drivers/Browser.java +++ b/java/client/test/org/openqa/selenium/testing/drivers/Browser.java @@ -23,6 +23,7 @@ public enum Browser { ALL, CHROME, EDGE, + CHROMIUMEDGE, HTMLUNIT, FIREFOX, IE, @@ -49,6 +50,13 @@ public static Browser detect() { } } + if ("edge".equals(browserName.toLowerCase())) { + if (System.getProperty("webdriver.edge.edgehtml") == null || Boolean.getBoolean("webdriver.edge.edgehtml")) + return EDGE; + + return CHROMIUMEDGE; + } + try { return Browser.valueOf(browserName.toUpperCase()); } catch (IllegalArgumentException e) { diff --git a/java/client/test/org/openqa/selenium/testing/drivers/DefaultDriverSupplier.java b/java/client/test/org/openqa/selenium/testing/drivers/DefaultDriverSupplier.java index 5aeb10d7fd02f..d6eb87193f104 100644 --- a/java/client/test/org/openqa/selenium/testing/drivers/DefaultDriverSupplier.java +++ b/java/client/test/org/openqa/selenium/testing/drivers/DefaultDriverSupplier.java @@ -44,7 +44,7 @@ public class DefaultDriverSupplier implements Supplier { .put(BrowserType.FIREFOX, FirefoxDriver::new) .put(BrowserType.HTMLUNIT, HtmlUnitDriver::new) .put(BrowserType.IE, InternetExplorerDriver::new) - .put(BrowserType.EDGE, EdgeDriver::new) + .put(BrowserType.EDGE, TestEdgeDriver::new) .put(BrowserType.SAFARI, SafariDriver::new) .put("Safari Technology Preview", SafariDriver::new) .build(); diff --git a/java/client/test/org/openqa/selenium/testing/drivers/TestEdgeDriver.java b/java/client/test/org/openqa/selenium/testing/drivers/TestEdgeDriver.java new file mode 100644 index 0000000000000..a7b52e54e800b --- /dev/null +++ b/java/client/test/org/openqa/selenium/testing/drivers/TestEdgeDriver.java @@ -0,0 +1,139 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.openqa.selenium.testing.drivers; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.edge.EdgeDriverService; +import org.openqa.selenium.edge.EdgeOptions; +import org.openqa.selenium.html5.LocalStorage; +import org.openqa.selenium.html5.Location; +import org.openqa.selenium.html5.LocationContext; +import org.openqa.selenium.html5.SessionStorage; +import org.openqa.selenium.html5.WebStorage; +import org.openqa.selenium.remote.DriverCommand; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.remote.html5.RemoteLocationContext; +import org.openqa.selenium.remote.html5.RemoteWebStorage; +import org.openqa.selenium.remote.service.DriverService; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.logging.Logger; +import java.util.stream.StreamSupport; + +/** + * Customized RemoteWebDriver that will communicate with a service that lives and dies with the + * entire test suite. We do not use {@link org.openqa.selenium.edge.EdgeDriver} since that starts and stops the service + * with each instance (and that is too expensive for our purposes). + */ +public class TestEdgeDriver extends RemoteWebDriver implements WebStorage, LocationContext { + private final static Logger LOG = Logger.getLogger(TestEdgeDriver.class.getName()); + + private static EdgeDriverService service; + private RemoteWebStorage webStorage; + private RemoteLocationContext locationContext; + + public TestEdgeDriver(Capabilities capabilities) { + super(getServiceUrl(), edgeWithCustomCapabilities(capabilities)); + webStorage = new RemoteWebStorage(getExecuteMethod()); + locationContext = new RemoteLocationContext(getExecuteMethod()); + } + + private static URL getServiceUrl() { + try { + if (service == null) { + Path logFile = Files.createTempFile("edgedriver", ".log"); + boolean isLegacy = System.getProperty("webdriver.edge.edgehtml") == null || Boolean.getBoolean("webdriver.edge.edgehtml"); + + EdgeDriverService.Builder builder = + StreamSupport.stream(ServiceLoader.load(DriverService.Builder.class).spliterator(), false) + .filter(b -> b instanceof EdgeDriverService.Builder) + .map(b -> (EdgeDriverService.Builder) b) + .filter(b -> b.isLegacy() == isLegacy) + .findFirst().orElseThrow(WebDriverException::new); + + service = (EdgeDriverService) builder.withVerbose(true).withLogFile(logFile.toFile()).build(); + LOG.info("edgedriver will log to " + logFile); + service.start(); + Runtime.getRuntime().addShutdownHook(new Thread(() -> service.stop())); + } + return service.getUrl(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static Capabilities edgeWithCustomCapabilities(Capabilities originalCapabilities) { + EdgeOptions options = new EdgeOptions(); + + if (System.getProperty("webdriver.edge.edgehtml") == null || Boolean.getBoolean("webdriver.edge.edgehtml")) + return options; + + options.addArguments("disable-extensions", "disable-infobars", "disable-breakpad"); + Map prefs = new HashMap<>(); + prefs.put("exit_type", "None"); + prefs.put("exited_cleanly", true); + options.setExperimentalOption("prefs", prefs); + String edgePath = System.getProperty("webdriver.edge.binary"); + if (edgePath != null) { + options.setBinary(new File(edgePath)); + } + + if (originalCapabilities != null) { + options.merge(originalCapabilities); + } + + return options; + } + + @Override + public X getScreenshotAs(OutputType target) { + // Get the screenshot as base64. + String base64 = (String) execute(DriverCommand.SCREENSHOT).getValue(); + // ... and convert it. + return target.convertFromBase64Png(base64); + } + + @Override + public LocalStorage getLocalStorage() { + return webStorage.getLocalStorage(); + } + + @Override + public SessionStorage getSessionStorage() { + return webStorage.getSessionStorage(); + } + + @Override + public Location location() { + return locationContext.location(); + } + + @Override + public void setLocation(Location location) { + locationContext.setLocation(location); + } +} 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 e9eef286876d4..98eaf6a13c1ab 100644 --- a/java/client/test/org/openqa/selenium/testing/drivers/WebDriverBuilder.java +++ b/java/client/test/org/openqa/selenium/testing/drivers/WebDriverBuilder.java @@ -75,6 +75,7 @@ static void addShutdownAction(Runnable action) { } return options; }) + .put(Browser.CHROMIUMEDGE, EdgeOptions::new) .put(Browser.EDGE, EdgeOptions::new) .put(Browser.HTMLUNIT, () -> new DesiredCapabilities(BrowserType.HTMLUNIT, "", Platform.ANY)) .put(Browser.OPERABLINK, OperaOptions::new) diff --git a/java/server/src/com/thoughtworks/selenium/webdriven/BUCK b/java/server/src/com/thoughtworks/selenium/webdriven/BUCK index 8c1fa2a9c42cb..089ebc64cf82f 100644 --- a/java/server/src/com/thoughtworks/selenium/webdriven/BUCK +++ b/java/server/src/com/thoughtworks/selenium/webdriven/BUCK @@ -6,7 +6,7 @@ java_library( deps = [ "//java/client/src/com/thoughtworks/selenium:leg-rc", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/opera:opera", diff --git a/java/server/src/org/openqa/grid/selenium/node/BUCK b/java/server/src/org/openqa/grid/selenium/node/BUCK index e6ddd5c1100b4..d53db791eb4c5 100644 --- a/java/server/src/org/openqa/grid/selenium/node/BUCK +++ b/java/server/src/org/openqa/grid/selenium/node/BUCK @@ -3,6 +3,7 @@ java_library( srcs = glob(["*.java"]), deps = [ "//java/client/src/org/openqa/selenium/chrome:chrome", + "//java/client/src/org/openqa/selenium/edge:edge", "//java/client/src/org/openqa/selenium/firefox:firefox", ], visibility = [ diff --git a/java/server/src/org/openqa/selenium/grid/BUCK b/java/server/src/org/openqa/selenium/grid/BUCK index 5d17eae787d0d..5c61e54b1630d 100644 --- a/java/server/src/org/openqa/selenium/grid/BUCK +++ b/java/server/src/org/openqa/selenium/grid/BUCK @@ -93,7 +93,7 @@ java_library( deps = [ ":lib", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/safari:safari", diff --git a/java/server/src/org/openqa/selenium/remote/server/BUCK b/java/server/src/org/openqa/selenium/remote/server/BUCK index 506b93baddd39..128451b769c58 100644 --- a/java/server/src/org/openqa/selenium/remote/server/BUCK +++ b/java/server/src/org/openqa/selenium/remote/server/BUCK @@ -126,7 +126,7 @@ java_library( ":sessions", ":webdriver-servlet", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/opera:opera", diff --git a/java/server/src/org/openqa/selenium/server/htmlrunner/BUCK b/java/server/src/org/openqa/selenium/server/htmlrunner/BUCK index ee1c7fc93eb5f..e73a058ff11fe 100644 --- a/java/server/src/org/openqa/selenium/server/htmlrunner/BUCK +++ b/java/server/src/org/openqa/selenium/server/htmlrunner/BUCK @@ -14,7 +14,7 @@ java_library( "//java/client/src/com/thoughtworks/selenium/webdriven:webdriven", "//java/client/src/org/openqa/selenium:selenium", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/opera:opera", diff --git a/java/server/test/org/openqa/grid/e2e/BUCK b/java/server/test/org/openqa/grid/e2e/BUCK index a322893842896..844dab8fd7a35 100644 --- a/java/server/test/org/openqa/grid/e2e/BUCK +++ b/java/server/test/org/openqa/grid/e2e/BUCK @@ -15,6 +15,7 @@ java_library( deps = [ "//java/client/src/com/thoughtworks/selenium:leg-rc", "//java/client/src/org/openqa/selenium/chrome:chrome", + "//java/client/src/org/openqa/selenium/edge:edge", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/client/src/org/openqa/selenium/remote:remote", "//java/client/src/org/openqa/selenium/support/ui:wait", diff --git a/java/server/test/org/openqa/grid/selenium/node/BUCK b/java/server/test/org/openqa/grid/selenium/node/BUCK index 654031977528a..67ceaad44295f 100644 --- a/java/server/test/org/openqa/grid/selenium/node/BUCK +++ b/java/server/test/org/openqa/grid/selenium/node/BUCK @@ -7,6 +7,7 @@ java_test( deps = [ "//java/client/src/org/openqa/selenium:core", "//java/client/src/org/openqa/selenium/chrome:chrome", + "//java/client/src/org/openqa/selenium/edge:edge", "//java/client/src/org/openqa/selenium/firefox:firefox", "//java/server/src/org/openqa/grid:grid", "//java/server/src/org/openqa/grid/selenium/node:node", diff --git a/java/server/test/org/openqa/selenium/remote/server/DriverFactoryTest.java b/java/server/test/org/openqa/selenium/remote/server/DriverFactoryTest.java index a2c9274f263c0..393e5d9b4d1cb 100644 --- a/java/server/test/org/openqa/selenium/remote/server/DriverFactoryTest.java +++ b/java/server/test/org/openqa/selenium/remote/server/DriverFactoryTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.openqa.selenium.remote.BrowserType.CHROME; +import static org.openqa.selenium.remote.BrowserType.EDGE; import static org.openqa.selenium.remote.BrowserType.FIREFOX; import static org.openqa.selenium.remote.BrowserType.IE; import static org.openqa.selenium.remote.BrowserType.SAFARI; @@ -51,6 +52,7 @@ public void testShouldRegisterCorrectDefaultsOnMac() { DefaultDriverFactory factory = new DefaultDriverFactory(Platform.MAC); assertTrue(canInstantiate(factory, CHROME)); + assertTrue(canInstantiate(factory, EDGE)); assertTrue(canInstantiate(factory, FIREFOX)); assertTrue(canInstantiate(factory, SAFARI)); assertFalse(canInstantiate(factory, IE)); @@ -61,6 +63,7 @@ public void testShouldRegisterCorrectDefaultsOnLinux() { DefaultDriverFactory factory = new DefaultDriverFactory(Platform.LINUX); assertTrue(canInstantiate(factory, CHROME)); + assertTrue(canInstantiate(factory, EDGE)); assertTrue(canInstantiate(factory, FIREFOX)); assertFalse(canInstantiate(factory, SAFARI)); assertFalse(canInstantiate(factory, IE)); @@ -71,6 +74,7 @@ public void testShouldRegisterCorrectDefaultsOnWindows() { DefaultDriverFactory factory = new DefaultDriverFactory(Platform.VISTA); assertTrue(canInstantiate(factory, CHROME)); + assertTrue(canInstantiate(factory, EDGE)); assertTrue(canInstantiate(factory, FIREFOX)); assertFalse(canInstantiate(factory, SAFARI)); assertTrue(canInstantiate(factory, IE)); diff --git a/java/server/test/org/openqa/selenium/remote/server/SessionLogsTest.java b/java/server/test/org/openqa/selenium/remote/server/SessionLogsTest.java index d6730ea09ed9a..de734c859a129 100644 --- a/java/server/test/org/openqa/selenium/remote/server/SessionLogsTest.java +++ b/java/server/test/org/openqa/selenium/remote/server/SessionLogsTest.java @@ -21,6 +21,7 @@ import static org.openqa.selenium.json.Json.MAP_TYPE; import static org.openqa.selenium.remote.http.Contents.string; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.CHROMIUMEDGE; import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.SAFARI; @@ -53,6 +54,7 @@ @Ignore(HTMLUNIT) @Ignore(IE) @Ignore(CHROME) +@Ignore(CHROMIUMEDGE) @Ignore(SAFARI) public class SessionLogsTest extends JUnit4TestBase { diff --git a/javascript/atoms/BUCK b/javascript/atoms/BUCK index a496183c4c3ea..a888d882d9820 100644 --- a/javascript/atoms/BUCK +++ b/javascript/atoms/BUCK @@ -240,7 +240,7 @@ browsers = { deps = [ "//java/client/test/org/openqa/selenium/javascript:javascript", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/firefox:firefox", ], diff --git a/javascript/ie-driver/BUCK b/javascript/ie-driver/BUCK index bcdf980d748bf..3e6b3fa359826 100644 --- a/javascript/ie-driver/BUCK +++ b/javascript/ie-driver/BUCK @@ -11,6 +11,6 @@ java_test( deps = [ "//java/client/test/org/openqa/selenium/javascript:javascript", "//java/client/src/org/openqa/selenium/ie:ie", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", ], ) diff --git a/javascript/remote/BUCK b/javascript/remote/BUCK index 245c28dbba306..ae134fd9bfdb4 100644 --- a/javascript/remote/BUCK +++ b/javascript/remote/BUCK @@ -35,7 +35,7 @@ browsers = { deps = [ "//java/client/test/org/openqa/selenium/javascript:javascript", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/firefox:firefox", ], diff --git a/javascript/selenium-atoms/BUCK b/javascript/selenium-atoms/BUCK index 27c27e376bc58..12d4991075735 100644 --- a/javascript/selenium-atoms/BUCK +++ b/javascript/selenium-atoms/BUCK @@ -185,7 +185,7 @@ browsers = { deps = [ "//java/client/test/org/openqa/selenium/javascript:javascript", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/firefox:firefox", ], diff --git a/javascript/selenium-core/BUCK b/javascript/selenium-core/BUCK index 47cfd1069db01..6e86714353969 100644 --- a/javascript/selenium-core/BUCK +++ b/javascript/selenium-core/BUCK @@ -79,7 +79,7 @@ browsers = { deps = [ "//java/client/test/org/openqa/selenium/javascript:javascript", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/firefox:firefox", ], diff --git a/javascript/webdriver/BUCK b/javascript/webdriver/BUCK index a4fecaef1fb96..47e60093c3b16 100644 --- a/javascript/webdriver/BUCK +++ b/javascript/webdriver/BUCK @@ -68,7 +68,7 @@ browsers = { deps = [ "//java/client/test/org/openqa/selenium/javascript:javascript", "//java/client/src/org/openqa/selenium/chrome:chrome", - "//java/client/src/org/openqa/selenium/edge:edge", + "//java/client/src/org/openqa/selenium/edge/edgehtml:edgehtml", "//java/client/src/org/openqa/selenium/ie:ie", "//java/client/src/org/openqa/selenium/firefox:firefox", ], diff --git a/rake-tasks/browsers.rb b/rake-tasks/browsers.rb index cd6c2343f77e8..2c21acba1b1f8 100644 --- a/rake-tasks/browsers.rb +++ b/rake-tasks/browsers.rb @@ -57,6 +57,14 @@ :browser_name => "chrome", :available => chrome? }, + "chromiumedge" => { + :java => { + :class => "org.openqa.selenium.edge.EdgeDriver", + :deps => [ "//java/client/src/org/openqa/selenium/edge:edge" ] + }, + :browser_name => "MicrosoftEdge", + :available => edge? + }, "blackberry" => { :python => { :driver => "BlackBerry", diff --git a/rake-tasks/checks.rb b/rake-tasks/checks.rb index f1078c62b4289..fb9d441cb5f80 100644 --- a/rake-tasks/checks.rb +++ b/rake-tasks/checks.rb @@ -61,6 +61,10 @@ def chrome? present?("chromedriver") || present?("chromedriver.exe") end +def edge? + present?("msedgedriver") || present?("msedgedriver.exe") +end + def opera? present?("opera") || present?("Opera") end