Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/support w3c bidi #398

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques
});
chromeOptions.addArguments("--no-sandbox");
if (browser.equals(Browsers.chromeHeadless)) {
chromeOptions.addArguments("--headless");
chromeOptions.addArguments("--headless=new");
}
userAgentCapabilities = chromeOptions;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import eu.tsystems.mms.tic.testframework.pageobjects.internal.UiElementLabelLocator;
import eu.tsystems.mms.tic.testframework.report.ScreenshotGrabber;
import eu.tsystems.mms.tic.testframework.report.UITestStepIntegration;
import eu.tsystems.mms.tic.testframework.testing.DefaultSeleniumBiDiTools;
import eu.tsystems.mms.tic.testframework.testing.TestController;
import eu.tsystems.mms.tic.testframework.testing.UiElementOverrides;
import eu.tsystems.mms.tic.testframework.useragents.BrowserInformation;
Expand All @@ -58,7 +59,8 @@
import eu.tsystems.mms.tic.testframework.webdrivermanager.ChromeDevTools;
import eu.tsystems.mms.tic.testframework.webdrivermanager.DefaultWebDriverManager;
import eu.tsystems.mms.tic.testframework.webdrivermanager.IWebDriverManager;
import eu.tsystems.mms.tic.testframework.testing.SeleniumChromeDevTools;
import eu.tsystems.mms.tic.testframework.testing.DefaultChromeDevTools;
import eu.tsystems.mms.tic.testframework.webdrivermanager.SeleniumBiDiTools;
import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverCapabilities;
import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverSessionsManager;

