or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

console-logging.mddomain-management.mdindex.mdjavascript-execution.mdnetwork-operations.mdruntime-events.mdtarget-management.md

network-operations.mddocs/

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

```