From 81758918380331e0a652efe9fe7302610eb6f772 Mon Sep 17 00:00:00 2001 From: Puja Jagani Date: Tue, 31 Jan 2023 11:38:50 +0530 Subject: [PATCH 1/3] [java] [cdp] Simplify Augmentation for Basic Auth --- .../selenium/remote/AddHasAuthentication.java | 68 +++++++++++++++++++ .../org/openqa/selenium/remote/Augmenter.java | 39 ++++++++++- .../openqa/selenium/grid/router/BUILD.bazel | 3 + .../grid/router/RemoteWebDriverCDPTest.java | 57 ++++++++++++++++ 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 java/src/org/openqa/selenium/remote/AddHasAuthentication.java create mode 100644 java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java diff --git a/java/src/org/openqa/selenium/remote/AddHasAuthentication.java b/java/src/org/openqa/selenium/remote/AddHasAuthentication.java new file mode 100644 index 0000000000000..e4db2a602845a --- /dev/null +++ b/java/src/org/openqa/selenium/remote/AddHasAuthentication.java @@ -0,0 +1,68 @@ +// 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.remote; + +import static org.openqa.selenium.remote.Browser.CHROME; +import static org.openqa.selenium.remote.Browser.EDGE; +import static org.openqa.selenium.remote.Browser.OPERA; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.HasAuthentication; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.devtools.DevTools; +import org.openqa.selenium.devtools.HasDevTools; +import org.openqa.selenium.internal.Require; + +import java.util.function.Predicate; +import java.util.logging.Logger; + +public class AddHasAuthentication + implements AugmenterProvider { + + private static final Logger logger = Logger.getLogger(AddHasAuthentication.class.getName()); + private static final Predicate IS_CHROMIUM_BROWSER = name -> + CHROME.is(name) || + EDGE.is(name) || + OPERA.is(name); + + @Override + public Predicate isApplicable() { + return caps -> IS_CHROMIUM_BROWSER.test(caps.getBrowserName()); + } + + @Override + public Class getDescribedInterface() { + return HasAuthentication.class; + } + + @Override + public HasAuthentication getImplementation(Capabilities capabilities, ExecuteMethod executeMethod) { + return (whenThisMatches, useTheseCredentials) -> { + Require.nonNull("Check to use to see how we should authenticate", whenThisMatches); + Require.nonNull("Credentials to use when authenticating", useTheseCredentials); + + if (((RemoteExecuteMethod) executeMethod).getWrappedDriver() instanceof HasDevTools) { + WebDriver driver = ((RemoteExecuteMethod) executeMethod).getWrappedDriver(); + DevTools devTools = ((HasDevTools) driver).getDevTools(); + devTools.createSessionIfThereIsNotOne(); + devTools.getDomains().network().addAuthHandler(whenThisMatches, useTheseCredentials); + } + // Todo: Similarly add for BiDi once BiDi supports the same functionality + }; + } +} diff --git a/java/src/org/openqa/selenium/remote/Augmenter.java b/java/src/org/openqa/selenium/remote/Augmenter.java index 98f62087391a9..afb749c151ede 100644 --- a/java/src/org/openqa/selenium/remote/Augmenter.java +++ b/java/src/org/openqa/selenium/remote/Augmenter.java @@ -26,6 +26,7 @@ import org.openqa.selenium.Beta; import org.openqa.selenium.Capabilities; +import org.openqa.selenium.HasAuthentication; import org.openqa.selenium.HasCapabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.WebDriver; @@ -36,6 +37,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.ServiceLoader; @@ -158,6 +160,12 @@ public WebDriver augment(WebDriver driver) { .filter(augmentation -> augmentation.whenMatches.test(caps)) .collect(Collectors.toList()); + return this.augment(driver, matchingAugmenters); + } + + private WebDriver augment(WebDriver driver, List> matchingAugmenters) { + Capabilities caps = ImmutableCapabilities.copyOf(((HasCapabilities) driver).getCapabilities()); + if (matchingAugmenters.isEmpty()) { return driver; } @@ -165,8 +173,11 @@ public WebDriver augment(WebDriver driver) { // Grab a remote execution method, if possible RemoteWebDriver remote = extractRemoteWebDriver(driver); ExecuteMethod execute = remote == null ? - (commandName, parameters) -> { throw new WebDriverException("Cannot execute remote command: " + commandName); } : - new RemoteExecuteMethod(remote); + (commandName, parameters) -> { + throw new WebDriverException( + "Cannot execute remote command: " + commandName); + } : + new RemoteExecuteMethod(remote); DynamicType.Builder builder = new ByteBuddy() .subclass(driver.getClass()) @@ -193,12 +204,36 @@ public WebDriver augment(WebDriver driver) { copyFields(driver.getClass(), driver, toReturn); + toReturn = addDependentAugmentations(toReturn); + return toReturn; } catch (ReflectiveOperationException e) { throw new IllegalStateException("Unable to create new proxy", e); } } + private WebDriver addDependentAugmentations(WebDriver driver) { + List> augmentationList = new ArrayList<>(); + + WebDriver toReturn = driver; + + // add interfaces that need to use the augmented driver + if (!(driver instanceof HasAuthentication)) { + augmentationList.add(createAugmentation(new AddHasAuthentication())); + } + + if (!augmentationList.isEmpty()) { + Capabilities caps = ImmutableCapabilities.copyOf(((HasCapabilities) driver).getCapabilities()); + + List> matchingAugmenters = augmentationList.stream() + .filter(augmentation -> augmentation.whenMatches.test(caps)) + .collect(Collectors.toList()); + + toReturn = this.augment(driver, matchingAugmenters); + } + return toReturn; + } + private RemoteWebDriver extractRemoteWebDriver(WebDriver driver) { Require.nonNull("WebDriver", driver); diff --git a/java/test/org/openqa/selenium/grid/router/BUILD.bazel b/java/test/org/openqa/selenium/grid/router/BUILD.bazel index 33c641069a8b6..219379b57cc4b 100644 --- a/java/test/org/openqa/selenium/grid/router/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/router/BUILD.bazel @@ -84,12 +84,15 @@ java_test_suite( deps = [ ":support", "//java/src/org/openqa/selenium/bidi", + "//java/src/org/openqa/selenium/chrome", + "//java/src/org/openqa/selenium/edge", "//java/src/org/openqa/selenium/firefox", "//java/src/org/openqa/selenium/grid", "//java/src/org/openqa/selenium/grid/config", "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", "//java/src/org/openqa/selenium/support", + "//java/test/org/openqa/selenium/environment", "//java/test/org/openqa/selenium/grid/testing", "//java/test/org/openqa/selenium/remote/tracing:tracing-support", "//java/test/org/openqa/selenium/testing:test-base", diff --git a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java new file mode 100644 index 0000000000000..20735c71f49b9 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java @@ -0,0 +1,57 @@ +// 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.grid.router; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.HasAuthentication; +import org.openqa.selenium.UsernameAndPassword; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.grid.config.TomlConfig; +import org.openqa.selenium.grid.router.DeploymentTypes.Deployment; +import org.openqa.selenium.remote.Augmenter; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.testing.drivers.Browser; + +import java.io.StringReader; + +class RemoteWebDriverCDPTest { + + @Test + void ensureCDPBasicAuthWorks() { + Browser browser = Browser.CHROME; + + Deployment deployment = DeploymentTypes.STANDALONE.start( + browser.getCapabilities(), + new TomlConfig(new StringReader( + "[node]\n" + + "driver-implementation = " + browser.displayName()))); + + WebDriver driver = new RemoteWebDriver(deployment.getServer().getUrl(), new ChromeOptions()); + driver = new Augmenter().augment(driver); + + ((HasAuthentication) driver).register(UsernameAndPassword.of("admin", "admin")); + + driver.get("https://the-internet.herokuapp.com/basic_auth"); + + assertThat(driver.findElement(By.tagName("p")).getText().contains("Congratulations!")).isTrue(); + } +} From e4ff6c73a9371de59f1fac2e1201fabd5fe1ec03 Mon Sep 17 00:00:00 2001 From: Puja Jagani Date: Thu, 2 Feb 2023 11:09:09 +0530 Subject: [PATCH 2/3] [java][cdp] Remove the test that uses third party website --- .../openqa/selenium/grid/router/BUILD.bazel | 3 - .../grid/router/RemoteWebDriverCDPTest.java | 57 ------------------- 2 files changed, 60 deletions(-) delete mode 100644 java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java diff --git a/java/test/org/openqa/selenium/grid/router/BUILD.bazel b/java/test/org/openqa/selenium/grid/router/BUILD.bazel index 219379b57cc4b..33c641069a8b6 100644 --- a/java/test/org/openqa/selenium/grid/router/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/router/BUILD.bazel @@ -84,15 +84,12 @@ java_test_suite( deps = [ ":support", "//java/src/org/openqa/selenium/bidi", - "//java/src/org/openqa/selenium/chrome", - "//java/src/org/openqa/selenium/edge", "//java/src/org/openqa/selenium/firefox", "//java/src/org/openqa/selenium/grid", "//java/src/org/openqa/selenium/grid/config", "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", "//java/src/org/openqa/selenium/support", - "//java/test/org/openqa/selenium/environment", "//java/test/org/openqa/selenium/grid/testing", "//java/test/org/openqa/selenium/remote/tracing:tracing-support", "//java/test/org/openqa/selenium/testing:test-base", diff --git a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java deleted file mode 100644 index 20735c71f49b9..0000000000000 --- a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverCDPTest.java +++ /dev/null @@ -1,57 +0,0 @@ -// 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.grid.router; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -import org.junit.jupiter.api.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.HasAuthentication; -import org.openqa.selenium.UsernameAndPassword; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.chrome.ChromeOptions; -import org.openqa.selenium.grid.config.TomlConfig; -import org.openqa.selenium.grid.router.DeploymentTypes.Deployment; -import org.openqa.selenium.remote.Augmenter; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.testing.drivers.Browser; - -import java.io.StringReader; - -class RemoteWebDriverCDPTest { - - @Test - void ensureCDPBasicAuthWorks() { - Browser browser = Browser.CHROME; - - Deployment deployment = DeploymentTypes.STANDALONE.start( - browser.getCapabilities(), - new TomlConfig(new StringReader( - "[node]\n" + - "driver-implementation = " + browser.displayName()))); - - WebDriver driver = new RemoteWebDriver(deployment.getServer().getUrl(), new ChromeOptions()); - driver = new Augmenter().augment(driver); - - ((HasAuthentication) driver).register(UsernameAndPassword.of("admin", "admin")); - - driver.get("https://the-internet.herokuapp.com/basic_auth"); - - assertThat(driver.findElement(By.tagName("p")).getText().contains("Congratulations!")).isTrue(); - } -} From 2c5360fafba8d6d18056d9f103543548811719a7 Mon Sep 17 00:00:00 2001 From: Puja Jagani Date: Thu, 2 Feb 2023 11:11:34 +0530 Subject: [PATCH 3/3] [java][cdp] Undo formatting changes --- java/src/org/openqa/selenium/remote/Augmenter.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/java/src/org/openqa/selenium/remote/Augmenter.java b/java/src/org/openqa/selenium/remote/Augmenter.java index afb749c151ede..2148524d48490 100644 --- a/java/src/org/openqa/selenium/remote/Augmenter.java +++ b/java/src/org/openqa/selenium/remote/Augmenter.java @@ -173,11 +173,8 @@ private WebDriver augment(WebDriver driver, List> matchingAugmen // Grab a remote execution method, if possible RemoteWebDriver remote = extractRemoteWebDriver(driver); ExecuteMethod execute = remote == null ? - (commandName, parameters) -> { - throw new WebDriverException( - "Cannot execute remote command: " + commandName); - } : - new RemoteExecuteMethod(remote); + (commandName, parameters) -> { throw new WebDriverException("Cannot execute remote command: " + commandName); } : + new RemoteExecuteMethod(remote); DynamicType.Builder builder = new ByteBuddy() .subclass(driver.getClass())