Skip to content

Commit e494d87

Browse files
Merge pull request #110 from aquality-automation/devTools_implementation
[Selenium 4] Implement DevTools functions and migrate interfaces
2 parents 7dac504 + e22ca1f commit e494d87

File tree

77 files changed

+3814
-281
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+3814
-281
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright 2019 Aquality Automation
189+
Copyright 2022 Aquality Automation
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

README.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ Most of performed methods are logged using LOG4J, so you can easily see a histor
1313
We use interfaces where is possible, so you can implement your own version of target interface with no need to rewrite other classes.
1414

1515
### Quick start
16+
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)
1617

17-
1. To start work with this package, simply add the dependency to your pom.xml:
18+
Alternatively, you can follow the steps below:
19+
20+
1. Add the dependency to your pom.xml:
1821
```
1922
<dependency>
2023
<groupId>com.github.aquality-automation</groupId>
2124
<artifactId>aquality-selenium</artifactId>
22-
<version>LATEST</version>
25+
<version>3.x.x</version>
2326
</dependency>
2427
```
2528

@@ -47,14 +50,37 @@ txbSearch.submit();
4750
browser.waitForPageToLoad();
4851
```
4952

50-
6. Quit browser at the end
53+
6. Use BiDi functionality to handle basic authentication:
54+
```java
55+
browser.network().addBasicAuthentication("domain.com", "username", "password");
5156
```
57+
or intercept network requests/responses:
58+
```java
59+
browser.network().startNetworkInterceptor((HttpHandler) request -> new HttpResponse()
60+
.setStatus(HttpStatus.SC_OK)
61+
.addHeader("Content-Type", MediaType.HTML_UTF_8.toString())
62+
.setContent(utf8String("Some phrase")));
63+
```
64+
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:
65+
```java
66+
final double latitude = 53.90772672521578;
67+
final double longitude = 27.458060411865375;
68+
final double accuracy = 0.97;
69+
browser.devTools().emulation().setGeolocationOverride(latitude, longitude, accuracy);
70+
```
71+
See more DevTools use cases [here](./src/test/java/tests/usecases/devtools)
72+
73+
8. Quit browser at the end
74+
```java
5275
browser.quit();
5376
```
5477

55-
See full example [here](./src/test/java/tests/usecases/QuickStartExample.java)
78+
See quick start example [here](./src/test/java/tests/usecases/QuickStartExample.java)
5679

5780
### Documentation
5881
To get more details please look at documentation:
5982
- [In English](https://github.com/aquality-automation/aquality-selenium-java/wiki/Overview-(English))
6083
- [In Russian](https://github.com/aquality-automation/aquality-selenium-java/wiki/Overview-(Russian))
84+
85+
### License
86+
Library's source code is made available under the [Apache 2.0 license](LICENSE).

pom.xml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.aquality-automation</groupId>
88
<artifactId>aquality-selenium</artifactId>
9-
<version>3.0.0</version>
9+
<version>3.1.0</version>
1010
<packaging>jar</packaging>
1111
<name>Aquality Selenium</name>
1212
<description>Library around Selenium WebDriver</description>
@@ -81,31 +81,25 @@
8181
<dependency>
8282
<groupId>com.github.aquality-automation</groupId>
8383
<artifactId>aquality-selenium-core</artifactId>
84-
<version>2.0.1</version>
85-
</dependency>
86-
87-
<dependency>
88-
<groupId>org.seleniumhq.selenium</groupId>
89-
<artifactId>selenium-java</artifactId>
90-
<version>4.1.0</version>
84+
<version>2.0.4</version>
9185
</dependency>
9286

9387
<dependency>
9488
<groupId>io.github.bonigarcia</groupId>
9589
<artifactId>webdrivermanager</artifactId>
96-
<version>5.0.2</version>
90+
<version>5.3.0</version>
9791
</dependency>
9892

9993
<dependency>
10094
<groupId>com.fasterxml.jackson.core</groupId>
10195
<artifactId>jackson-databind</artifactId>
102-
<version>2.13.0</version>
96+
<version>2.13.4</version>
10397
</dependency>
10498

10599
<dependency>
106100
<groupId>org.testng</groupId>
107101
<artifactId>testng</artifactId>
108-
<version>6.14.3</version>
102+
<version>7.5</version>
109103
<scope>test</scope>
110104
</dependency>
111105
</dependencies>

src/main/java/aquality/selenium/browser/Browser.java

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
package aquality.selenium.browser;
22

3+
import aquality.selenium.browser.devtools.DevToolsHandling;
4+
import aquality.selenium.browser.devtools.JavaScriptHandling;
5+
import aquality.selenium.browser.devtools.NetworkHandling;
36
import aquality.selenium.configuration.IBrowserProfile;
47
import aquality.selenium.configuration.ITimeoutConfiguration;
58
import aquality.selenium.core.applications.IApplication;
69
import aquality.selenium.core.localization.ILocalizationManager;
710
import aquality.selenium.core.localization.ILocalizedLogger;
811
import aquality.selenium.core.waitings.IConditionalWait;
912
import org.apache.commons.io.IOUtils;
10-
import org.openqa.selenium.Alert;
11-
import org.openqa.selenium.Dimension;
12-
import org.openqa.selenium.NoAlertPresentException;
13-
import org.openqa.selenium.OutputType;
13+
import org.apache.commons.lang3.NotImplementedException;
14+
import org.openqa.selenium.*;
1415
import org.openqa.selenium.WebDriver.Navigation;
16+
import org.openqa.selenium.devtools.HasDevTools;
1517
import org.openqa.selenium.logging.LogEntries;
18+
import org.openqa.selenium.remote.Augmenter;
1619
import org.openqa.selenium.remote.RemoteWebDriver;
1720
import org.openqa.selenium.support.ui.ExpectedCondition;
1821

1922
import java.io.File;
2023
import java.io.IOException;
2124
import java.nio.charset.StandardCharsets;
2225
import java.time.Duration;
23-
import java.util.concurrent.TimeUnit;
2426
import java.util.function.Supplier;
2527

2628
public class Browser implements IApplication {
@@ -32,6 +34,7 @@ public class Browser implements IApplication {
3234
private final ILocalizationManager localizationManager;
3335
private final ILocalizedLogger localizedLogger;
3436

37+
private DevToolsHandling devTools;
3538
private Duration implicitTimeout;
3639

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

268+
/**
269+
* Executes JS (jQuery) script.
270+
*
271+
* @param script Script pinned with {@link this#javaScriptEngine()}.
272+
* @param arguments Arguments for the script (web elements, values etc.
273+
* @return Result object of script execution
274+
*/
275+
public Object executeScript(final ScriptKey script, Object... arguments) {
276+
return executeJavaScript(() -> getDriver().executeScript(script, arguments));
277+
}
278+
265279
private Object executeJavaScript(Supplier<Object> executeScriptFunc) {
266280
Object result = executeScriptFunc.get();
267281
return result instanceof Boolean ? Boolean.parseBoolean(result.toString()) : result;
@@ -368,4 +382,41 @@ public final BrowserName getBrowserName() {
368382
private Duration getImplicitWaitTimeout() {
369383
return implicitTimeout;
370384
}
385+
386+
/**
387+
* Provides interface to handle DevTools for Chromium-based and Firefox drivers.
388+
* @return an instance of {@link DevToolsHandling}
389+
*/
390+
public DevToolsHandling devTools() {
391+
if (devTools != null) {
392+
return devTools;
393+
}
394+
WebDriver driver = getDriver();
395+
if (!(driver instanceof HasDevTools)) {
396+
driver = new Augmenter().augment(driver);
397+
}
398+
if (driver instanceof HasDevTools) {
399+
devTools = new DevToolsHandling((HasDevTools) driver);
400+
return devTools;
401+
}
402+
else {
403+
throw new NotImplementedException("DevTools protocol is not supported for current browser.");
404+
}
405+
}
406+
407+
/**
408+
* Provides Network Handling functionality
409+
* @return an instance of {@link NetworkHandling}
410+
*/
411+
public NetworkHandling network() {
412+
return devTools().network();
413+
}
414+
415+
/**
416+
* Provides JavaScript Monitoring functionality.
417+
* @return an instance of {@link JavaScriptHandling}
418+
*/
419+
public JavaScriptHandling javaScriptEngine() {
420+
return devTools().javaScript();
421+
}
371422
}

src/main/java/aquality/selenium/browser/BrowserName.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@ public enum BrowserName {
55
EDGE,
66
FIREFOX,
77
IEXPLORER,
8-
SAFARI
8+
OPERA,
9+
OTHER,
10+
SAFARI,
11+
YANDEX
912
}

src/main/java/aquality/selenium/browser/JavaScript.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ public enum JavaScript {
3333
SELECT_COMBOBOX_VALUE_BY_TEXT("selectComboboxValueByText.js"),
3434
SET_FOCUS("setFocus.js"),
3535
SET_VALUE("setValue.js"),
36+
SET_ATTRIBUTE("setAttribute.js"),
3637
SCROLL_BY("scrollBy.js"),
3738
IS_PAGE_LOADED("isPageLoaded.js"),
3839
SCROLL_WINDOW_BY("scrollWindowBy.js"),
3940
SET_INNER_HTML("setInnerHTML.js"),
4041
GET_VIEWPORT_COORDINATES("getViewPortCoordinates.js"),
4142
GET_SCREEN_OFFSET("getScreenOffset.js"),
4243
OPEN_IN_NEW_TAB("openInNewTab.js"),
43-
OPEN_NEW_TAB("openNewTab.js");
44+
OPEN_NEW_TAB("openNewTab.js"),
45+
EXPAND_SHADOW_ROOT("expandShadowRoot.js");
4446

4547
private final String filename;
4648

@@ -55,11 +57,12 @@ public enum JavaScript {
5557
*/
5658
public String getScript() {
5759
URL scriptFile = getClass().getResource("/js/" + filename);
58-
try {
59-
InputStream stream = scriptFile.openStream();
60-
return IOUtils.toString(stream, StandardCharsets.UTF_8.name());
61-
} catch (IOException e) {
62-
Logger.getInstance().fatal(format("Couldn't find the script \"%s\"", filename), e);
60+
if (scriptFile != null) {
61+
try (InputStream stream = scriptFile.openStream()) {
62+
return IOUtils.toString(stream, StandardCharsets.UTF_8.name());
63+
} catch (IOException e) {
64+
Logger.getInstance().fatal(format("Couldn't find the script \"%s\"", filename), e);
65+
}
6366
}
6467
return "";
6568
}

src/main/java/aquality/selenium/browser/LocalBrowserFactory.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@
88
import io.github.bonigarcia.wdm.config.Architecture;
99
import org.openqa.selenium.Capabilities;
1010
import org.openqa.selenium.chrome.ChromeDriver;
11+
import org.openqa.selenium.chrome.ChromeOptions;
1112
import org.openqa.selenium.edge.EdgeDriver;
13+
import org.openqa.selenium.edge.EdgeOptions;
1214
import org.openqa.selenium.firefox.FirefoxDriver;
15+
import org.openqa.selenium.firefox.FirefoxOptions;
1316
import org.openqa.selenium.ie.InternetExplorerDriver;
17+
import org.openqa.selenium.ie.InternetExplorerOptions;
18+
import org.openqa.selenium.remote.AbstractDriverOptions;
1419
import org.openqa.selenium.remote.RemoteWebDriver;
1520
import org.openqa.selenium.safari.SafariDriver;
21+
import org.openqa.selenium.safari.SafariOptions;
1622

1723
public class LocalBrowserFactory extends BrowserFactory {
1824

@@ -32,35 +38,32 @@ protected RemoteWebDriver getDriver() {
3238
Architecture systemArchitecture = driverSettings.getSystemArchitecture();
3339
switch (browserName) {
3440
case CHROME:
41+
case YANDEX:
3542
WebDriverManager.chromedriver().driverVersion(webDriverVersion).setup();
36-
driver = getDriver(ChromeDriver.class, driverSettings.getCapabilities());
43+
driver = new ChromeDriver((ChromeOptions) driverSettings.getDriverOptions());
44+
break;
45+
case OPERA:
46+
WebDriverManager.operadriver().driverVersion(webDriverVersion).setup();
47+
driver = new ChromeDriver((ChromeOptions) driverSettings.getDriverOptions());
3748
break;
3849
case FIREFOX:
3950
WebDriverManager.firefoxdriver().driverVersion(webDriverVersion).setup();
40-
driver = getDriver(FirefoxDriver.class, driverSettings.getCapabilities());
51+
driver = new FirefoxDriver((FirefoxOptions) driverSettings.getDriverOptions());
4152
break;
4253
case IEXPLORER:
4354
WebDriverManager.iedriver().architecture(systemArchitecture).driverVersion(webDriverVersion).setup();
44-
driver = getDriver(InternetExplorerDriver.class, driverSettings.getCapabilities());
55+
driver = new InternetExplorerDriver((InternetExplorerOptions) driverSettings.getDriverOptions());
4556
break;
4657
case EDGE:
4758
WebDriverManager.edgedriver().driverVersion(webDriverVersion).setup();
48-
driver = getDriver(EdgeDriver.class, driverSettings.getCapabilities());
59+
driver = new EdgeDriver((EdgeOptions) driverSettings.getDriverOptions());
4960
break;
5061
case SAFARI:
51-
driver = getDriver(SafariDriver.class, driverSettings.getCapabilities());
62+
driver = new SafariDriver((SafariOptions) driverSettings.getDriverOptions());
5263
break;
5364
default:
5465
throw new IllegalArgumentException(String.format("Browser [%s] is not supported.", browserName));
5566
}
5667
return driver;
5768
}
58-
59-
private <T extends RemoteWebDriver> T getDriver(Class<T> driverClass, Capabilities capabilities) {
60-
try {
61-
return driverClass.getDeclaredConstructor(Capabilities.class).newInstance(capabilities);
62-
} catch (ReflectiveOperationException e) {
63-
throw new UnsupportedOperationException(String.format("Cannot instantiate driver with type '%1$s'.", driverClass), e);
64-
}
65-
}
6669
}

src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public RemoteBrowserFactory(IActionRetrier actionRetrier, IBrowserProfile browse
3535

3636
@Override
3737
protected RemoteWebDriver getDriver() {
38-
Capabilities capabilities = browserProfile.getDriverSettings().getCapabilities();
38+
Capabilities capabilities = browserProfile.getDriverSettings().getDriverOptions();
3939
localizedLogger.info("loc.browser.grid");
4040

4141
ClientFactory clientFactory = new ClientFactory();

0 commit comments

Comments
 (0)