0
# Network Operations and Interception
1
2
Handles network operations, request/response interception, authentication, and user agent management. This domain enables comprehensive network monitoring and manipulation capabilities for advanced automation scenarios.
3
4
## Capabilities
5
6
### V102Network Class
7
8
Main class for network operations and request interception. Extends the idealized Network interface to provide v102-specific implementations for network control and monitoring.
9
10
```java { .api }
11
/**
12
* Handles network operations, request/response interception, and authentication
13
*/
14
public class V102Network extends Network<AuthRequired, RequestPaused> {
15
/**
16
* Creates a new V102Network instance with the specified DevTools connection
17
* @param devTools DevTools connection instance (required)
18
*/
19
public V102Network(DevTools devTools);
20
21
/**
22
* Sets a custom user agent override for all requests
23
* @param userAgent UserAgent configuration with user agent string, language, and platform
24
* @return Command to set user agent override
25
*/
26
protected Command<Void> setUserAgentOverride(UserAgent userAgent);
27
28
/**
29
* Enables network caching for all requests
30
* @return Command to enable network caching
31
*/
32
protected Command<Void> enableNetworkCaching();
33
34
/**
35
* Disables network caching for all requests
36
* @return Command to disable network caching
37
*/
38
protected Command<Void> disableNetworkCaching();
39
40
/**
41
* Enables fetch interception for all request patterns
42
* Intercepts both REQUEST and RESPONSE stages
43
* @return Command to enable fetch interception
44
*/
45
protected Command<Void> enableFetchForAllPatterns();
46
47
/**
48
* Disables fetch interception
49
* @return Command to disable fetch interception
50
*/
51
protected Command<Void> disableFetch();
52
53
/**
54
* Returns the authentication required event for handling HTTP auth challenges
55
* @return Event for authentication requests
56
*/
57
protected Event<AuthRequired> authRequiredEvent();
58
59
/**
60
* Returns the request paused event for intercepted requests
61
* @return Event for paused requests during interception
62
*/
63
public Event<RequestPaused> requestPausedEvent();
64
65
/**
66
* Extracts URI from authentication required event
67
* @param authRequired Authentication required event
68
* @return String URI that requires authentication
69
*/
70
protected String getUriFrom(AuthRequired authRequired);
71
72
/**
73
* Continues with authentication using provided credentials
74
* @param authRequired Authentication required event
75
* @param credentials Username and password for authentication
76
* @return Command to provide authentication credentials
77
*/
78
protected Command<Void> continueWithAuth(AuthRequired authRequired, UsernameAndPassword credentials);
79
80
/**
81
* Cancels authentication request
82
* @param authRequired Authentication required event to cancel
83
* @return Command to cancel authentication
84
*/
85
protected Command<Void> cancelAuth(AuthRequired authRequired);
86
87
/**
88
* Creates Selenium HTTP messages from paused request
89
* @param pausedReq Paused request event
90
* @return Either HttpRequest or HttpResponse depending on interception stage
91
*/
92
public Either<HttpRequest, HttpResponse> createSeMessages(RequestPaused pausedReq);
93
94
/**
95
* Extracts request ID from paused request
96
* @param pausedReq Paused request event
97
* @return String request identifier
98
*/
99
protected String getRequestId(RequestPaused pausedReq);
100
101
/**
102
* Continues intercepted request without modification
103
* @param pausedRequest Paused request to continue
104
* @return Command to continue request unchanged
105
*/
106
protected Command<Void> continueWithoutModification(RequestPaused pausedRequest);
107
108
/**
109
* Continues intercepted request with modifications
110
* @param pausedReq Original paused request
111
* @param req Modified HTTP request to send instead
112
* @return Command to continue with modified request
113
*/
114
protected Command<Void> continueRequest(RequestPaused pausedReq, HttpRequest req);
115
116
/**
117
* Fulfills intercepted request with custom response
118
* @param pausedReq Original paused request
119
* @param res Custom HTTP response to return
120
* @return Command to fulfill request with custom response
121
*/
122
protected Command<Void> fulfillRequest(RequestPaused pausedReq, HttpResponse res);
123
}
124
```
125
126
**Usage Examples:**
127
128
### Basic Network Interception
129
130
```java
131
import org.openqa.selenium.chrome.ChromeDriver;
132
import org.openqa.selenium.devtools.DevTools;
133
import org.openqa.selenium.devtools.v102.V102Domains;
134
import org.openqa.selenium.remote.http.HttpRequest;
135
import org.openqa.selenium.remote.http.HttpResponse;
136
137
// Setup
138
ChromeDriver driver = new ChromeDriver();
139
DevTools devTools = driver.getDevTools();
140
devTools.createSession();
141
V102Domains domains = new V102Domains(devTools);
142
143
// Enable network interception
144
devTools.send(domains.network().enableFetchForAllPatterns());
145
146
// Listen for intercepted requests
147
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
148
// Get request/response from the paused request
149
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
150
151
if (message.isLeft()) {
152
// Handle intercepted request
153
HttpRequest request = message.left();
154
System.out.println("Intercepted request: " + request.getMethod() + " " + request.getUri());
155
156
// Continue without modification
157
devTools.send(domains.network().continueWithoutModification(pausedRequest));
158
} else {
159
// Handle intercepted response
160
HttpResponse response = message.right();
161
System.out.println("Intercepted response: " + response.getStatus());
162
163
// Continue without modification
164
devTools.send(domains.network().continueWithoutModification(pausedRequest));
165
}
166
});
167
168
// Navigate to trigger network activity
169
driver.get("https://example.com");
170
171
// Cleanup
172
devTools.send(domains.network().disableFetch());
173
```
174
175
### Request Modification
176
177
```java
178
import org.openqa.selenium.remote.http.HttpMethod;
179
import java.net.URI;
180
181
// Enable interception and modify requests
182
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
183
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
184
185
if (message.isLeft()) {
186
HttpRequest originalRequest = message.left();
187
188
// Modify specific requests
189
if (originalRequest.getUri().toString().contains("/api/data")) {
190
// Create modified request
191
HttpRequest modifiedRequest = new HttpRequest(
192
HttpMethod.GET,
193
originalRequest.getUri().toString() + "?modified=true"
194
);
195
196
// Copy headers from original request
197
originalRequest.getHeaderNames().forEach(headerName -> {
198
originalRequest.getHeaders(headerName).forEach(headerValue -> {
199
modifiedRequest.addHeader(headerName, headerValue);
200
});
201
});
202
203
// Add custom header
204
modifiedRequest.addHeader("X-Modified-By", "Selenium");
205
206
// Continue with modified request
207
devTools.send(domains.network().continueRequest(pausedRequest, modifiedRequest));
208
} else {
209
// Continue original request unchanged
210
devTools.send(domains.network().continueWithoutModification(pausedRequest));
211
}
212
}
213
});
214
```
215
216
### Custom Response Fulfillment
217
218
```java
219
import org.openqa.selenium.remote.http.HttpResponse;
220
221
// Fulfill requests with custom responses
222
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
223
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
224
225
if (message.isLeft()) {
226
HttpRequest request = message.left();
227
228
// Intercept specific API calls and return mock data
229
if (request.getUri().toString().contains("/api/user/profile")) {
230
String mockResponse = "{\"id\": 123, \"name\": \"Mock User\", \"email\": \"mock@example.com\"}";
231
232
HttpResponse customResponse = new HttpResponse();
233
customResponse.setStatus(200);
234
customResponse.addHeader("Content-Type", "application/json");
235
customResponse.setContent(mockResponse.getBytes());
236
237
// Fulfill with custom response
238
devTools.send(domains.network().fulfillRequest(pausedRequest, customResponse));
239
} else {
240
devTools.send(domains.network().continueWithoutModification(pausedRequest));
241
}
242
}
243
});
244
```
245
246
### User Agent and Caching Control
247
248
```java
249
import org.openqa.selenium.devtools.idealized.Network.UserAgent;
250
251
// Set custom user agent
252
UserAgent customAgent = new UserAgent(
253
"MyApp/1.0 (Custom Selenium Agent)",
254
"en-US,en;q=0.9",
255
"Linux x86_64"
256
);
257
devTools.send(domains.network().setUserAgentOverride(customAgent));
258
259
// Disable caching for testing
260
devTools.send(domains.network().disableNetworkCaching());
261
262
// Navigate with custom user agent and no caching
263
driver.get("https://httpbin.org/user-agent");
264
265
// Re-enable caching
266
devTools.send(domains.network().enableNetworkCaching());
267
```
268
269
### Authentication Handling
270
271
```java
272
import org.openqa.selenium.UsernameAndPassword;
273
274
// Handle HTTP authentication challenges
275
devTools.addListener(domains.network().authRequiredEvent(), (authRequired) -> {
276
String uri = domains.network().getUriFrom(authRequired);
277
System.out.println("Authentication required for: " + uri);
278
279
// Provide credentials
280
UsernameAndPassword credentials = new UsernameAndPassword("username", "password");
281
devTools.send(domains.network().continueWithAuth(authRequired, credentials));
282
283
// Or cancel authentication:
284
// devTools.send(domains.network().cancelAuth(authRequired));
285
});
286
287
// Navigate to a site that requires authentication
288
driver.get("https://httpbin.org/basic-auth/username/password");
289
```
290
291
## CDP Protocol Classes
292
293
The V102Network class interacts with several generated CDP protocol classes:
294
295
### Network Domain
296
297
```java { .api }
298
// Generated CDP network classes (available at runtime)
299
class Network {
300
static Command<Void> setUserAgentOverride(String userAgent, String acceptLanguage, String platform, Optional<String> userAgentMetadata);
301
static Command<Void> setCacheDisabled(boolean cacheDisabled);
302
}
303
304
// Network request representation
305
class Request {
306
String getMethod();
307
String getUrl();
308
Map<String, String> getHeaders();
309
Optional<String> getPostData();
310
}
311
```
312
313
### Fetch Domain
314
315
```java { .api }
316
// Generated CDP fetch classes (available at runtime)
317
class Fetch {
318
static Command<Void> enable(Optional<List<RequestPattern>> patterns, Optional<Boolean> handleAuthRequests);
319
static Command<Void> disable();
320
static Event<AuthRequired> authRequired();
321
static Event<RequestPaused> requestPaused();
322
static Command<Void> continueRequest(RequestId requestId, Optional<String> url, Optional<String> method, Optional<String> postData, Optional<List<HeaderEntry>> headers, Optional<Boolean> interceptResponse);
323
static Command<Void> fulfillRequest(RequestId requestId, int responseCode, Optional<List<HeaderEntry>> responseHeaders, Optional<String> binaryResponseHeaders, Optional<String> body, Optional<String> responsePhrase);
324
static Command<Void> continueWithAuth(RequestId requestId, AuthChallengeResponse authChallengeResponse);
325
static Command<GetResponseBodyResponse> getResponseBody(RequestId requestId);
326
}
327
328
// Authentication required event
329
class AuthRequired {
330
RequestId getRequestId();
331
AuthChallenge getAuthChallenge();
332
}
333
334
class AuthChallenge {
335
String getOrigin();
336
String getScheme();
337
String getRealm();
338
}
339
340
// Request paused event
341
class RequestPaused {
342
RequestId getRequestId();
343
Request getRequest();
344
Optional<Integer> getResponseStatusCode();
345
Optional<String> getResponseErrorReason();
346
Optional<List<HeaderEntry>> getResponseHeaders();
347
}
348
349
// Request and response data structures
350
class RequestPattern {
351
RequestPattern(Optional<String> urlPattern, Optional<String> resourceType, Optional<RequestStage> requestStage);
352
}
353
354
enum RequestStage {
355
REQUEST, RESPONSE
356
}
357
358
class HeaderEntry {
359
HeaderEntry(String name, String value);
360
String getName();
361
String getValue();
362
}
363
364
class AuthChallengeResponse {
365
enum Response {
366
PROVIDECREDENTIALS, CANCELAUTH, DEFAULT
367
}
368
369
AuthChallengeResponse(Response response, Optional<String> username, Optional<String> password);
370
}
371
```
372
373
### Selenium Integration Types
374
375
```java { .api }
376
// Selenium network types
377
class UserAgent {
378
String userAgent();
379
String acceptLanguage();
380
String platform();
381
}
382
383
class UsernameAndPassword {
384
String username();
385
String password();
386
}
387
388
class HttpRequest {
389
HttpRequest(HttpMethod method, String uri);
390
HttpMethod getMethod();
391
URI getUri();
392
void addHeader(String name, String value);
393
Iterable<String> getHeaderNames();
394
Iterable<String> getHeaders(String name);
395
Supplier<InputStream> getContent();
396
}
397
398
class HttpResponse {
399
void setStatus(int status);
400
int getStatus();
401
void addHeader(String name, String value);
402
Iterable<String> getHeaderNames();
403
Iterable<String> getHeaders(String name);
404
void setContent(byte[] content);
405
Supplier<InputStream> getContent();
406
}
407
408
class Either<L, R> {
409
boolean isLeft();
410
boolean isRight();
411
L left();
412
R right();
413
}
414
```
415
416
## Network Monitoring Patterns
417
418
### Request Logging
419
420
```java
421
// Log all network requests
422
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
423
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
424
425
if (message.isLeft()) {
426
HttpRequest request = message.left();
427
System.out.println(String.format(
428
"Request: %s %s",
429
request.getMethod(),
430
request.getUri()
431
));
432
}
433
434
devTools.send(domains.network().continueWithoutModification(pausedRequest));
435
});
436
```
437
438
### Response Analysis
439
440
```java
441
// Analyze response data
442
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
443
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
444
445
if (message.isRight()) {
446
HttpResponse response = message.right();
447
System.out.println(String.format(
448
"Response: %d for request %s",
449
response.getStatus(),
450
domains.network().getRequestId(pausedRequest)
451
));
452
453
// Log response headers
454
response.getHeaderNames().forEach(headerName -> {
455
response.getHeaders(headerName).forEach(headerValue -> {
456
System.out.println(" " + headerName + ": " + headerValue);
457
});
458
});
459
}
460
461
devTools.send(domains.network().continueWithoutModification(pausedRequest));
462
});
463
```
464
465
### Conditional Interception
466
467
```java
468
// Intercept only specific types of requests
469
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
470
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
471
472
if (message.isLeft()) {
473
HttpRequest request = message.left();
474
String uri = request.getUri().toString();
475
476
if (uri.contains("/api/") && request.getMethod().equals("POST")) {
477
// Handle API POST requests specially
478
handleApiPostRequest(pausedRequest, request);
479
} else if (uri.endsWith(".css") || uri.endsWith(".js")) {
480
// Block static resources for faster testing
481
HttpResponse blockedResponse = new HttpResponse();
482
blockedResponse.setStatus(204); // No Content
483
devTools.send(domains.network().fulfillRequest(pausedRequest, blockedResponse));
484
} else {
485
devTools.send(domains.network().continueWithoutModification(pausedRequest));
486
}
487
}
488
});
489
```