0
# JavaScript Operations
1
2
JavaScript execution, debugging, and browser-side binding management for advanced automation scenarios. Provides capabilities for script injection, JavaScript binding creation, and runtime interaction.
3
4
## Core Imports
5
6
```java
7
import org.openqa.selenium.devtools.v99.V99Javascript;
8
import org.openqa.selenium.devtools.DevTools;
9
import org.openqa.selenium.devtools.Command;
10
import org.openqa.selenium.devtools.Event;
11
import java.util.function.Consumer;
12
```
13
14
## Capabilities
15
16
### JavaScript Handler
17
18
Creates a JavaScript operations handler for Chrome DevTools Protocol v99.
19
20
```java { .api }
21
/**
22
* Creates JavaScript operations handler for CDP v99
23
* @param devtools - DevTools client instance
24
*/
25
public V99Javascript(DevTools devtools);
26
```
27
28
### Runtime Management
29
30
Enable and disable the JavaScript runtime domain for script execution and debugging.
31
32
```java { .api }
33
/**
34
* Enable JavaScript runtime domain for script operations
35
* @return Command to enable runtime
36
*/
37
protected Command<Void> enableRuntime();
38
39
/**
40
* Disable JavaScript runtime domain
41
* @return Command to disable runtime
42
*/
43
protected Command<Void> disableRuntime();
44
```
45
46
### Page Management
47
48
Enable and disable the page domain for script injection on new documents.
49
50
```java { .api }
51
/**
52
* Enable page domain for script injection capabilities
53
* @return Command to enable page domain
54
*/
55
protected Command<Void> enablePage();
56
57
/**
58
* Disable page domain
59
* @return Command to disable page domain
60
*/
61
protected Command<Void> disablePage();
62
```
63
64
### JavaScript Bindings
65
66
Create and manage communication channels between browser JavaScript and Java code.
67
68
```java { .api }
69
/**
70
* Add JavaScript binding for browser-to-Java communication
71
* @param scriptName - Name of the binding function in JavaScript
72
*/
73
public void addJsBinding(String scriptName);
74
75
/**
76
* Remove JavaScript binding
77
* @param scriptName - Name of the binding to remove
78
*/
79
public void removeJsBinding(String scriptName);
80
81
/**
82
* Add listener for when JavaScript bindings are called
83
* @param listener - Consumer that receives payload strings from JavaScript
84
*/
85
public void addBindingCalledListener(Consumer<String> listener);
86
87
/**
88
* Add JavaScript binding for browser-to-Java communication (internal)
89
* @param scriptName - Name of the binding function in JavaScript
90
* @return Command to create the binding
91
*/
92
protected Command<Void> doAddJsBinding(String scriptName);
93
94
/**
95
* Remove JavaScript binding (internal)
96
* @param scriptName - Name of the binding to remove
97
* @return Command to remove the binding
98
*/
99
protected Command<Void> doRemoveJsBinding(String scriptName);
100
101
/**
102
* Get event for when JavaScript bindings are called (internal)
103
* @return Event handler for binding calls
104
*/
105
protected Event<BindingCalled> bindingCalledEvent();
106
107
/**
108
* Extract payload from binding event (internal)
109
* @param event - Binding called event
110
* @return Payload string from JavaScript
111
*/
112
protected String extractPayload(BindingCalled event);
113
```
114
115
### Script Management
116
117
Manage script injection and pinning for new document creation.
118
119
```java { .api }
120
/**
121
* Pin a script to be executed on every new document with a binding
122
* @param exposeScriptAs - Name to expose the script binding as
123
* @param script - JavaScript code to inject and pin
124
* @return ScriptId for the pinned script
125
*/
126
public ScriptId pin(String exposeScriptAs, String script);
127
128
/**
129
* Disable JavaScript functionality and clean up pinned scripts
130
*/
131
public void disable();
132
133
/**
134
* Add script to evaluate on new document creation (internal)
135
* @param script - JavaScript code to inject
136
* @return Command returning script identifier
137
*/
138
protected Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(String script);
139
140
/**
141
* Remove previously injected script (internal)
142
* @param id - Script identifier to remove
143
* @return Command to remove the script
144
*/
145
protected Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier id);
146
```
147
148
## Protocol Types
149
150
### Script Identifier
151
152
```java { .api }
153
/**
154
* Identifier for injected scripts from CDP
155
*/
156
public class ScriptIdentifier {
157
// Generated from CDP protocol - exact structure depends on protocol version
158
}
159
160
/**
161
* Wrapper for pinned script management
162
*/
163
public class ScriptId {
164
public ScriptId(Object actualId);
165
public Object getActualId();
166
}
167
```
168
169
### Binding Called Event
170
171
```java { .api }
172
/**
173
* Event data when JavaScript binding is called
174
*/
175
public class BindingCalled {
176
/**
177
* Get the payload sent from JavaScript
178
* @return Payload string
179
*/
180
public String getPayload();
181
182
/**
183
* Get the name of the binding that was called
184
* @return Binding name
185
*/
186
public String getName();
187
188
/**
189
* Get execution context ID where binding was called
190
* @return Context ID
191
*/
192
public ExecutionContextId getExecutionContextId();
193
}
194
```
195
196
## Usage Examples
197
198
### Basic Binding Setup
199
200
```java
201
import org.openqa.selenium.devtools.DevTools;
202
import org.openqa.selenium.devtools.v99.V99Domains;
203
204
DevTools devTools = ...; // from ChromeDriver
205
V99Domains domains = new V99Domains(devTools);
206
207
// Add JavaScript binding using public API
208
domains.javascript().addJsBinding("myCallback");
209
210
// Listen for binding calls using public API
211
domains.javascript().addBindingCalledListener(payload -> {
212
System.out.println("Received from JavaScript: " + payload);
213
214
// Process the payload and potentially respond
215
processJavaScriptMessage(payload);
216
});
217
218
// In browser JavaScript, call: myCallback('Hello from browser!');
219
```
220
221
### Script Injection and Pinning
222
223
```java
224
// Pin a script to run on every new document
225
String initScript = """
226
console.log('Page initialized');
227
window.myApp = {
228
version: '1.0.0',
229
initialized: true
230
};
231
""";
232
233
// Pin script with exposed binding
234
ScriptId scriptId = domains.javascript().pin("initApp", initScript);
235
236
// The script will now run on every new page load
237
// and "initApp" binding will be available in JavaScript
238
239
// Cleanup when done
240
domains.javascript().disable(); // Removes all pinned scripts and bindings
241
```
242
243
### Runtime Control
244
245
```java
246
// Enable runtime for JavaScript operations
247
devTools.send(domains.javascript().enableRuntime());
248
249
// Perform JavaScript operations...
250
// (binding setup, script injection, etc.)
251
252
// Cleanup - disable runtime when done
253
devTools.send(domains.javascript().disableRuntime());
254
devTools.send(domains.javascript().disablePage());
255
```
256
257
### Advanced Binding Communication
258
259
```java
260
// Set up multiple bindings for bidirectional communication
261
domains.javascript().addJsBinding("sendToJava");
262
domains.javascript().addJsBinding("getFromJava");
263
264
// Single listener handles all binding calls
265
domains.javascript().addBindingCalledListener(payload -> {
266
// Parse payload to determine which binding was called
267
// The payload contains the binding name and data
268
if (payload.startsWith("sendToJava:")) {
269
String data = payload.substring("sendToJava:".length());
270
handleDataFromBrowser(data);
271
} else if (payload.startsWith("getFromJava:")) {
272
String request = payload.substring("getFromJava:".length());
273
String response = getDataForBrowser(request);
274
sendResponseToBrowser(response);
275
}
276
});
277
278
// In JavaScript:
279
// sendToJava('sendToJava:' + JSON.stringify(data));
280
// getFromJava('getFromJava:' + requestType);
281
```
282
283
## Error Handling
284
285
JavaScript operations can fail for several reasons:
286
287
- **Runtime not enabled**: Enable runtime domain before JavaScript operations
288
- **Page not enabled**: Enable page domain before script injection
289
- **Invalid script syntax**: JavaScript syntax errors will be reported through events
290
- **Binding conflicts**: Binding names must be unique
291
- **Context mismatch**: Bindings are tied to specific execution contexts
292
293
Handle errors through standard DevTools exception handling and event monitoring:
294
295
```java
296
try {
297
devTools.send(domains.javascript().enableRuntime());
298
devTools.send(domains.javascript().doAddJsBinding("myBinding"));
299
} catch (DevToolsException e) {
300
System.err.println("Failed to set up JavaScript binding: " + e.getMessage());
301
}
302
303
// Monitor for JavaScript exceptions
304
devTools.addListener(domains.events().exceptionThrownEvent(), exception -> {
305
System.err.println("JavaScript exception: " + exception.getExceptionDetails().getText());
306
});
307
```