0
# JavaScript Integration
1
2
JavaScript execution environment management and bidirectional communication setup for Chrome DevTools Protocol v138. Provides script injection, binding management, and page-level script control with full type safety.
3
4
## Capabilities
5
6
### JavaScript Handler
7
8
Main JavaScript handler providing execution environment management and binding capabilities.
9
10
```java { .api }
11
/**
12
* JavaScript execution and binding management for CDP v138
13
* @param devtools DevTools connection for JavaScript operations
14
*/
15
public class v138Javascript extends Javascript<ScriptIdentifier, BindingCalled> {
16
public v138Javascript(DevTools devtools);
17
18
// Public API methods inherited from Javascript base class
19
public void disable();
20
public ScriptId pin(String exposeScriptAs, String script);
21
public void addBindingCalledListener(Consumer<String> listener);
22
public void addJsBinding(String scriptName);
23
public void removeJsBinding(String scriptName);
24
}
25
```
26
27
**Usage Example:**
28
29
```java
30
import org.openqa.selenium.devtools.v138.v138Javascript;
31
import org.openqa.selenium.devtools.DevTools;
32
33
v138Javascript js = new v138Javascript(devTools);
34
35
// Add a JavaScript binding using public API
36
js.addJsBinding("myFunction");
37
38
// Listen for binding calls
39
js.addBindingCalledListener(payload -> {
40
System.out.println("Received from JavaScript: " + payload);
41
});
42
43
// Pin a script for execution
44
ScriptId scriptId = js.pin("initScript", "window.myApp = { ready: true };");
45
```
46
47
### Public JavaScript API Methods
48
49
High-level methods for JavaScript binding and script management without dealing with raw CDP commands.
50
51
```java { .api }
52
/**
53
* Add a JavaScript binding to enable communication from JavaScript to Java
54
* @param scriptName Name of the binding function available in JavaScript
55
*/
56
public void addJsBinding(String scriptName);
57
58
/**
59
* Remove a previously added JavaScript binding
60
* @param scriptName Name of the binding to remove
61
*/
62
public void removeJsBinding(String scriptName);
63
64
/**
65
* Add listener for binding calls from JavaScript
66
* @param listener Consumer that receives binding payloads as strings
67
*/
68
public void addBindingCalledListener(Consumer<String> listener);
69
70
/**
71
* Pin a script to be evaluated and store reference for management
72
* @param exposeScriptAs Name to expose the script as
73
* @param script JavaScript code to pin
74
* @return ScriptId for managing the pinned script
75
*/
76
public ScriptId pin(String exposeScriptAs, String script);
77
78
/**
79
* Disable JavaScript domain and clean up resources
80
*/
81
public void disable();
82
```
83
84
**Usage Example:**
85
86
```java
87
v138Javascript js = new v138Javascript(devTools);
88
89
// Set up bidirectional communication
90
js.addJsBinding("sendToJava");
91
92
js.addBindingCalledListener(payload -> {
93
System.out.println("JavaScript sent: " + payload);
94
95
// Parse and handle the payload
96
if (payload.contains("ready")) {
97
System.out.println("JavaScript application is ready");
98
}
99
});
100
101
// Pin initialization script
102
ScriptId initId = js.pin("appInit",
103
"window.sendToJava('Application initialized');");
104
105
// Navigate - pinned script will execute
106
driver.get("https://example.com");
107
108
// Clean up when done
109
js.removeJsBinding("sendToJava");
110
js.disable();
111
```
112
113
### Runtime Domain Control
114
115
Manages the Runtime domain required for JavaScript execution and binding.
116
117
```java { .api }
118
/**
119
* Enable Runtime domain for JavaScript operations
120
* @return Command to enable runtime domain
121
*/
122
@Override
123
protected Command<Void> enableRuntime();
124
125
/**
126
* Disable Runtime domain
127
* @return Command to disable runtime domain
128
*/
129
@Override
130
protected Command<Void> disableRuntime();
131
```
132
133
### Page Domain Control
134
135
Manages the Page domain required for script injection and page-level operations.
136
137
```java { .api }
138
/**
139
* Enable Page domain for script injection
140
* @return Command to enable page domain
141
*/
142
@Override
143
protected Command<Void> enablePage();
144
145
/**
146
* Disable Page domain
147
* @return Command to disable page domain
148
*/
149
@Override
150
protected Command<Void> disablePage();
151
```
152
153
### JavaScript Binding Management
154
155
Creates bidirectional communication channels between Java and JavaScript.
156
157
```java { .api }
158
/**
159
* Add a JavaScript binding to communicate with Java
160
* @param scriptName Name of the binding function available in JavaScript
161
* @return Command to add the binding
162
*/
163
@Override
164
protected Command<Void> doAddJsBinding(String scriptName);
165
166
/**
167
* Remove a previously added JavaScript binding
168
* @param scriptName Name of the binding to remove
169
* @return Command to remove the binding
170
*/
171
@Override
172
protected Command<Void> doRemoveJsBinding(String scriptName);
173
```
174
175
**Usage Example:**
176
177
```java
178
// Add binding for bidirectional communication
179
devTools.send(js.doAddJsBinding("sendToJava"));
180
181
// Listen for binding calls from JavaScript
182
devTools.addListener(js.bindingCalledEvent(), event -> {
183
String payload = js.extractPayload(event);
184
System.out.println("Received from JavaScript: " + payload);
185
186
// Process the payload and optionally respond
187
// (Response would typically be via executeScript)
188
});
189
190
// In browser JavaScript, this will trigger the listener:
191
// sendToJava("Hello from JavaScript!");
192
```
193
194
### Script Injection
195
196
Injects JavaScript code to be evaluated on every new document load.
197
198
```java { .api }
199
/**
200
* Add script to be evaluated on every new document
201
* @param script JavaScript code to inject
202
* @return Command that returns ScriptIdentifier for later removal
203
*/
204
@Override
205
protected Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(String script);
206
207
/**
208
* Remove previously injected script
209
* @param id ScriptIdentifier returned from addScriptToEvaluateOnNewDocument
210
* @return Command to remove the script
211
*/
212
@Override
213
protected Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier id);
214
```
215
216
**Usage Example:**
217
218
```java
219
// Inject script that runs on every page load
220
String initScript = """
221
window.myApp = {
222
initialized: true,
223
version: '1.0.0',
224
log: function(msg) {
225
console.log('[MyApp] ' + msg);
226
}
227
};
228
""";
229
230
ScriptIdentifier scriptId = devTools.send(
231
js.addScriptToEvaluateOnNewDocument(initScript));
232
233
// Navigate to pages - script will run automatically
234
driver.get("https://example.com");
235
driver.get("https://another-site.com");
236
237
// Remove the script when no longer needed
238
devTools.send(js.removeScriptToEvaluateOnNewDocument(scriptId));
239
```
240
241
### Binding Event Stream
242
243
Provides access to binding call events from JavaScript to Java.
244
245
```java { .api }
246
/**
247
* Stream of binding call events from JavaScript
248
* @return Event stream for binding calls
249
*/
250
@Override
251
protected Event<BindingCalled> bindingCalledEvent();
252
253
/**
254
* Extract payload from binding call event
255
* @param event BindingCalled event from JavaScript
256
* @return String payload sent from JavaScript
257
*/
258
@Override
259
protected String extractPayload(BindingCalled event);
260
```
261
262
## Complete JavaScript Integration Example
263
264
```java
265
import org.openqa.selenium.chrome.ChromeDriver;
266
import org.openqa.selenium.devtools.DevTools;
267
import org.openqa.selenium.devtools.v138.v138Javascript;
268
import org.openqa.selenium.devtools.v138.page.model.ScriptIdentifier;
269
270
ChromeDriver driver = new ChromeDriver();
271
DevTools devTools = driver.getDevTools();
272
devTools.createSession();
273
274
v138Javascript js = new v138Javascript(devTools);
275
276
// Enable required domains
277
devTools.send(js.enableRuntime());
278
devTools.send(js.enablePage());
279
280
// Set up bidirectional communication
281
devTools.send(js.doAddJsBinding("reportToJava"));
282
283
// Listen for messages from JavaScript
284
devTools.addListener(js.bindingCalledEvent(), event -> {
285
String message = js.extractPayload(event);
286
System.out.println("JavaScript says: " + message);
287
288
// Send response back via script execution
289
driver.executeScript("window.javaResponse = arguments[0];",
290
"Received: " + message);
291
});
292
293
// Inject initialization script
294
String initScript = """
295
window.communicator = {
296
sendToJava: function(message) {
297
reportToJava(JSON.stringify({
298
type: 'message',
299
content: message,
300
timestamp: Date.now()
301
}));
302
},
303
304
initialize: function() {
305
console.log('Communicator initialized');
306
this.sendToJava('System ready');
307
}
308
};
309
310
// Auto-initialize when DOM is ready
311
if (document.readyState === 'loading') {
312
document.addEventListener('DOMContentLoaded',
313
() => window.communicator.initialize());
314
} else {
315
window.communicator.initialize();
316
}
317
""";
318
319
ScriptIdentifier scriptId = devTools.send(
320
js.addScriptToEvaluateOnNewDocument(initScript));
321
322
// Navigate - initialization script will run
323
driver.get("https://example.com");
324
325
// Interact with the page
326
driver.executeScript("window.communicator.sendToJava('Page loaded successfully');");
327
328
// Clean up
329
devTools.send(js.removeScriptToEvaluateOnNewDocument(scriptId));
330
devTools.send(js.doRemoveJsBinding("reportToJava"));
331
devTools.send(js.disablePage());
332
devTools.send(js.disableRuntime());
333
devTools.close();
334
driver.quit();
335
```
336
337
## Types
338
339
```java { .api }
340
// Script identification for management
341
class ScriptIdentifier {
342
String toString(); // Unique identifier for injected scripts
343
}
344
345
// Binding event data
346
class BindingCalled {
347
String getName(); // Name of the binding that was called
348
String getPayload(); // Data sent from JavaScript
349
int getExecutionContextId(); // Context where binding was called
350
}
351
```