or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-contexts.mdbrowser-management.mdelement-handling.mdindex.mdinput-simulation.mdlocators-selectors.mdnetwork-management.mdpage-interaction.md

network-management.mddocs/

0

# Network Management

1

2

Request interception, response mocking, and comprehensive network monitoring for testing and debugging.

3

4

## Capabilities

5

6

### HTTPRequest Interface

7

8

Represents an HTTP request that can be intercepted, modified, or monitored.

9

10

```typescript { .api }

11

interface HTTPRequest {

12

/** Get request URL */

13

url(): string;

14

/** Get resource type */

15

resourceType(): ResourceType;

16

/** Get HTTP method */

17

method(): string;

18

/** Get request headers */

19

headers(): Record<string, string>;

20

/** Get POST data */

21

postData(): string | undefined;

22

/** Get POST data as buffer */

23

postDataBuffer(): Buffer | undefined;

24

/** Check if request is navigation request */

25

isNavigationRequest(): boolean;

26

/** Check if request is intercepted */

27

isInterceptResolutionHandled(): boolean;

28

/** Get response */

29

response(): HTTPResponse | null;

30

/** Get frame that initiated request */

31

frame(): Frame | null;

32

/** Get redirect chain */

33

redirectChain(): HTTPRequest[];

34

/** Get failure details if request failed */

35

failure(): { errorText: string } | null;

36

/** Abort request */

37

abort(errorCode?: ErrorCode): Promise<void>;

38

/** Continue request with optional overrides */

39

continue(overrides?: ContinueRequestOverrides): Promise<void>;

40

/** Respond to request with mock response */

41

respond(response: ResponseForRequest): Promise<void>;

42

/** Get request initiator */

43

initiator(): Initiator;

44

/** Check if request has POST data */

45

hasPostData(): boolean;

46

}

47

48

type ResourceType =

49

| "document"

50

| "stylesheet"

51

| "image"

52

| "media"

53

| "font"

54

| "script"

55

| "texttrack"

56

| "xhr"

57

| "fetch"

58

| "prefetch"

59

| "eventsource"

60

| "websocket"

61

| "manifest"

62

| "signedexchange"

63

| "ping"

64

| "cspviolationreport"

65

| "preflight"

66

| "other";

67

68

type ErrorCode =

69

| "aborted"

70

| "accessdenied"

71

| "addressunreachable"

72

| "blockedbyclient"

73

| "blockedbyresponse"

74

| "connectionaborted"

75

| "connectionclosed"

76

| "connectionfailed"

77

| "connectionrefused"

78

| "connectionreset"

79

| "internetdisconnected"

80

| "namenotresolved"

81

| "timedout"

82

| "failed";

83

84

interface ContinueRequestOverrides {

85

/** Override URL */

86

url?: string;

87

/** Override method */

88

method?: string;

89

/** Override POST data */

90

postData?: string;

91

/** Override headers */

92

headers?: Record<string, string>;

93

}

94

95

interface ResponseForRequest {

96

/** Response status code */

97

status?: number;

98

/** Response headers */

99

headers?: Record<string, string>;

100

/** Response body */

101

body?: string | Buffer;

102

/** Content type header */

103

contentType?: string;

104

}

105

106

interface Initiator {

107

/** Type of initiator */

108

type: "parser" | "script" | "preload" | "SignedExchange" | "preflight" | "other";

109

/** Stack trace if initiated by script */

110

stack?: CallFrame[];

111

/** URL if initiated by parser */

112

url?: string;

113

/** Line number */

114

lineNumber?: number;

115

/** Column number */

116

columnNumber?: number;

117

}

118

119

interface CallFrame {

120

functionName: string;

121

scriptId: string;

122

url: string;

123

lineNumber: number;

124

columnNumber: number;

125

}

126

```

127

128

**Usage Examples:**

129

130

