0
# JavaScript Execution
1
2
JavaScript execution and binding management for the Chrome DevTools Protocol v85. This functionality allows you to execute JavaScript in different browser contexts, create persistent bindings between browser and Java code, and inject scripts that run on page load.
3
4
## Capabilities
5
6
### V85Javascript Class
7
8
The main class for JavaScript execution extending the base Javascript functionality.
9
10
```java { .api }
11
/**
12
* JavaScript execution and binding management for Chrome DevTools v85
13
*/
14
public class V85Javascript extends Javascript<ScriptIdentifier, BindingCalled> {
15
/**
16
* Creates a new V85Javascript instance
17
* @param devtools - DevTools session for sending commands
18
*/
19
public V85Javascript(DevTools devtools);
20
}
21
```
22
23
### Runtime Domain Control
24
25
Enable and disable the Runtime domain for JavaScript execution.
26
27
```java { .api }
28
/**
29
* Enables the Runtime domain for JavaScript execution
30
* @return Command to enable runtime
31
*/
32
protected Command<Void> enableRuntime();
33
34
/**
35
* Disables the Runtime domain
36
* @return Command to disable runtime
37
*/
38
protected Command<Void> disableRuntime();
39
```
40
41
### JavaScript Bindings
42
43
Create bidirectional communication channels between browser JavaScript and Java code.
44
45
```java { .api }
46
/**
47
* Adds a JavaScript binding with the specified name
48
* @param scriptName - Name of the binding function in JavaScript
49
* @return Command to add the binding
50
*/
51
protected Command<Void> doAddJsBinding(String scriptName);
52
53
/**
54
* Removes a JavaScript binding
55
* @param scriptName - Name of the binding to remove
56
* @return Command to remove the binding
57
*/
58
protected Command<Void> doRemoveJsBinding(String scriptName);
59
60
/**
61
* Event fired when a JavaScript binding is called from the browser
62
* @return Event for binding calls
63
*/
64
protected Event<BindingCalled> bindingCalledEvent();
65
66
/**
67
* Extracts the payload from a binding called event
68
* @param event - The binding called event
69
* @return Payload string from the event
70
*/
71
protected String extractPayload(BindingCalled event);
72
```
73
74
**Usage Example:**
75
76
```java
77
import org.openqa.selenium.devtools.v85.V85Javascript;
78
79
V85Javascript javascript = (V85Javascript) domains.javascript();
80
81
// Add a binding using high-level API
82
javascript.addJsBinding("javaFunction");
83
84
// Listen for binding calls using high-level API
85
javascript.addBindingCalledListener(payload -> {
86
System.out.println("JavaScript called javaFunction with: " + payload);
87
88
// Process the payload and potentially respond
89
processBindingCall(payload);
90
});
91
92
// In the browser, JavaScript can now call:
93
// window.javaFunction("Hello from JavaScript!");
94
```
95
96
### Page Domain Control
97
98
Enable and disable the Page domain for script injection.
99
100
```java { .api }
101
/**
102
* Enables the Page domain for script injection
103
* @return Command to enable page domain
104
*/
105
protected Command<Void> enablePage();
106
107
/**
108
* Disables the Page domain
109
* @return Command to disable page domain
110
*/
111
protected Command<Void> disablePage();
112
```
113
114
### Script Injection
115
116
Inject JavaScript code that runs automatically on new document loads.
117
118
```java { .api }
119
/**
120
* Adds a script to be evaluated whenever a new document is created
121
* @param script - JavaScript code to inject
122
* @return Command that returns a ScriptIdentifier for the injected script
123
*/
124
protected Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(String script);
125
126
/**
127
* Removes a previously injected script
128
* @param id - ScriptIdentifier of the script to remove
129
* @return Command to remove the script
130
*/
131
protected Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier id);
132
```
133
134
**Usage Example:**
135
136
```java
137
import org.openqa.selenium.devtools.idealized.ScriptId;
138
139
// Inject a script using high-level API (pin method)
140
String initScript = """
141
console.log('Page loaded with custom script');
142
window.customAPI = {
143
sendData: function(data) {
144
javaFunction(JSON.stringify(data));
145
}
146
};
147
""";
148
149
ScriptId scriptId = javascript.pin("customAPI", initScript);
150
151
// The script will run automatically on every page load
152
// ScriptId can be used for reference, but removal requires domain-level control
153
```
154
155
### Complete Workflow Example
156
157
Here's a complete example showing JavaScript binding and script injection:
158
159
```java
160
import org.openqa.selenium.chrome.ChromeDriver;
161
import org.openqa.selenium.devtools.DevTools;
162
import org.openqa.selenium.devtools.v85.V85Domains;
163
164
ChromeDriver driver = new ChromeDriver();
165
DevTools devTools = driver.getDevTools();
166
devTools.createSession();
167
168
V85Domains domains = new V85Domains(devTools);
169
V85Javascript javascript = (V85Javascript) domains.javascript();
170
171
// Create a binding for Java-JavaScript communication using high-level API
172
javascript.addJsBinding("sendToJava");
173
174
// Listen for JavaScript calls using high-level API
175
javascript.addBindingCalledListener(data -> {
176
System.out.println("Received from JavaScript: " + data);
177
178
// Process the data
179
handleJavaScriptData(data);
180
});
181
182
// Inject initialization script
183
String initScript = """
184
window.sendMessage = function(message) {
185
sendToJava(JSON.stringify({
186
type: 'message',
187
content: message,
188
timestamp: Date.now()
189
}));
190
};
191
192
console.log('Custom API initialized');
193
""";
194
195
ScriptId scriptId = javascript.pin("sendMessage", initScript);
196
197
// Navigate to a page - the script will run automatically
198
driver.get("https://example.com");
199
200
// The page can now call: window.sendMessage("Hello Java!");
201
```
202
203
## CDP Model Classes
204
205
### ScriptIdentifier
206
207
Identifier for injected scripts that can be used to remove them later.
208
209
```java { .api }
210
/**
211
* Unique identifier for an injected script
212
*/
213
public class ScriptIdentifier {
214
public String toString();
215
}
216
```
217
218
### BindingCalled
219
220
Event data when a JavaScript binding is called from the browser.
221
222
```java { .api }
223
/**
224
* Event fired when a JavaScript binding is called
225
*/
226
public class BindingCalled {
227
/**
228
* Gets the name of the called binding
229
* @return Binding name
230
*/
231
public String getName();
232
233
/**
234
* Gets the payload sent from JavaScript
235
* @return Payload string
236
*/
237
public String getPayload();
238
239
/**
240
* Gets the execution context ID where the binding was called
241
* @return Execution context ID
242
*/
243
public Optional<Integer> getExecutionContextId();
244
}
245
```
246
247
## Advanced Patterns
248
249
### Bidirectional Communication
250
251
```java
252
// Set up bidirectional communication
253
devTools.send(javascript.doAddJsBinding("javaAPI"));
254
255
devTools.addListener(javascript.bindingCalledEvent(), event -> {
256
String payload = javascript.extractPayload(event);
257
JsonObject request = JsonParser.parseString(payload).getAsJsonObject();
258
259
switch (request.get("action").getAsString()) {
260
case "getData":
261
// Execute JavaScript to send data back
262
String responseScript = String.format(
263
"window.handleJavaResponse('%s', %s);",
264
request.get("id").getAsString(),
265
getDataAsJson()
266
);
267
devTools.send(Runtime.evaluate(responseScript, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()));
268
break;
269
270
case "log":
271
System.out.println("JS Log: " + request.get("message").getAsString());
272
break;
273
}
274
});
275
```
276
277
### Error Handling
278
279
```java
280
try {
281
ScriptIdentifier scriptId = devTools.send(javascript.addScriptToEvaluateOnNewDocument(script));
282
System.out.println("Script injected successfully: " + scriptId);
283
} catch (DevToolsException e) {
284
System.err.println("Failed to inject script: " + e.getMessage());
285
}
286
```