Skip to content

Commit 5b8add2

Browse files
committed
Working on DevToolsHandling implementation, EmulationHandling and NetworkHandling
1 parent 13ed405 commit 5b8add2

File tree

10 files changed

+614
-93
lines changed

10 files changed

+614
-93
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class Browser implements IApplication {
3333
private final ILocalizationManager localizationManager;
3434
private final ILocalizedLogger localizedLogger;
3535

36+
private DevToolsHandling devTools;
3637
private Duration implicitTimeout;
3738

3839
public Browser(RemoteWebDriver remoteWebDriver) {
@@ -375,12 +376,16 @@ private Duration getImplicitWaitTimeout() {
375376
* @return an instance of {@link DevToolsHandling}
376377
*/
377378
public DevToolsHandling devTools() {
379+
if (devTools != null) {
380+
return devTools;
381+
}
378382
WebDriver driver = getDriver();
379383
if (!(driver instanceof HasDevTools)) {
380384
driver = new Augmenter().augment(driver);
381385
}
382386
if (driver instanceof HasDevTools) {
383-
return new DevToolsHandling((HasDevTools) driver);
387+
devTools = new DevToolsHandling((HasDevTools) driver);
388+
return devTools;
384389
}
385390
else {
386391
throw new NotImplementedException("DevTools protocol is not supported for current browser.");
Lines changed: 135 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
11
package aquality.selenium.browser.devtools;
22

3+
import aquality.selenium.browser.AqualityServices;
4+
import aquality.selenium.core.localization.ILocalizedLogger;
5+
import org.apache.commons.lang3.NotImplementedException;
6+
import org.openqa.selenium.chromium.ChromiumDriver;
7+
import org.openqa.selenium.devtools.Command;
38
import org.openqa.selenium.devtools.DevTools;
9+
import org.openqa.selenium.devtools.Event;
410
import org.openqa.selenium.devtools.HasDevTools;
511

12+
import java.util.Map;
13+
import java.util.function.Consumer;
14+
15+
/**
16+
* Wrapper for Selenium {@link DevTools} functionality.
17+
*/
618
public class DevToolsHandling {
719
private final HasDevTools devToolsProvider;
20+
private final ILocalizedLogger logger;
21+
822
private DevTools session;
23+
private NetworkHandling network;
24+
private EmulationHandling emulation;
925

26+
/**
27+
* Initializes an instance of {@link DevToolsHandling}
28+
* @param devToolsProvider Instance of {@link org.openqa.selenium.WebDriver} which supports CDP protocol.
29+
*/
1030
public DevToolsHandling(HasDevTools devToolsProvider) {
1131
this.devToolsProvider = devToolsProvider;
32+
this.logger = AqualityServices.getLocalizedLogger();
1233
}
1334

1435
private DevTools getDevTools() {
@@ -18,21 +39,130 @@ private DevTools getDevTools() {
1839
return session;
1940
}
2041

21-
public DevTools getSession() {
42+
private void logCommand(String commandName, Map<String, Object> commandParameters) {
43+
if (!commandParameters.isEmpty()) {
44+
logger.info("loc.browser.devtools.command.execute.withparams", commandName, commandParameters);
45+
}
46+
else {
47+
logger.info("loc.browser.devtools.command.execute", commandName);
48+
}
49+
}
50+
51+
private void logCommandResult(Object result) {
52+
if (result != null) {
53+
if (result instanceof Map && ((Map<?, ?>) result).isEmpty()) {
54+
return;
55+
}
56+
logger.info("loc.browser.devtools.command.execute.result", result);
57+
}
58+
}
59+
60+
/**
61+
* Creates a session to communicate with a browser using the Chromium Developer Tools debugging protocol, if there is not one.
62+
* If the session already exist, returns existing session.
63+
* Defaults to autodetect the protocol version for Chromium, V85 for Firefox.
64+
* @return The active session to use to communicate with the Chromium Developer Tools debugging protocol.
65+
*/
66+
public DevTools getDevToolsSession() {
67+
logger.info("loc.browser.devtools.session.get", "default");
2268
getDevTools().createSessionIfThereIsNotOne();
2369
return session;
2470
}
2571

26-
public DevTools getSession(String windowHandle) {
72+
/**
73+
* Creates a session to communicate with a browser using the Chromium Developer Tools debugging protocol, if there is not one, on given window/tab (aka target).
74+
* If the session already exist, returns existing session.
75+
* If windowHandle is null, then the first "page" type will be selected.
76+
* Pass the windowHandle if you have multiple windows/tabs opened to connect to the expected window/tab.
77+
* Defaults to autodetect the protocol version for Chromium, V85 for Firefox.
78+
* @param windowHandle result of {@link org.openqa.selenium.WebDriver#getWindowHandle()}, optional. *
79+
* @return The active session to use to communicate with the Chromium Developer Tools debugging protocol.
80+
*/
81+
public DevTools getDevToolsSession(String windowHandle) {
82+
logger.info("loc.browser.devtools.session.get", windowHandle);
2783
getDevTools().createSessionIfThereIsNotOne(windowHandle);
2884
return session;
2985
}
3086

31-
public EmulationTools emulation() {
32-
return new EmulationTools(getSession());
87+
/**
88+
* Closes a DevTools session.
89+
*/
90+
public void closeDevToolsSession() {
91+
logger.info("loc.browser.devtools.session.close");
92+
getDevTools().disconnectSession();
3393
}
3494

95+
/**
96+
* Executes a custom Chromium Dev Tools Protocol Command.
97+
* Note: works only if current driver is instance of {@link ChromiumDriver}.
98+
* @param commandName Name of the command to execute.
99+
* @param commandParameters Parameters of the command to execute.
100+
* @return An object representing the result of the command, if applicable.
101+
*/
102+
public Map<String, Object> executeCdpCommand(String commandName, Map<String, Object> commandParameters) {
103+
if (devToolsProvider instanceof ChromiumDriver) {
104+
logCommand(commandName, commandParameters);
105+
ChromiumDriver driver = (ChromiumDriver) devToolsProvider;
106+
Map<String, Object> result = driver.executeCdpCommand(commandName, commandParameters);
107+
logCommandResult(result);
108+
return result;
109+
}
110+
else {
111+
throw new NotImplementedException("Execution of CDP command directly is not supported for current browser. Try sendCommand method instead.");
112+
}
113+
}
114+
115+
/**
116+
* Sends the specified command and returns the associated command response.
117+
* @param command An instance of the {@link Command} to send.
118+
* @param <X> The type of the command's result. For most commands it's {@link Void}
119+
* @return the result of the command, if applicable
120+
*/
121+
public <X> X sendCommand(Command<X> command) {
122+
logCommand(command.getMethod(), command.getParams());
123+
X result = getDevToolsSession().send(command);
124+
logCommandResult(result);
125+
return result;
126+
}
127+
128+
/**
129+
* Adds a listener for a specific event with the handler for it.
130+
* @param event Event to listen for
131+
* @param handler Handler to call
132+
* @param <X> The type of the event's result.
133+
*/
134+
public <X> void addListener(Event<X> event, Consumer<X> handler) {
135+
logger.info("loc.browser.devtools.listener.add", event.getMethod());
136+
getDevToolsSession().addListener(event, handler);
137+
}
138+
139+
/**
140+
* Removes all the listeners, and disables all the domains.
141+
*/
142+
public void clearListeners() {
143+
logger.info("loc.browser.devtools.listener.clear");
144+
getDevToolsSession().clearListeners();
145+
}
146+
147+
/**
148+
* Version-independent emulation DevTools commands.
149+
* @return an instance of {@link EmulationHandling}.
150+
*/
151+
public EmulationHandling emulation() {
152+
if (emulation == null) {
153+
emulation = new EmulationHandling(this);
154+
}
155+
return emulation;
156+
}
157+
158+
/**
159+
* DevTools commands for network requests interception.
160+
* @return an instance of {@link NetworkHandling}.
161+
*/
35162
public NetworkHandling network() {
36-
return new NetworkHandling(getSession());
163+
if (network == null) {
164+
network = new NetworkHandling(this);
165+
}
166+
return network;
37167
}
38168
}

0 commit comments

Comments
 (0)