```typescript

131

import puppeteer from "puppeteer-core";

132

133

const browser = await puppeteer.launch({ executablePath: "/path/to/chrome" });

134

const page = await browser.newPage();

135

136

// Enable request interception

137

await page.setRequestInterception(true);

138

139

// Basic request monitoring

140

page.on("request", (request) => {

141

console.log("Request:", request.method(), request.url());

142

console.log("Resource type:", request.resourceType());

143

console.log("Headers:", request.headers());

144

145

// Continue all requests normally

146

request.continue();

147

});

148

149

// Block specific resource types

150

page.on("request", (request) => {

151

if (request.resourceType() === "image") {

152

request.abort("blockedbyclient");

153

} else {

154

request.continue();

155

}

156

});

157

158

// Modify requests

159

page.on("request", (request) => {

160

const overrides: ContinueRequestOverrides = {};

161

162

// Add custom header

163

overrides.headers = {

164

...request.headers(),

165

"X-Custom-Header": "custom-value"

166

};

167

168

// Modify user agent

169

if (request.headers()["user-agent"]) {

170

overrides.headers["user-agent"] = "Custom-User-Agent/1.0";

171

}

172

173

request.continue(overrides);

174

});

175

176

// Mock API responses

177

page.on("request", (request) => {

178

if (request.url().includes("/api/users")) {

179

request.respond({

180

status: 200,

181

contentType: "application/json",

182

body: JSON.stringify([

183

{ id: 1, name: "John Doe" },

184

{ id: 2, name: "Jane Smith" }

185

])

186

});

187

} else {

188

request.continue();

189

}

190

});

191

192

await page.goto("https://example.com");

193

await browser.close();

194

```

195

196

### HTTPResponse Interface

197

198

Represents an HTTP response received from the server.

199

200

```typescript { .api }

201

interface HTTPResponse {

202

/** Get response URL */

203

url(): string;

204

/** Check if response is successful (200-299) */

205

ok(): boolean;

206

/** Get status code */

207

status(): number;

208

/** Get status text */

209

statusText(): string;

210

/** Get response headers */

211

headers(): Record<string, string>;

212

/** Get security details for HTTPS */

213

securityDetails(): SecurityDetails | null;

214

/** Get request that produced this response */

215

request(): HTTPRequest;

216

/** Check if response was served from cache */

217

fromCache(): boolean;

218

/** Check if response was served from service worker */

219

fromServiceWorker(): boolean;

220

/** Get frame that received this response */

221

frame(): Frame | null;

222

/** Get response body as text */

223

text(): Promise<string>;

224

/** Get response body as JSON */

225

json(): Promise<any>;

226

/** Get response body as buffer */

227

buffer(): Promise<Buffer>;

228

/** Get timing information */

229

timing(): ResponseTiming | null;

230

/** Get remote address */

231

remoteAddress(): RemoteAddress;

232

}

233

234

interface SecurityDetails {

235

/** Subject name */

236

subjectName(): string;

237

/** Issuer name */

238

issuer(): string;

239

/** Valid from timestamp */

240

validFrom(): number;

241

/** Valid to timestamp */

242

validTo(): number;

243

/** Protocol version */

244

protocol(): string;

245

/** Subject alternative names */

246

subjectAlternativeNames(): string[];

247

}

248

249

interface ResponseTiming {

250

/** Request start time */

251

requestTime: number;

252

/** Proxy start time */

253

proxyStart: number;

254

/** Proxy end time */

255

proxyEnd: number;

256

/** DNS start time */

257

dnsStart: number;

258

/** DNS end time */

259

dnsEnd: number;

260

/** Connect start time */

261

connectStart: number;

262

/** Connect end time */

263

connectEnd: number;

264

/** SSL start time */

265

sslStart: number;

266

/** SSL end time */

267

sslEnd: number;

268

/** Worker start time */

269

workerStart: number;

270

/** Worker ready time */

271

workerReady: number;

272

/** Send start time */

273

sendStart: number;

274

/** Send end time */

275

sendEnd: number;

276

/** Push start time */

277

pushStart: number;

278

/** Push end time */

279

pushEnd: number;

280

/** Receive headers end time */

281

receiveHeadersEnd: number;

282

}

283

284

interface RemoteAddress {

285

/** IP address */

286

ip: string;

287

/** Port number */

288

port: number;

289

}

290

```

291

292

