0
# JavaScript Integration
1
2
JavaScript engine configuration and event handling including script execution control, error handling, and browser API simulation for comprehensive JavaScript support in headless browsing.
3
4
## Capabilities
5
6
### JavaScript Engine Configuration
7
8
Control JavaScript execution and configure engine behavior for optimal performance and compatibility.
9
10
```java { .api }
11
/**
12
* Enable or disable JavaScript execution globally
13
* @param enabled true to enable JavaScript processing
14
*/
15
public void setJavaScriptEnabled(boolean enabled);
16
17
/**
18
* Check if JavaScript is currently enabled
19
* @return true if JavaScript execution is enabled
20
*/
21
public boolean isJavaScriptEnabled();
22
23
/**
24
* Configure whether JavaScript errors should throw exceptions
25
* @param throwException true to throw exceptions on script errors
26
*/
27
public void setThrowExceptionOnScriptError(boolean throwException);
28
29
/**
30
* Wait for background JavaScript tasks to complete
31
* @param timeoutMillis maximum time to wait in milliseconds
32
* @return number of JavaScript jobs that completed
33
*/
34
public int waitForBackgroundJavaScript(long timeoutMillis);
35
```
36
37
**Usage Examples:**
38
39
```java
40
WebClient webClient = new WebClient();
41
42
// Enable JavaScript for dynamic pages
43
webClient.getOptions().setJavaScriptEnabled(true);
44
45
// Configure error handling - don't fail on script errors
46
webClient.getOptions().setThrowExceptionOnScriptError(false);
47
48
// Load a page with JavaScript
49
HtmlPage page = webClient.getPage("https://example.com/dynamic-app");
50
51
// Wait for JavaScript to complete (AJAX, timers, etc.)
52
webClient.waitForBackgroundJavaScript(5000); // Wait up to 5 seconds
53
54
// Now interact with the fully loaded page
55
HtmlElement dynamicContent = page.getElementById("ajax-loaded-content");
56
```
57
58
### JavaScript Alert Handling
59
60
Handle JavaScript alert() dialog boxes with custom alert handlers.
61
62
```java { .api }
63
public interface AlertHandler {
64
/**
65
* Handle a JavaScript alert dialog
66
* @param page the page that triggered the alert
67
* @param message the alert message text
68
*/
69
void handleAlert(Page page, String message);
70
}
71
72
/**
73
* Set a custom handler for JavaScript alert() calls
74
* @param handler the AlertHandler implementation
75
*/
76
public void setAlertHandler(AlertHandler handler);
77
```
78
79
**Usage Examples:**
80
81
```java
82
// Simple alert handler that prints to console
83
webClient.setAlertHandler(new AlertHandler() {
84
@Override
85
public void handleAlert(Page page, String message) {
86
System.out.println("JavaScript Alert on " + page.getUrl() + ": " + message);
87
}
88
});
89
90
// Lambda-based alert handler
91
webClient.setAlertHandler((page, message) -> {
92
System.out.println("Alert: " + message);
93
});
94
95
// Store alerts for later verification in tests
96
List<String> alerts = new ArrayList<>();
97
webClient.setAlertHandler((page, message) -> alerts.add(message));
98
99
// Load page that shows alerts
100
HtmlPage page = webClient.getPage("https://example.com/alert-demo");
101
// JavaScript: alert("Welcome to our site!");
102
103
// Check collected alerts
104
assertEquals(1, alerts.size());
105
assertEquals("Welcome to our site!", alerts.get(0));
106
```
107
108
### JavaScript Confirm Handling
109
110
Handle JavaScript confirm() dialog boxes with custom confirm handlers that can return true/false responses.
111
112
```java { .api }
113
public interface ConfirmHandler {
114
/**
115
* Handle a JavaScript confirm dialog
116
* @param page the page that triggered the confirm
117
* @param message the confirm message text
118
* @return true to simulate clicking "OK", false for "Cancel"
119
*/
120
boolean handleConfirm(Page page, String message);
121
}
122
123
/**
124
* Set a custom handler for JavaScript confirm() calls
125
* @param handler the ConfirmHandler implementation
126
*/
127
public void setConfirmHandler(ConfirmHandler handler);
128
```
129
130
**Usage Examples:**
131
132
```java
133
// Always confirm (click "OK")
134
webClient.setConfirmHandler((page, message) -> {
135
System.out.println("Confirm: " + message + " -> OK");
136
return true;
137
});
138
139
// Conditional confirm based on message content
140
webClient.setConfirmHandler((page, message) -> {
141
if (message.contains("delete")) {
142
System.out.println("Confirming deletion: " + message);
143
return true;
144
} else {
145
System.out.println("Canceling: " + message);
146
return false;
147
}
148
});
149
150
// Test confirm behavior
151
HtmlPage page = webClient.getPage("https://example.com/confirm-demo");
152
HtmlButton deleteBtn = page.getElementById("deleteButton");
153
// JavaScript: if (confirm("Are you sure you want to delete this item?")) { ... }
154
deleteBtn.click(); // Will trigger confirm handler
155
```
156
157
### JavaScript Prompt Handling
158
159
Handle JavaScript prompt() dialog boxes with custom prompt handlers that can provide input values.
160
161
```java { .api }
162
public interface PromptHandler {
163
/**
164
* Handle a JavaScript prompt dialog
165
* @param page the page that triggered the prompt
166
* @param message the prompt message text
167
* @param defaultValue the default value shown in the prompt, may be null
168
* @return the value to return to JavaScript, or null to simulate "Cancel"
169
*/
170
String handlePrompt(Page page, String message, String defaultValue);
171
}
172
173
/**
174
* Set a custom handler for JavaScript prompt() calls
175
* @param handler the PromptHandler implementation
176
*/
177
public void setPromptHandler(PromptHandler handler);
178
```
179
180
**Usage Examples:**
181
182
```java
183
// Simple prompt handler that returns default values
184
webClient.setPromptHandler((page, message, defaultValue) -> {
185
System.out.println("Prompt: " + message);
186
return defaultValue != null ? defaultValue : "default response";
187
});
188
189
// Dynamic prompt responses based on message
190
webClient.setPromptHandler((page, message, defaultValue) -> {
191
if (message.contains("name")) {
192
return "John Doe";
193
} else if (message.contains("email")) {
194
return "john@example.com";
195
} else {
196
return defaultValue;
197
}
198
});
199
200
// Cancel specific prompts
201
webClient.setPromptHandler((page, message, defaultValue) -> {
202
if (message.contains("password")) {
203
// Return null to simulate clicking "Cancel"
204
return null;
205
}
206
return "some value";
207
});
208
209
// Usage in testing
210
HtmlPage page = webClient.getPage("https://example.com/prompt-demo");
211
// JavaScript: var name = prompt("Please enter your name:", "Guest");
212
// Will use the configured prompt handler
213
```
214
215
### JavaScript Error Handling
216
217
Handle JavaScript execution errors with detailed error listeners and custom error processing.
218
219
```java { .api }
220
public interface JavaScriptErrorListener {
221
/**
222
* Handle JavaScript runtime exceptions
223
* @param page the page where the error occurred
224
* @param scriptException the JavaScript exception details
225
*/
226
void scriptException(HtmlPage page, ScriptException scriptException);
227
228
/**
229
* Handle JavaScript execution timeouts
230
* @param page the page where the timeout occurred
231
* @param allowedTime the maximum time allowed for execution
232
* @param executionTime the actual execution time
233
*/
234
void timeoutError(HtmlPage page, long allowedTime, long executionTime);
235
236
/**
237
* Handle malformed script URLs
238
* @param page the page with the malformed URL
239
* @param url the malformed URL string
240
* @param malformedURLException the URL parsing exception
241
*/
242
void malformedScriptURL(HtmlPage page, String url, MalformedURLException malformedURLException);
243
244
/**
245
* Handle script loading errors
246
* @param page the page where the error occurred
247
* @param scriptUrl the URL of the script that failed to load
248
* @param exception the loading exception
249
*/
250
void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception);
251
}
252
253
public class DefaultJavaScriptErrorListener implements JavaScriptErrorListener {
254
// Default implementation that logs errors
255
}
256
257
public class SilentJavaScriptErrorListener implements JavaScriptErrorListener {
258
// Silent implementation that ignores all errors
259
}
260
261
/**
262
* Set a JavaScript error listener
263
* @param listener the JavaScriptErrorListener implementation
264
*/
265
public void setJavaScriptErrorListener(JavaScriptErrorListener listener);
266
```
267
268
**Usage Examples:**
269
270
```java
271
// Custom error listener for debugging
272
webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() {
273
@Override
274
public void scriptException(HtmlPage page, ScriptException scriptException) {
275
System.err.println("JavaScript Error on " + page.getUrl());
276
System.err.println("Error: " + scriptException.getMessage());
277
scriptException.printStackTrace();
278
}
279
280
@Override
281
public void timeoutError(HtmlPage page, long allowedTime, long executionTime) {
282
System.err.println("JavaScript Timeout on " + page.getUrl());
283
System.err.println("Allowed: " + allowedTime + "ms, Actual: " + executionTime + "ms");
284
}
285
286
@Override
287
public void malformedScriptURL(HtmlPage page, String url, MalformedURLException exception) {
288
System.err.println("Malformed Script URL: " + url);
289
}
290
291
@Override
292
public void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception) {
293
System.err.println("Failed to load script: " + scriptUrl);
294
}
295
});
296
297
// Use silent listener to ignore all JavaScript errors
298
webClient.setJavaScriptErrorListener(new SilentJavaScriptErrorListener());
299
300
// Collect errors for testing
301
List<ScriptException> scriptErrors = new ArrayList<>();
302
webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() {
303
@Override
304
public void scriptException(HtmlPage page, ScriptException scriptException) {
305
scriptErrors.add(scriptException);
306
}
307
308
// Implement other methods as needed
309
@Override
310
public void timeoutError(HtmlPage page, long allowedTime, long executionTime) {}
311
@Override
312
public void malformedScriptURL(HtmlPage page, String url, MalformedURLException exception) {}
313
@Override
314
public void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception) {}
315
});
316
```
317
318
### JavaScript Exception Types
319
320
Exception types thrown by JavaScript execution problems.
321
322
```java { .api }
323
public class ScriptException extends RuntimeException {
324
// Runtime JavaScript execution errors
325
// Contains details about the JavaScript error
326
}
327
328
public class ElementNotFoundException extends RuntimeException {
329
// Thrown when JavaScript tries to access non-existent DOM elements
330
}
331
```
332
333
**Usage Examples:**
334
335
```java
336
try {
337
// Enable JavaScript error exceptions
338
webClient.getOptions().setThrowExceptionOnScriptError(true);
339
340
HtmlPage page = webClient.getPage("https://example.com/broken-js");
341
342
} catch (ScriptException e) {
343
System.err.println("JavaScript execution failed: " + e.getMessage());
344
345
// Handle specific error conditions
346
if (e.getMessage().contains("undefined")) {
347
System.err.println("Undefined variable or function");
348
}
349
}
350
```
351
352
### Advanced JavaScript Integration
353
354
Advanced techniques for working with JavaScript-heavy applications.
355
356
**Usage Examples:**
357
358
```java
359
// Configuration for single-page applications (SPAs)
360
WebClient webClient = new WebClient();
361
webClient.getOptions().setJavaScriptEnabled(true);
362
webClient.getOptions().setCssEnabled(true); // May be needed for layout-dependent JS
363
webClient.getOptions().setThrowExceptionOnScriptError(false);
364
365
// Set up comprehensive JavaScript handlers
366
webClient.setAlertHandler((page, message) -> System.out.println("Alert: " + message));
367
webClient.setConfirmHandler((page, message) -> true); // Auto-confirm
368
webClient.setPromptHandler((page, message, defaultValue) -> defaultValue);
369
370
// Load SPA and wait for initialization
371
HtmlPage page = webClient.getPage("https://example.com/spa");
372
373
// Wait for initial JavaScript setup
374
webClient.waitForBackgroundJavaScript(3000);
375
376
// Wait for specific element to appear (loaded by AJAX)
377
int attempts = 0;
378
HtmlElement dynamicButton = null;
379
while (attempts < 10 && dynamicButton == null) {
380
dynamicButton = page.getElementById("ajax-loaded-button");
381
if (dynamicButton == null) {
382
Thread.sleep(500);
383
webClient.waitForBackgroundJavaScript(1000);
384
attempts++;
385
}
386
}
387
388
if (dynamicButton != null) {
389
// Interact with dynamically loaded content
390
dynamicButton.click();
391
webClient.waitForBackgroundJavaScript(2000);
392
}
393
394
// For testing JavaScript-generated content
395
String pageContent = page.asNormalizedText();
396
assertTrue("Expected content not found", pageContent.contains("Dynamic Content Loaded"));
397
```