Skip to content

Commit

Permalink
Merge pull request #110 from aquality-automation/devTools_implementation
Browse files Browse the repository at this point in the history
[Selenium 4] Implement DevTools functions and migrate interfaces
  • Loading branch information
aqualityAutomation authored Sep 20, 2022
2 parents 7dac504 + e22ca1f commit e494d87
Show file tree
Hide file tree
Showing 77 changed files with 3,814 additions and 281 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2019 Aquality Automation
Copyright 2022 Aquality Automation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ Most of performed methods are logged using LOG4J, so you can easily see a histor
We use interfaces where is possible, so you can implement your own version of target interface with no need to rewrite other classes.

### Quick start
To start the project using aquality.selenium framework, you can [download our template BDD project by this link.](https://github.com/aquality-automation/aquality-selenium-java-template)

1. To start work with this package, simply add the dependency to your pom.xml:
Alternatively, you can follow the steps below:

1. Add the dependency to your pom.xml:
```
<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium</artifactId>
<version>LATEST</version>
<version>3.x.x</version>
</dependency>
```

Expand Down Expand Up @@ -47,14 +50,37 @@ txbSearch.submit();
browser.waitForPageToLoad();
```

6. Quit browser at the end
6. Use BiDi functionality to handle basic authentication:
```java
browser.network().addBasicAuthentication("domain.com", "username", "password");
```
or intercept network requests/responses:
```java
browser.network().startNetworkInterceptor((HttpHandler) request -> new HttpResponse()
.setStatus(HttpStatus.SC_OK)
.addHeader("Content-Type", MediaType.HTML_UTF_8.toString())
.setContent(utf8String("Some phrase")));
```
7. Emulate GeoLocation, Device, Touch, Media, UserAgent overrides, Disable script execution, log HTTP exchange, track Performance metrics, add initialization scripts, and more using browser.devTools() interfaces:
```java
final double latitude = 53.90772672521578;
final double longitude = 27.458060411865375;
final double accuracy = 0.97;
browser.devTools().emulation().setGeolocationOverride(latitude, longitude, accuracy);
```
See more DevTools use cases [here](./src/test/java/tests/usecases/devtools)

8. Quit browser at the end
```java
browser.quit();
```

See full example [here](./src/test/java/tests/usecases/QuickStartExample.java)
See quick start example [here](./src/test/java/tests/usecases/QuickStartExample.java)

### Documentation
To get more details please look at documentation:
- [In English](https://github.com/aquality-automation/aquality-selenium-java/wiki/Overview-(English))
- [In Russian](https://github.com/aquality-automation/aquality-selenium-java/wiki/Overview-(Russian))

### License
Library's source code is made available under the [Apache 2.0 license](LICENSE).
16 changes: 5 additions & 11 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<packaging>jar</packaging>
<name>Aquality Selenium</name>
<description>Library around Selenium WebDriver</description>
Expand Down Expand Up @@ -81,31 +81,25 @@
<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium-core</artifactId>
<version>2.0.1</version>
</dependency>

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.0</version>
<version>2.0.4</version>
</dependency>

<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.0.2</version>
<version>5.3.0</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
<version>2.13.4</version>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<version>7.5</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
61 changes: 56 additions & 5 deletions src/main/java/aquality/selenium/browser/Browser.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
package aquality.selenium.browser;

import aquality.selenium.browser.devtools.DevToolsHandling;
import aquality.selenium.browser.devtools.JavaScriptHandling;
import aquality.selenium.browser.devtools.NetworkHandling;
import aquality.selenium.configuration.IBrowserProfile;
import aquality.selenium.configuration.ITimeoutConfiguration;
import aquality.selenium.core.applications.IApplication;
import aquality.selenium.core.localization.ILocalizationManager;
import aquality.selenium.core.localization.ILocalizedLogger;
import aquality.selenium.core.waitings.IConditionalWait;
import org.apache.commons.io.IOUtils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.OutputType;
import org.apache.commons.lang3.NotImplementedException;
import org.openqa.selenium.*;
import org.openqa.selenium.WebDriver.Navigation;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public class Browser implements IApplication {
Expand All @@ -32,6 +34,7 @@ public class Browser implements IApplication {
private final ILocalizationManager localizationManager;
private final ILocalizedLogger localizedLogger;

private DevToolsHandling devTools;
private Duration implicitTimeout;

public Browser(RemoteWebDriver remoteWebDriver) {
Expand Down Expand Up @@ -262,6 +265,17 @@ public Object executeScript(final String script, Object... arguments) {
return executeJavaScript(() -> getDriver().executeScript(script, arguments));
}

/**
* Executes JS (jQuery) script.
*
* @param script Script pinned with {@link this#javaScriptEngine()}.
* @param arguments Arguments for the script (web elements, values etc.
* @return Result object of script execution
*/
public Object executeScript(final ScriptKey script, Object... arguments) {
return executeJavaScript(() -> getDriver().executeScript(script, arguments));
}

private Object executeJavaScript(Supplier<Object> executeScriptFunc) {
Object result = executeScriptFunc.get();
return result instanceof Boolean ? Boolean.parseBoolean(result.toString()) : result;
Expand Down Expand Up @@ -368,4 +382,41 @@ public final BrowserName getBrowserName() {
private Duration getImplicitWaitTimeout() {
return implicitTimeout;
}

/**
* Provides interface to handle DevTools for Chromium-based and Firefox drivers.
* @return an instance of {@link DevToolsHandling}
*/
public DevToolsHandling devTools() {
if (devTools != null) {
return devTools;
}
WebDriver driver = getDriver();
if (!(driver instanceof HasDevTools)) {
driver = new Augmenter().augment(driver);
}
if (driver instanceof HasDevTools) {
devTools = new DevToolsHandling((HasDevTools) driver);
return devTools;
}
else {
throw new NotImplementedException("DevTools protocol is not supported for current browser.");
}
}

/**
* Provides Network Handling functionality
* @return an instance of {@link NetworkHandling}
*/
public NetworkHandling network() {
return devTools().network();
}

/**
* Provides JavaScript Monitoring functionality.
* @return an instance of {@link JavaScriptHandling}
*/
public JavaScriptHandling javaScriptEngine() {
return devTools().javaScript();
}
}
5 changes: 4 additions & 1 deletion src/main/java/aquality/selenium/browser/BrowserName.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ public enum BrowserName {
EDGE,
FIREFOX,
IEXPLORER,
SAFARI
OPERA,
OTHER,
SAFARI,
YANDEX
}
15 changes: 9 additions & 6 deletions src/main/java/aquality/selenium/browser/JavaScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,16 @@ public enum JavaScript {
SELECT_COMBOBOX_VALUE_BY_TEXT("selectComboboxValueByText.js"),
SET_FOCUS("setFocus.js"),
SET_VALUE("setValue.js"),
SET_ATTRIBUTE("setAttribute.js"),
SCROLL_BY("scrollBy.js"),
IS_PAGE_LOADED("isPageLoaded.js"),
SCROLL_WINDOW_BY("scrollWindowBy.js"),
SET_INNER_HTML("setInnerHTML.js"),
GET_VIEWPORT_COORDINATES("getViewPortCoordinates.js"),
GET_SCREEN_OFFSET("getScreenOffset.js"),
OPEN_IN_NEW_TAB("openInNewTab.js"),
OPEN_NEW_TAB("openNewTab.js");
OPEN_NEW_TAB("openNewTab.js"),
EXPAND_SHADOW_ROOT("expandShadowRoot.js");

private final String filename;

Expand All @@ -55,11 +57,12 @@ public enum JavaScript {
*/
public String getScript() {
URL scriptFile = getClass().getResource("/js/" + filename);
try {
InputStream stream = scriptFile.openStream();
return IOUtils.toString(stream, StandardCharsets.UTF_8.name());
} catch (IOException e) {
Logger.getInstance().fatal(format("Couldn't find the script \"%s\"", filename), e);
if (scriptFile != null) {
try (InputStream stream = scriptFile.openStream()) {
return IOUtils.toString(stream, StandardCharsets.UTF_8.name());
} catch (IOException e) {
Logger.getInstance().fatal(format("Couldn't find the script \"%s\"", filename), e);
}
}
return "";
}
Expand Down
29 changes: 16 additions & 13 deletions src/main/java/aquality/selenium/browser/LocalBrowserFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@
import io.github.bonigarcia.wdm.config.Architecture;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;
import org.openqa.selenium.remote.AbstractDriverOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariOptions;

public class LocalBrowserFactory extends BrowserFactory {

Expand All @@ -32,35 +38,32 @@ protected RemoteWebDriver getDriver() {
Architecture systemArchitecture = driverSettings.getSystemArchitecture();
switch (browserName) {
case CHROME:
case YANDEX:
WebDriverManager.chromedriver().driverVersion(webDriverVersion).setup();
driver = getDriver(ChromeDriver.class, driverSettings.getCapabilities());
driver = new ChromeDriver((ChromeOptions) driverSettings.getDriverOptions());
break;
case OPERA:
WebDriverManager.operadriver().driverVersion(webDriverVersion).setup();
driver = new ChromeDriver((ChromeOptions) driverSettings.getDriverOptions());
break;
case FIREFOX:
WebDriverManager.firefoxdriver().driverVersion(webDriverVersion).setup();
driver = getDriver(FirefoxDriver.class, driverSettings.getCapabilities());
driver = new FirefoxDriver((FirefoxOptions) driverSettings.getDriverOptions());
break;
case IEXPLORER:
WebDriverManager.iedriver().architecture(systemArchitecture).driverVersion(webDriverVersion).setup();
driver = getDriver(InternetExplorerDriver.class, driverSettings.getCapabilities());
driver = new InternetExplorerDriver((InternetExplorerOptions) driverSettings.getDriverOptions());
break;
case EDGE:
WebDriverManager.edgedriver().driverVersion(webDriverVersion).setup();
driver = getDriver(EdgeDriver.class, driverSettings.getCapabilities());
driver = new EdgeDriver((EdgeOptions) driverSettings.getDriverOptions());
break;
case SAFARI:
driver = getDriver(SafariDriver.class, driverSettings.getCapabilities());
driver = new SafariDriver((SafariOptions) driverSettings.getDriverOptions());
break;
default:
throw new IllegalArgumentException(String.format("Browser [%s] is not supported.", browserName));
}
return driver;
}

private <T extends RemoteWebDriver> T getDriver(Class<T> driverClass, Capabilities capabilities) {
try {
return driverClass.getDeclaredConstructor(Capabilities.class).newInstance(capabilities);
} catch (ReflectiveOperationException e) {
throw new UnsupportedOperationException(String.format("Cannot instantiate driver with type '%1$s'.", driverClass), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public RemoteBrowserFactory(IActionRetrier actionRetrier, IBrowserProfile browse

@Override
protected RemoteWebDriver getDriver() {
Capabilities capabilities = browserProfile.getDriverSettings().getCapabilities();
Capabilities capabilities = browserProfile.getDriverSettings().getDriverOptions();
localizedLogger.info("loc.browser.grid");

ClientFactory clientFactory = new ClientFactory();
Expand Down
Loading

0 comments on commit e494d87

Please sign in to comment.