**Usage Examples:**

293

294

```typescript

295

// Response monitoring

296

page.on("response", async (response) => {

297

console.log("Response:", response.status(), response.url());

298

console.log("Headers:", response.headers());

299

console.log("From cache:", response.fromCache());

300

console.log("From service worker:", response.fromServiceWorker());

301

302

if (!response.ok()) {

303

console.log("Failed response:", response.statusText());

304

}

305

306

// Get response body for specific URLs

307

if (response.url().includes("/api/")) {

308

const body = await response.text();

309

console.log("API Response body:", body);

310

}

311

});

312

313

// Security information for HTTPS

314

page.on("response", (response) => {

315

const security = response.securityDetails();

316

if (security) {

317

console.log("Certificate subject:", security.subjectName());

318

console.log("Certificate issuer:", security.issuer());

319

console.log("Protocol:", security.protocol());

320

}

321

});

322

323

// Performance monitoring

324

page.on("response", (response) => {

325

const timing = response.timing();

326

if (timing) {

327

const totalTime = timing.receiveHeadersEnd - timing.requestTime;

328

console.log(`Request to ${response.url()} took ${totalTime}ms`);

329

}

330

});

331

```

332

333

### Request Interception Patterns

334

335

Common patterns for request interception and modification:

336

337

```typescript { .api }

338

interface RequestInterceptionPatterns {

339

/** Block resources by type or URL pattern */

340

blockResources(patterns: ResourceBlockPattern[]): void;

341

/** Mock API endpoints */

342

mockAPIs(mocks: APIMock[]): void;

343

/** Add authentication headers */

344

addAuth(token: string): void;

345

/** Modify user agent */

346

setUserAgent(userAgent: string): void;

347

/** Add CORS headers to responses */

348

enableCORS(): void;

349

/** Log all network activity */

350

logAllRequests(): void;

351

}

352

353

interface ResourceBlockPattern {

354

resourceType?: ResourceType;

355

urlPattern?: string | RegExp;

356

errorCode?: ErrorCode;

357

}

358

359

interface APIMock {

360

urlPattern: string | RegExp;

361

method?: string;

362

response: ResponseForRequest;

363

}

364

```

365

366

**Usage Examples:**

367

368

```typescript

369

// Block images and stylesheets for faster loading

370

await page.setRequestInterception(true);

371

372

page.on("request", (request) => {

373

const blockedTypes = ["image", "stylesheet", "font"];

374

if (blockedTypes.includes(request.resourceType())) {

375

request.abort("blockedbyclient");

376

} else {

377

request.continue();

378

}

379

});

380

381

// Mock multiple API endpoints

382

const apiMocks = [

383

{

384

url: "/api/users",

385

response: {

386

status: 200,

387

contentType: "application/json",

388

body: JSON.stringify([{ id: 1, name: "Test User" }])

389

}

390

},

391

{

392

url: "/api/config",

393

response: {

394

status: 200,

395

contentType: "application/json",

396

body: JSON.stringify({ theme: "dark", version: "1.0.0" })

397

}

398

}

399

];

400

401

page.on("request", (request) => {

402

const mock = apiMocks.find(m => request.url().includes(m.url));

403

if (mock) {

404

request.respond(mock.response);

405

} else {

406

request.continue();

407

}

408

});

409

410

// Add authentication to all API requests

411

page.on("request", (request) => {

412

if (request.url().includes("/api/")) {

413

const headers = {

414

...request.headers(),

415

"Authorization": "Bearer your-token-here"

416

};

417

request.continue({ headers });

418

} else {

419

request.continue();

420

}

421

});

422

423

// Comprehensive request logging

424

page.on("request", (request) => {

425

console.log(`→ ${request.method()} ${request.url()}`);

426

console.log(` Type: ${request.resourceType()}`);

427

console.log(` Headers:`, request.headers());

428

429

if (request.postData()) {

430

console.log(` POST data:`, request.postData());

431

}

432

433

request.continue();

434

});

435

436

page.on("response", async (response) => {

437

console.log(`← ${response.status()} ${response.url()}`);

438

console.log(` Headers:`, response.headers());

439

440

if (response.url().includes("/api/")) {

441

const body = await response.text();

442

console.log(` Body:`, body);

443

}

444

});

445

446

page.on("requestfailed", (request) => {

447

const failure = request.failure();

448

console.log(`✗ ${request.url()} failed: ${failure?.errorText}`);

449

});

450

```

