Skip to content

Commit d9b148b

Browse files
committed
Working on JavaScriptHandling
1 parent 5b8add2 commit d9b148b

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

src/main/java/aquality/selenium/browser/devtools/DevToolsHandling.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class DevToolsHandling {
2222
private DevTools session;
2323
private NetworkHandling network;
2424
private EmulationHandling emulation;
25+
private JavaScriptHandling javaScript;
2526

2627
/**
2728
* Initializes an instance of {@link DevToolsHandling}
@@ -32,6 +33,10 @@ public DevToolsHandling(HasDevTools devToolsProvider) {
3233
this.logger = AqualityServices.getLocalizedLogger();
3334
}
3435

36+
HasDevTools getDevToolsProvider() {
37+
return devToolsProvider;
38+
}
39+
3540
private DevTools getDevTools() {
3641
if (session == null) {
3742
session = devToolsProvider.getDevTools();
@@ -165,4 +170,11 @@ public NetworkHandling network() {
165170
}
166171
return network;
167172
}
173+
174+
public JavaScriptHandling javaScript() {
175+
if (javaScript == null) {
176+
javaScript = new JavaScriptHandling(this);
177+
}
178+
return javaScript;
179+
}
168180
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package aquality.selenium.browser.devtools;
2+
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.JavascriptException;
7+
import org.openqa.selenium.WebDriver;
8+
import org.openqa.selenium.devtools.events.ConsoleEvent;
9+
import org.openqa.selenium.devtools.events.DomMutationEvent;
10+
import org.openqa.selenium.devtools.idealized.Events;
11+
import org.openqa.selenium.devtools.idealized.Javascript;
12+
import org.openqa.selenium.devtools.idealized.ScriptId;
13+
import org.openqa.selenium.logging.EventType;
14+
import org.openqa.selenium.logging.HasLogEvents;
15+
import org.openqa.selenium.remote.Augmenter;
16+
17+
import java.util.ArrayList;
18+
import java.util.HashSet;
19+
import java.util.List;
20+
import java.util.Set;
21+
import java.util.function.Consumer;
22+
23+
import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;
24+
import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;
25+
26+
/**
27+
* DevTools commands for version-independent network interception.
28+
* For more information, see {@link Javascript}.
29+
*/
30+
public class JavaScriptHandling {
31+
private final DevToolsHandling tools;
32+
private final Javascript<?, ?> engine;
33+
private final Events<?, ?> events;
34+
private final ILocalizedLogger logger = AqualityServices.getLocalizedLogger();
35+
private final Set<String> bindings = new HashSet<>();
36+
37+
/**
38+
* Initializes a new instance of the {@link JavaScriptHandling} class.
39+
* @param tools Instance of {@link DevToolsHandling}.
40+
*/
41+
public JavaScriptHandling(DevToolsHandling tools) {
42+
this.tools = tools;
43+
this.engine = tools.getDevToolsSession().getDomains().javascript();
44+
this.events = tools.getDevToolsSession().getDomains().events();
45+
}
46+
47+
/**
48+
* Gets the read-only list of binding callbacks added for this JavaScript engine.
49+
* @return list of binding callbacks added for this JavaScript engine.
50+
*/
51+
public List<String> getBindings() {
52+
logger.info("loc.browser.javascript.scriptcallbackbindings.get");
53+
return new ArrayList<>(bindings);
54+
}
55+
56+
/**
57+
* Removes all initialization scripts from being loaded for each document, and stops listening for events.
58+
*/
59+
public void disable() {
60+
logger.info("loc.browser.javascript.reset");
61+
engine.disable();
62+
bindings.clear();
63+
}
64+
65+
/**
66+
* Pins a JavaScript snippet for execution in the browser without transmitting the entire script across the wire
67+
* for every execution.
68+
* @param exposeScriptAs The name of the callback that will trigger events when the named binding is called by
69+
* JavaScript executing in the browser.
70+
* @param script The JavaScript to pin.
71+
* @return a {@link ScriptId} object to use to execute the script.
72+
*/
73+
public ScriptId pin(String exposeScriptAs, String script) {
74+
logger.info("loc.browser.javascript.snippet.pin");
75+
logger.info("loc.browser.javascript.scriptcallbackbinding.add", exposeScriptAs);
76+
bindings.add(exposeScriptAs);
77+
return engine.pin(exposeScriptAs, script);
78+
}
79+
80+
/**
81+
* Adds a listener for events that occur when a JavaScript callback with a named binding is executed.
82+
* To add a binding, use {@link this.addJsBinding}.
83+
* @param listener a listener to add, consuming a name of exposed script.
84+
*/
85+
public void addBindingCalledListener(Consumer<String> listener) {
86+
logger.info("loc.browser.javascript.event.callbackexecuted.add");
87+
engine.addBindingCalledListener(listener);
88+
}
89+
90+
private HasLogEvents getDriverThatHasLogEvents() {
91+
WebDriver driver = (WebDriver) tools.getDevToolsProvider();
92+
if (!(driver instanceof HasLogEvents)) {
93+
Augmenter augmenter = new Augmenter();
94+
String browserName = AqualityServices.getBrowserProfile().getBrowserName().name().toLowerCase();
95+
driver = augmenter.addDriverAugmentation(browserName, HasLogEvents.class, (caps, exec) -> new HasLogEvents() {
96+
@Override
97+
public <X> void onLogEvent(EventType<X> kind) {
98+
kind.initializeListener((WebDriver) tools.getDevToolsProvider());
99+
}
100+
}).augment(driver);
101+
if (!(driver instanceof HasLogEvents)) {
102+
throw new NotImplementedException(
103+
String.format("Driver for the current browser [%s] doesn't implement HasLogEvents", browserName));
104+
}
105+
}
106+
return (HasLogEvents) driver;
107+
}
108+
109+
/**
110+
* Adds a listener for events that occur when a value of an attribute in an element is being changed.
111+
* @param listener a listener to add, consuming a dom mutation event.
112+
*/
113+
public void addDomMutatedListener(Consumer<DomMutationEvent> listener) {
114+
logger.info("loc.browser.javascript.event.dommutated.add");
115+
getDriverThatHasLogEvents().onLogEvent(domMutation(listener));
116+
}
117+
118+
/**
119+
* Adds a listener for events that occur when methods on the JavaScript console are called.
120+
* @param listener a listener to add, consuming a javascript exception.
121+
*/
122+
public void addConsoleEventListener(Consumer<ConsoleEvent> listener) {
123+
logger.info("loc.browser.javascript.event.consoleapicalled.add");
124+
getDriverThatHasLogEvents().onLogEvent(consoleEvent(listener));
125+
}
126+
127+
/**
128+
* Adds a listener for events that occur when methods on the JavaScript console are called.
129+
* @param listener a listener to add, consuming a javascript exception.
130+
*/
131+
public void addJavaScriptConsoleApiListener(Consumer<ConsoleEvent> listener) {
132+
logger.info("loc.browser.javascript.event.consoleapicalled.add");
133+
events.addConsoleListener(listener);
134+
}
135+
136+
/**
137+
* Adds a listener for events that occur when an exception is thrown by JavaScript being executed in the browser.
138+
* @param listener a listener to add, consuming a javascript exception.
139+
*/
140+
public void addJavaScriptExceptionThrownListener(Consumer<JavascriptException> listener) {
141+
logger.info("loc.browser.javascript.event.exceptionthrown.add");
142+
events.addJavascriptExceptionListener(listener);
143+
}
144+
145+
/**
146+
* Adds a binding to a callback method that will raise an event when the named binding is called by JavaScript
147+
* executing in the browser.
148+
* @param scriptName The name of the callback that will trigger events.
149+
*/
150+
public void addJsBinding(String scriptName) {
151+
logger.info("loc.browser.javascript.scriptcallbackbinding.add", scriptName);
152+
engine.addJsBinding(scriptName);
153+
bindings.add(scriptName);
154+
}
155+
156+
/**
157+
* Removes a binding to a JavaScript callback.
158+
* @param scriptName The name of the callback to be removed.
159+
*/
160+
public void removeJsBinding(String scriptName) {
161+
logger.info("loc.browser.javascript.scriptcallbackbinding.remove", scriptName);
162+
engine.removeJsBinding(scriptName);
163+
bindings.remove(scriptName);
164+
}
165+
}

0 commit comments

Comments
 (0)