0
# Event Handling
1
2
The event handling system provides comprehensive monitoring and logging capabilities for WebDriver actions through event-driven programming patterns. It allows you to register listeners that receive notifications before and after WebDriver operations, enabling detailed logging, debugging, and custom behavior injection.
3
4
## EventFiringWebDriver
5
6
```java { .api }
7
public class EventFiringWebDriver implements WebDriver, JavascriptExecutor, TakesScreenshot, WrapsDriver, HasInputDevices, HasTouchScreen, Interactive, HasCapabilities {
8
/**
9
* Create EventFiringWebDriver wrapper around existing WebDriver
10
*/
11
public EventFiringWebDriver(WebDriver driver);
12
13
/**
14
* Register an event listener to receive WebDriver events
15
*/
16
public EventFiringWebDriver register(WebDriverEventListener eventListener);
17
18
/**
19
* Unregister an event listener
20
*/
21
public EventFiringWebDriver unregister(WebDriverEventListener eventListener);
22
23
/**
24
* Get the wrapped WebDriver instance
25
*/
26
public WebDriver getWrappedDriver();
27
28
// All WebDriver methods with event firing
29
public void get(String url);
30
public String getCurrentUrl();
31
public String getTitle();
32
public List<WebElement> findElements(By by);
33
public WebElement findElement(By by);
34
public String getPageSource();
35
public void close();
36
public void quit();
37
public Set<String> getWindowHandles();
38
public String getWindowHandle();
39
public TargetLocator switchTo();
40
public Navigation navigate();
41
public Options manage();
42
43
// JavascriptExecutor methods with event firing
44
public Object executeScript(String script, Object... args);
45
public Object executeAsyncScript(String script, Object... args);
46
47
// TakesScreenshot methods with event firing
48
public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException;
49
}
50
```
51
52
### Basic EventFiringWebDriver Usage
53
54
```java
55
import org.openqa.selenium.WebDriver;
56
import org.openqa.selenium.chrome.ChromeDriver;
57
import org.openqa.selenium.support.events.EventFiringWebDriver;
58
import org.openqa.selenium.support.events.WebDriverEventListener;
59
60
// Create regular WebDriver
61
WebDriver driver = new ChromeDriver();
62
63
// Wrap with EventFiringWebDriver
64
EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver);
65
66
// Register event listener
67
eventDriver.register(new MyEventListener());
68
69
// Use normally - all actions will fire events
70
eventDriver.get("https://example.com");
71
eventDriver.findElement(By.id("button")).click();
72
73
// Clean up
74
eventDriver.quit();
75
```
76
77
## WebDriverEventListener Interface
78
79
```java { .api }
80
public interface WebDriverEventListener {
81
/**
82
* Called before Alert.accept()
83
*/
84
void beforeAlertAccept(WebDriver driver);
85
86
/**
87
* Called after Alert.accept()
88
*/
89
void afterAlertAccept(WebDriver driver);
90
91
/**
92
* Called before Alert.dismiss()
93
*/
94
void beforeAlertDismiss(WebDriver driver);
95
96
/**
97
* Called after Alert.dismiss()
98
*/
99
void afterAlertDismiss(WebDriver driver);
100
101
/**
102
* Called before navigation to URL
103
*/
104
void beforeNavigateTo(String url, WebDriver driver);
105
106
/**
107
* Called after navigation to URL
108
*/
109
void afterNavigateTo(String url, WebDriver driver);
110
111
/**
112
* Called before back navigation
113
*/
114
void beforeNavigateBack(WebDriver driver);
115
116
/**
117
* Called after back navigation
118
*/
119
void afterNavigateBack(WebDriver driver);
120
121
/**
122
* Called before forward navigation
123
*/
124
void beforeNavigateForward(WebDriver driver);
125
126
/**
127
* Called after forward navigation
128
*/
129
void afterNavigateForward(WebDriver driver);
130
131
/**
132
* Called before page refresh
133
*/
134
void beforeNavigateRefresh(WebDriver driver);
135
136
/**
137
* Called after page refresh
138
*/
139
void afterNavigateRefresh(WebDriver driver);
140
141
/**
142
* Called before element location
143
*/
144
void beforeFindBy(By by, WebElement element, WebDriver driver);
145
146
/**
147
* Called after element location
148
*/
149
void afterFindBy(By by, WebElement element, WebDriver driver);
150
151
/**
152
* Called before element click
153
*/
154
void beforeClickOn(WebElement element, WebDriver driver);
155
156
/**
157
* Called after element click
158
*/
159
void afterClickOn(WebElement element, WebDriver driver);
160
161
/**
162
* Called before element value change (sendKeys, clear)
163
*/
164
void beforeChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend);
165
166
/**
167
* Called after element value change
168
*/
169
void afterChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend);
170
171
/**
172
* Called before JavaScript execution
173
*/
174
void beforeScript(String script, WebDriver driver);
175
176
/**
177
* Called after JavaScript execution
178
*/
179
void afterScript(String script, WebDriver driver);
180
181
/**
182
* Called before window switch
183
*/
184
void beforeSwitchToWindow(String windowName, WebDriver driver);
185
186
/**
187
* Called after window switch
188
*/
189
void afterSwitchToWindow(String windowName, WebDriver driver);
190
191
/**
192
* Called when any WebDriver operation throws an exception
193
*/
194
void onException(Throwable throwable, WebDriver driver);
195
196
/**
197
* Called before screenshot capture
198
*/
199
<X> void beforeGetScreenshotAs(OutputType<X> target);
200
201
/**
202
* Called after screenshot capture
203
*/
204
<X> void afterGetScreenshotAs(OutputType<X> target, X screenshot);
205
206
/**
207
* Called before getText() on element
208
*/
209
void beforeGetText(WebElement element, WebDriver driver);
210
211
/**
212
* Called after getText() on element
213
*/
214
void afterGetText(WebElement element, WebDriver driver, String text);
215
}
216
```
217
218
## AbstractWebDriverEventListener
219
220
```java { .api }
221
public abstract class AbstractWebDriverEventListener implements WebDriverEventListener {
222
// Empty implementations of all WebDriverEventListener methods
223
// Extend this class and override only the methods you need
224
225
public void beforeAlertAccept(WebDriver driver) {}
226
public void afterAlertAccept(WebDriver driver) {}
227
public void beforeAlertDismiss(WebDriver driver) {}
228
public void afterAlertDismiss(WebDriver driver) {}
229
public void beforeNavigateTo(String url, WebDriver driver) {}
230
public void afterNavigateTo(String url, WebDriver driver) {}
231
public void beforeNavigateBack(WebDriver driver) {}
232
public void afterNavigateBack(WebDriver driver) {}
233
public void beforeNavigateForward(WebDriver driver) {}
234
public void afterNavigateForward(WebDriver driver) {}
235
public void beforeNavigateRefresh(WebDriver driver) {}
236
public void afterNavigateRefresh(WebDriver driver) {}
237
public void beforeFindBy(By by, WebElement element, WebDriver driver) {}
238
public void afterFindBy(By by, WebElement element, WebDriver driver) {}
239
public void beforeClickOn(WebElement element, WebDriver driver) {}
240
public void afterClickOn(WebElement element, WebDriver driver) {}
241
public void beforeChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend) {}
242
public void afterChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend) {}
243
public void beforeScript(String script, WebDriver driver) {}
244
public void afterScript(String script, WebDriver driver) {}
245
public void beforeSwitchToWindow(String windowName, WebDriver driver) {}
246
public void afterSwitchToWindow(String windowName, WebDriver driver) {}
247
public void onException(Throwable throwable, WebDriver driver) {}
248
public <X> void beforeGetScreenshotAs(OutputType<X> target) {}
249
public <X> void afterGetScreenshotAs(OutputType<X> target, X screenshot) {}
250
public void beforeGetText(WebElement element, WebDriver driver) {}
251
public void afterGetText(WebElement element, WebDriver driver, String text) {}
252
}
253
```
254
255
## Event Handler Examples
256
257
### Logging Event Listener
258
259
```java
260
import org.openqa.selenium.support.events.AbstractWebDriverEventListener;
261
import java.util.logging.Logger;
262
263
public class LoggingEventListener extends AbstractWebDriverEventListener {
264
private static final Logger LOG = Logger.getLogger(LoggingEventListener.class.getName());
265
266
@Override
267
public void beforeNavigateTo(String url, WebDriver driver) {
268
LOG.info("Navigating to: " + url);
269
}
270
271
@Override
272
public void afterNavigateTo(String url, WebDriver driver) {
273
LOG.info("Successfully navigated to: " + url);
274
}
275
276
@Override
277
public void beforeClickOn(WebElement element, WebDriver driver) {
278
LOG.info("Clicking on element: " + element.toString());
279
}
280
281
@Override
282
public void afterClickOn(WebElement element, WebDriver driver) {
283
LOG.info("Successfully clicked on element");
284
}
285
286
@Override
287
public void beforeChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend) {
288
LOG.info("Typing into element: " + element.toString() +
289
" with text: " + Arrays.toString(keysToSend));
290
}
291
292
@Override
293
public void onException(Throwable throwable, WebDriver driver) {
294
LOG.severe("Exception occurred: " + throwable.getMessage());
295
}
296
}
297
```
298
299
### Screenshot-on-Failure Listener
300
301
```java
302
public class ScreenshotOnFailureListener extends AbstractWebDriverEventListener {
303
private final String screenshotDir;
304
305
public ScreenshotOnFailureListener(String screenshotDir) {
306
this.screenshotDir = screenshotDir;
307
}
308
309
@Override
310
public void onException(Throwable throwable, WebDriver driver) {
311
if (driver instanceof TakesScreenshot) {
312
String filename = "failure_" + System.currentTimeMillis() + ".png";
313
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
314
try {
315
Files.copy(screenshot.toPath(),
316
Paths.get(screenshotDir, filename));
317
System.out.println("Screenshot saved: " + filename);
318
} catch (IOException e) {
319
System.err.println("Failed to save screenshot: " + e.getMessage());
320
}
321
}
322
}
323
}
324
```
325
326
### Performance Monitoring Listener
327
328
```java
329
public class PerformanceMonitorListener extends AbstractWebDriverEventListener {
330
private final Map<String, Long> operationTimes = new HashMap<>();
331
332
@Override
333
public void beforeNavigateTo(String url, WebDriver driver) {
334
operationTimes.put("navigation_" + url, System.currentTimeMillis());
335
}
336
337
@Override
338
public void afterNavigateTo(String url, WebDriver driver) {
339
Long startTime = operationTimes.remove("navigation_" + url);
340
if (startTime != null) {
341
long duration = System.currentTimeMillis() - startTime;
342
System.out.println("Navigation to " + url + " took " + duration + "ms");
343
}
344
}
345
346
@Override
347
public void beforeClickOn(WebElement element, WebDriver driver) {
348
operationTimes.put("click_" + element.hashCode(), System.currentTimeMillis());
349
}
350
351
@Override
352
public void afterClickOn(WebElement element, WebDriver driver) {
353
Long startTime = operationTimes.remove("click_" + element.hashCode());
354
if (startTime != null) {
355
long duration = System.currentTimeMillis() - startTime;
356
System.out.println("Click operation took " + duration + "ms");
357
}
358
}
359
360
@Override
361
public void beforeScript(String script, WebDriver driver) {
362
operationTimes.put("script_" + script.hashCode(), System.currentTimeMillis());
363
}
364
365
@Override
366
public void afterScript(String script, WebDriver driver) {
367
Long startTime = operationTimes.remove("script_" + script.hashCode());
368
if (startTime != null) {
369
long duration = System.currentTimeMillis() - startTime;
370
System.out.println("JavaScript execution took " + duration + "ms");
371
}
372
}
373
}
374
```
375
376
## Internal Event Components
377
378
### EventFiringKeyboard
379
380
```java { .api }
381
public class EventFiringKeyboard implements Keyboard {
382
/**
383
* Keyboard wrapper for event firing (internal use)
384
*/
385
public EventFiringKeyboard(WebDriver driver, WebDriverEventListener dispatcher);
386
387
public void sendKeys(CharSequence... keysToSend);
388
public void pressKey(CharSequence keyToPress);
389
public void releaseKey(CharSequence keyToRelease);
390
}
391
```
392
393
### EventFiringMouse
394
395
```java { .api }
396
public class EventFiringMouse implements Mouse {
397
/**
398
* Mouse wrapper for event firing (internal use)
399
*/
400
public EventFiringMouse(WebDriver driver, WebDriverEventListener dispatcher);
401
402
public void click(Coordinates where);
403
public void doubleClick(Coordinates where);
404
public void mouseDown(Coordinates where);
405
public void mouseUp(Coordinates where);
406
public void mouseMove(Coordinates where);
407
public void mouseMove(Coordinates where, long xOffset, long yOffset);
408
public void contextClick(Coordinates where);
409
}
410
```
411
412
### EventFiringTouch
413
414
```java { .api }
415
public class EventFiringTouch implements TouchScreen {
416
/**
417
* TouchScreen wrapper for event firing (internal use)
418
*/
419
public EventFiringTouch(WebDriver driver, WebDriverEventListener dispatcher);
420
421
public void singleTap(Coordinates where);
422
public void down(int x, int y);
423
public void up(int x, int y);
424
public void move(int x, int y);
425
public void scroll(Coordinates where, int xOffset, int yOffset);
426
public void doubleTap(Coordinates where);
427
public void longPress(Coordinates where);
428
public void scroll(int xOffset, int yOffset);
429
public void flick(int xSpeed, int ySpeed);
430
public void flick(Coordinates where, int xOffset, int yOffset, int speed);
431
}
432
```
433
434
## Advanced Event Patterns
435
436
### Multiple Listeners
437
438
```java
439
EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver);
440
441
// Register multiple listeners for different purposes
442
eventDriver.register(new LoggingEventListener());
443
eventDriver.register(new ScreenshotOnFailureListener("screenshots/"));
444
eventDriver.register(new PerformanceMonitorListener());
445
eventDriver.register(new CustomValidationListener());
446
447
// All listeners will receive events
448
eventDriver.get("https://example.com");
449
```
450
451
### Conditional Event Handling
452
453
```java
454
public class ConditionalEventListener extends AbstractWebDriverEventListener {
455
private boolean enableLogging = true;
456
private boolean enableScreenshots = false;
457
458
public void setLoggingEnabled(boolean enabled) {
459
this.enableLogging = enabled;
460
}
461
462
public void setScreenshotsEnabled(boolean enabled) {
463
this.enableScreenshots = enabled;
464
}
465
466
@Override
467
public void beforeClickOn(WebElement element, WebDriver driver) {
468
if (enableLogging) {
469
System.out.println("Clicking: " + element.getTagName());
470
}
471
}
472
473
@Override
474
public void onException(Throwable throwable, WebDriver driver) {
475
if (enableScreenshots && driver instanceof TakesScreenshot) {
476
// Take screenshot on exception
477
captureScreenshot(driver);
478
}
479
}
480
}
481
```
482
483
### Event Data Collection
484
485
```java
486
public class DataCollectionListener extends AbstractWebDriverEventListener {
487
private final List<EventData> events = new ArrayList<>();
488
489
@Override
490
public void afterNavigateTo(String url, WebDriver driver) {
491
events.add(new EventData("navigation", url, System.currentTimeMillis()));
492
}
493
494
@Override
495
public void afterClickOn(WebElement element, WebDriver driver) {
496
String elementInfo = element.getTagName() +
497
(element.getAttribute("id") != null ?
498
"#" + element.getAttribute("id") : "");
499
events.add(new EventData("click", elementInfo, System.currentTimeMillis()));
500
}
501
502
public List<EventData> getCollectedEvents() {
503
return new ArrayList<>(events);
504
}
505
506
public void clearEvents() {
507
events.clear();
508
}
509
510
public static class EventData {
511
public final String type;
512
public final String details;
513
public final long timestamp;
514
515
public EventData(String type, String details, long timestamp) {
516
this.type = type;
517
this.details = details;
518
this.timestamp = timestamp;
519
}
520
}
521
}
522
```