451

452

### Network Events

453

454

Page-level network events for monitoring and debugging:

455

456

```typescript { .api }

457

interface NetworkEvents {

458

/** Emitted when request starts */

459

"request": (request: HTTPRequest) => void;

460

/** Emitted when response received */

461

"response": (response: HTTPResponse) => void;

462

/** Emitted when request completes successfully */

463

"requestfinished": (request: HTTPRequest) => void;

464

/** Emitted when request fails */

465

"requestfailed": (request: HTTPRequest) => void;

466

}

467

```

468

469

**Usage Examples:**

470

471

```typescript

472

// Network event monitoring

473

const networkEvents = [];

474

475

page.on("request", (request) => {

476

networkEvents.push({

477

type: "request",

478

url: request.url(),

479

method: request.method(),

480

timestamp: Date.now()

481

});

482

});

483

484

page.on("response", (response) => {

485

networkEvents.push({

486

type: "response",

487

url: response.url(),

488

status: response.status(),

489

timestamp: Date.now()

490

});

491

});

492

493

page.on("requestfailed", (request) => {

494

const failure = request.failure();

495

networkEvents.push({

496

type: "requestfailed",

497

url: request.url(),

498

error: failure?.errorText,

499

timestamp: Date.now()

500

});

501

});

502

503

// Analyze network activity after page load

504

await page.goto("https://example.com");

505

await page.waitForLoadState("networkidle");

506

507

console.log("Network activity summary:");

508

console.log(`Total requests: ${networkEvents.filter(e => e.type === "request").length}`);

509

console.log(`Successful responses: ${networkEvents.filter(e => e.type === "response").length}`);

510

console.log(`Failed requests: ${networkEvents.filter(e => e.type === "requestfailed").length}`);

511

```

512

513

### Advanced Network Features

514

515

Advanced networking capabilities and utilities:

516

517

```typescript { .api }

518

interface AdvancedNetworkFeatures {

519

/** Wait for specific request/response */

520

waitForRequest(urlOrPredicate: string | ((req: HTTPRequest) => boolean), options?: WaitForOptions): Promise<HTTPRequest>;

521

waitForResponse(urlOrPredicate: string | ((res: HTTPResponse) => boolean), options?: WaitForOptions): Promise<HTTPResponse>;

522

/** Capture network traffic */

523

captureNetworkTraffic(): NetworkCapture;

524

/** Simulate network conditions */

525

setNetworkConditions(conditions: NetworkConditions): Promise<void>;

526

/** Set offline mode */

527

setOfflineMode(enabled: boolean): Promise<void>;

528

/** Set user agent */

529

setUserAgent(userAgent: string, userAgentMetadata?: UserAgentMetadata): Promise<void>;

530

/** Set extra HTTP headers */

531

setExtraHTTPHeaders(headers: Record<string, string>): Promise<void>;

532

/** Authenticate with HTTP credentials */

533

authenticate(credentials: Credentials | null): Promise<void>;

534

}

535

536

interface NetworkCapture {

537

/** Start capturing */

538

start(): Promise<void>;

539

/** Stop capturing and return data */

540

stop(): Promise<NetworkTrafficEntry[]>;

541

}

542

543

interface NetworkTrafficEntry {

544

request: {

545

url: string;

546

method: string;

547

headers: Record<string, string>;

548

postData?: string;

549

timestamp: number;

550

};

551

response?: {

552

status: number;

553

headers: Record<string, string>;

554

body: string;

555

timestamp: number;

556

};

557

timing: ResponseTiming;

558

}

559

560

interface NetworkConditions {

561

/** Download speed in bytes/sec */

562

downloadThroughput: number;

563

/** Upload speed in bytes/sec */

564

uploadThroughput: number;

565

/** Latency in milliseconds */

566

latency: number;

567

/** Offline mode */

568

offline?: boolean;

569

}

570

571

interface WaitForOptions {

572

/** Maximum wait time */

573

timeout?: number;

574

/** Wait for navigation to complete */

575

waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[];

576

}

577

```