Expand All @@ -79,7 +81,8 @@ protected void configure() {

// Instances
bind(BrowserInformation.class).to(UapBrowserInformation.class);
bind(ChromeDevTools.class).to(SeleniumChromeDevTools.class);
bind(ChromeDevTools.class).to(DefaultChromeDevTools.class);
bind(SeleniumBiDiTools.class).to(DefaultSeleniumBiDiTools.class);
bind(UiElementHighlighter.class).to(DefaultUiElementHighlighter.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,15 @@
*
* @author mgn
*/
public class SeleniumChromeDevTools implements ChromeDevTools, Loggable {
public class DefaultChromeDevTools implements ChromeDevTools, Loggable {

/**
* Create a Chrome DevTools session
*/
@Override
public DevTools getRawDevTools(WebDriver webDriver) {
if (!isSupported(webDriver)) {
throw new RuntimeException("The current browser does not support DevTools");
}
validateSupport(webDriver);

try {
DevTools devTools = null;
final String message = "Creating DevTools instance of ";
Expand All @@ -80,9 +79,6 @@ public DevTools getRawDevTools(WebDriver webDriver) {

@Override
public void setGeoLocation(WebDriver webDriver, double latitude, double longitude, int accuracy) {
if (!isSupported(webDriver)) {
throw new RuntimeException("The current browser does not support DevTools");
}
DevTools devTools = this.getRawDevTools(webDriver);
devTools.send(Emulation.setGeolocationOverride(
Optional.of(latitude),
Expand All @@ -93,9 +89,7 @@ public void setGeoLocation(WebDriver webDriver, double latitude, double longitud

@Override
public void setDevice(WebDriver webDriver, Dimension dimension, int scaleFactor, boolean mobile) {
if (!isSupported(webDriver)) {
throw new RuntimeException("The current browser does not support DevTools");
}
validateSupport(webDriver);
DevTools devTools = this.getRawDevTools(webDriver);
devTools.send(Emulation.setDeviceMetricsOverride(
dimension.getWidth(),
Expand All @@ -119,9 +113,6 @@ public void setDevice(WebDriver webDriver, Dimension dimension, int scaleFactor,

@Override
public void setBasicAuthentication(WebDriver webDriver, Supplier<Credentials> credentials) {
if (!isSupported(webDriver)) {
throw new RuntimeException("The current browser does not support DevTools");
}
DevTools devTools = this.getRawDevTools(webDriver);

try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Testerra
*
* (C) 2024, Martin Großmann, Deutsche Telekom MMS GmbH, Deutsche Telekom AG
*
* Deutsche Telekom AG and all other contributors /
* copyright owners license 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 eu.tsystems.mms.tic.testframework.testing;

import eu.tsystems.mms.tic.testframework.webdrivermanager.SeleniumBiDiTools;
import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverRequest;
import org.apache.commons.lang3.NotImplementedException;
import org.openqa.selenium.Credentials;
import org.openqa.selenium.WebDriver;

import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.remote.Augmenter;

import java.util.function.Supplier;

/**
* Created on 2024-02-28
*
* @author mgn
*/
public class DefaultSeleniumBiDiTools implements SeleniumBiDiTools {

@Override
public Network getNetwork(WebDriver webDriver) {
validateSupport(webDriver);

WebDriver originalFromDecorated = WEB_DRIVER_MANAGER.getOriginalFromDecorated(webDriver);

if (this.isRemoteDriver(webDriver)) {
Augmenter augmenter = new Augmenter();
return new Network(augmenter.augment(originalFromDecorated));
}
return new Network(originalFromDecorated);
}

@Override
public LogInspector getLogInsepctor(WebDriver webDriver) {
validateSupport(webDriver);

WebDriver originalFromDecorated = WEB_DRIVER_MANAGER.getOriginalFromDecorated(webDriver);

if (this.isRemoteDriver(webDriver)) {
Augmenter augmenter = new Augmenter();
return new LogInspector(augmenter.augment(originalFromDecorated));
}
return new LogInspector(originalFromDecorated);
}

@Override
public void setBasicAuthentication(WebDriver webDriver, Supplier<Credentials> credentials) {
throw new NotImplementedException("Basic authentication is missing for remote webdriver");
}

@Override
public void validateSupport(WebDriver webDriver) {
SeleniumBiDiTools.super.validateSupport(webDriver);

WebDriverRequest webDriverRequest = WEB_DRIVER_MANAGER.getSessionContext(webDriver).get().getWebDriverRequest();
if (!webDriverRequest.getCapabilities().is("webSocketUrl")) {
throw new RuntimeException("For using Selenium BiDi the capability 'webSocketUrl=true' is needed.");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package eu.tsystems.mms.tic.testframework.testing;

import eu.tsystems.mms.tic.testframework.common.Testerra;
import eu.tsystems.mms.tic.testframework.webdrivermanager.SeleniumBiDiTools;

/**
* Created on 2024-02-28
*
* @author mgn
*/
public interface SeleniumBidiToolsProvider {

SeleniumBiDiTools SELENIUM_BIDI_TOOLS = Testerra.getInjector().getInstance(SeleniumBiDiTools.class);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Testerra
*
* (C) 2024, Martin Großmann, Deutsche Telekom MMS GmbH, Deutsche Telekom AG
*
* Deutsche Telekom AG and all other contributors /
* copyright owners license 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 eu.tsystems.mms.tic.testframework.webdrivermanager;

import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider;
import org.openqa.selenium.Credentials;
import org.openqa.selenium.WebDriver;

import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

/**
* Created on 2024-02-28
*
* @author mgn
*/
public interface BiDiTools extends WebDriverManagerProvider {

void setBasicAuthentication(WebDriver webDriver, Supplier<Credentials> credentials);

default boolean isRemoteDriver(WebDriver webDriver) {
WebDriverRequest webDriverRequest = WEB_DRIVER_MANAGER.getSessionContext(webDriver).get().getWebDriverRequest();
return webDriverRequest.getServerUrl().isPresent();
}

default void validateSupport(WebDriver driver) {
Optional<String> requestedBrowser = WEB_DRIVER_MANAGER.getRequestedBrowser(driver);
boolean supported = Optional.ofNullable(requestedBrowser)
.map(Optional::get)
.map(browser -> this.getSupportedBrowsers().contains(browser))
.orElse(false);
if (!supported) {
throw new RuntimeException("The current browser does not support DevTools");
}
}

List<String> getSupportedBrowsers();

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.devtools.DevTools;

import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

Expand All @@ -35,7 +36,7 @@
*
* @author mgn
*/
public interface ChromeDevTools extends WebDriverManagerProvider {
public interface ChromeDevTools extends BiDiTools {

DevTools getRawDevTools(WebDriver webDriver);

Expand All @@ -45,17 +46,19 @@ public interface ChromeDevTools extends WebDriverManagerProvider {

void setBasicAuthentication(WebDriver webDriver, Supplier<Credentials> credentials);

default boolean isSupported(WebDriver driver) {
Optional<String> requestedBrowser = WEB_DRIVER_MANAGER.getRequestedBrowser(driver);
return Optional.ofNullable(requestedBrowser)
.map(Optional::get)
.map(browser -> browser.toLowerCase().contains(Browsers.chrome))
.orElse(false);
}
// default boolean isSupported(WebDriver driver) {
// Optional<String> requestedBrowser = WEB_DRIVER_MANAGER.getRequestedBrowser(driver);
// return Optional.ofNullable(requestedBrowser)
// .map(Optional::get)
// .map(browser -> browser.toLowerCase().contains(Browsers.chrome))
// .orElse(false);
// }

default boolean isRemoteDriver(WebDriver webDriver) {
WebDriverRequest webDriverRequest = WEB_DRIVER_MANAGER.getSessionContext(webDriver).get().getWebDriverRequest();
return webDriverRequest.getServerUrl().isPresent();
// default boolean isRemoteDriver(WebDriver webDriver) {
// WebDriverRequest webDriverRequest = WEB_DRIVER_MANAGER.getSessionContext(webDriver).get().getWebDriverRequest();
// return webDriverRequest.getServerUrl().isPresent();
default List<String> getSupportedBrowsers() {
return List.of(Browsers.chrome, Browsers.chromeHeadless);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Testerra
*
* (C) 2024, Martin Großmann, Deutsche Telekom MMS GmbH, Deutsche Telekom AG
*
* Deutsche Telekom AG and all other contributors /
* copyright owners license 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 eu.tsystems.mms.tic.testframework.webdrivermanager;

import eu.tsystems.mms.tic.testframework.constants.Browsers;
import org.openqa.selenium.WebDriver;

import org.openqa.selenium.bidi.log.LogEntry;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.ResponseDetails;

import java.util.List;
import java.util.function.Consumer;

/**
* Created on 2024-02-28
*
* @author mgn
*/
public interface SeleniumBiDiTools extends BiDiTools {

Network getNetwork(WebDriver webDriver);

LogInspector getLogInsepctor(WebDriver webDriver);

default void registerForResponseCompleted(WebDriver webDriver, Consumer<ResponseDetails> consumer) {
this.getNetwork(webDriver).onResponseCompleted(consumer);
}

default void registerGenericLogListener(WebDriver webDriver, Consumer<LogEntry> consumer) {
this.getLogInsepctor(webDriver).onLog(consumer);
}

default List<String> getSupportedBrowsers() {
return List.of(Browsers.chrome, Browsers.chromeHeadless, Browsers.firefox, Browsers.edge);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ public enum TestPage {
SHADOW_ROOT("ShadowDom/shadow_dom1.html"),
SHADOW_ROOT2("ShadowDom/shadow_dom2.html"),
SHADOW_ROOT3("ShadowDom/shadow_dom3.html"),
SWITCH_WINDOW("Multiwindow/index.html");
SWITCH_WINDOW("Multiwindow/index.html"),

BIDI_JS_LOGS("Bidi/log-entries.html"),
BIDI_BROKEN_IMAGE("Bidi/broken-image.html");

private String path;
private String elementText;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import org.openqa.selenium.JavascriptException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
Expand Down Expand Up @@ -221,6 +223,26 @@ public void testT06_BasicAuth_ChromeBiDiAPI() {
uiElementFinder.find(By.tagName("p")).assertThat().text().isContaining("Congratulations");
}

// Does not work.
// webdriver.get runs into infinity page loading
// @Test
// public void testT06a_BasicAuth_ChromeBiDiAPI_remote() {
// DesktopWebDriverRequest request = new DesktopWebDriverRequest();
// request.setBrowser(Browsers.chrome);
//// request.setBrowserVersion("106");
//
// WebDriver webDriver = WEB_DRIVER_MANAGER.getWebDriver(request);
// UiElementFinder uiElementFinder = UI_ELEMENT_FINDER_FACTORY.create(webDriver);
// Predicate<URI> uriPredicate = uri -> uri.getHost().contains("the-internet.herokuapp.com");
//
// RemoteWebDriver remoteWebDriver = WEB_DRIVER_MANAGER.unwrapWebDriver(webDriver, RemoteWebDriver.class).get();
// WebDriver augmentedDriver = new Augmenter().augment(remoteWebDriver);
// ((HasAuthentication) augmentedDriver).register(uriPredicate, UsernameAndPassword.of("admin", "admin"));
//
// webDriver.get("https://the-internet.herokuapp.com/basic_auth");
// uiElementFinder.find(By.tagName("p")).assertThat().text().isContaining("Congratulations");
// }

/**
* The following example uses the BiDi implementation of Chrome to add basic authentication information
* <p>
Expand Down
Loading