578

579

**Usage Examples:**

580

581

```typescript

582

// Wait for specific requests/responses

583

const apiRequest = page.waitForRequest(req =>

584

req.url().includes("/api/data") && req.method() === "POST"

585

);

586

587

const apiResponse = page.waitForResponse(res =>

588

res.url().includes("/api/data") && res.status() === 200

589

);

590

591

// Trigger the requests

592

await page.click("#load-data-button");

593

594

// Wait for completion

595

const [request, response] = await Promise.all([apiRequest, apiResponse]);

596

console.log("API call completed:", response.status());

597

598

// Simulate slow network

599

await page.emulateNetworkConditions({

600

downloadThroughput: 50 * 1024, // 50KB/s

601

uploadThroughput: 20 * 1024, // 20KB/s

602

latency: 200 // 200ms

603

});

604

605

// Test offline functionality

606

await page.setOfflineMode(true);

607

try {

608

await page.goto("https://example.com");

609

} catch (error) {

610

console.log("Page failed to load offline:", error.message);

611

}

612

await page.setOfflineMode(false);

613

614

// Set custom headers for all requests

615

await page.setExtraHTTPHeaders({

616

"X-API-Key": "your-api-key",

617

"X-Client-Version": "1.0.0"

618

});

619

620

// HTTP authentication

621

await page.authenticate({

622

username: "testuser",

623

password: "testpass"

624

});

625

```

626

627

### Error Handling

628

629

Network-related error handling and debugging:

630

631

```typescript { .api }

632

class NetworkError extends Error {

633

constructor(message: string);

634

}

635

636

class RequestInterceptionError extends NetworkError {

637

constructor(message: string);

638

}

639

640

class ResponseError extends NetworkError {

641

constructor(message: string, response: HTTPResponse);

642

response: HTTPResponse;

643

}

644

```

645

646

**Usage Examples:**

647

648

```typescript

649

// Robust request interception with error handling

650

page.on("request", async (request) => {

651

try {

652

if (request.url().includes("/api/")) {

653

// Validate request before continuing

654

const headers = request.headers();

655

if (!headers["authorization"]) {

656

await request.respond({

657

status: 401,

658

body: JSON.stringify({ error: "Unauthorized" })

659

});

660

return;

661

}

662

}

663

664

await request.continue();

665

} catch (error) {

666

console.log("Request interception error:", error.message);

667

// Fallback: continue the request

668

try {

669

await request.continue();

670

} catch (fallbackError) {

671

console.log("Fallback failed:", fallbackError.message);

672

}

673

}

674

});

675

676

// Handle response errors gracefully

677

page.on("response", async (response) => {

678

if (!response.ok()) {

679

console.log(`HTTP ${response.status()} for ${response.url()}`);

680

681

try {

682

const body = await response.text();

683

console.log("Error response body:", body);

684

} catch (error) {

685

console.log("Could not read error response body:", error.message);

686

}

687

}

688

});

689

690

// Retry failed requests

691

async function waitForResponseWithRetry(

692

page: Page,

693

urlPattern: string,

694

maxRetries = 3

695

): Promise<HTTPResponse> {

696

for (let i = 0; i < maxRetries; i++) {

697

try {

698

const response = await page.waitForResponse(

699

res => res.url().includes(urlPattern),

700

{ timeout: 10000 }

701

);

702

703

if (response.ok()) {

704

return response;

705

}

706

707

console.log(`Attempt ${i + 1}: Response ${response.status()}`);

708

} catch (error) {

709

console.log(`Attempt ${i + 1} failed:`, error.message);

710

}

711

712

if (i < maxRetries - 1) {

713

await page.waitForTimeout(1000 * (i + 1)); // Exponential backoff

714

}

715

}

716

717

throw new NetworkError(`Failed to get successful response after ${maxRetries} attempts`);

718

}

719

```