or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-control.mdindex.mdmobile-device.mdnetwork-api.mdpage-interaction.mdtesting-framework.mdvisual-debugging.md

network-api.mddocs/

0

# Network & API Testing

1

2

HTTP request interception, response mocking, API testing capabilities, and network event handling with full request/response control.

3

4

## Capabilities

5

6

### API Request Client

7

8

Built-in HTTP client for API testing and external service communication.

9

10

```typescript { .api }

11

/**

12

* Global API request client

13

*/

14

const request: APIRequest;

15

16

interface APIRequest {

17

/** Create new API request context */

18

newContext(options?: APIRequestNewContextOptions): Promise<APIRequestContext>;

19

}

20

21

interface APIRequestContext {

22

/** Send GET request */

23

get(url: string, options?: APIRequestContextOptions): Promise<APIResponse>;

24

/** Send POST request */

25

post(url: string, options?: APIRequestContextOptions): Promise<APIResponse>;

26

/** Send PUT request */

27

put(url: string, options?: APIRequestContextOptions): Promise<APIResponse>;

28

/** Send PATCH request */

29

patch(url: string, options?: APIRequestContextOptions): Promise<APIResponse>;

30

/** Send DELETE request */

31

delete(url: string, options?: APIRequestContextOptions): Promise<APIResponse>;

32

/** Send HEAD request */

33

head(url: string, options?: APIRequestContextOptions): Promise<APIResponse>;

34

/** Send custom method request */

35

fetch(urlOrRequest: string | Request, options?: APIRequestContextOptions): Promise<APIResponse>;

36

/** Dispose context */

37

dispose(): Promise<void>;

38

/** Store auth state */

39

setExtraHTTPHeaders(headers: { [key: string]: string }): Promise<void>;

40

/** Set storage state */

41

setStorageState(state: { cookies: Cookie[]; origins: any[] }): Promise<void>;

42

/** Get storage state */

43

storageState(options?: { path?: string }): Promise<{ cookies: Cookie[]; origins: any[] }>;

44

}

45

46

interface APIRequestContextOptions {

47

/** Request parameters */

48

params?: { [key: string]: string | number | boolean };

49

/** Request headers */

50

headers?: { [key: string]: string };

51

/** Request body */

52

data?: string | Buffer | object;

53

/** Form data */

54

form?: { [key: string]: string | number | boolean };

55

/** Multipart form data */

56

multipart?: { [key: string]: string | number | boolean | { name: string; mimeType: string; buffer: Buffer } };

57

/** Request timeout */

58

timeout?: number;

59

/** Fail on HTTP error status */

60

failOnStatusCode?: boolean;

61

/** Ignore HTTPS errors */

62

ignoreHTTPSErrors?: boolean;

63

}

64

```

65

66

**Usage Examples:**

67

68

```typescript

69

import { request } from 'playwright';

70

71

// Create API context

72

const apiContext = await request.newContext({

73

baseURL: 'https://api.example.com',

74

extraHTTPHeaders: {

75

'Authorization': 'Bearer token123',

76

'Content-Type': 'application/json'

77

}

78

});

79

80

// Make API requests

81

const response = await apiContext.get('/users');

82

const userData = await response.json();

83

84

const createResponse = await apiContext.post('/users', {

85

data: {

86

name: 'John Doe',

87

email: 'john@example.com'

88

}

89

});

90

91

// Form data

92

const formResponse = await apiContext.post('/upload', {

93

multipart: {

94

file: { name: 'document.pdf', mimeType: 'application/pdf', buffer: fileBuffer },

95

description: 'Important document'

96

}

97

});

98

99

await apiContext.dispose();

100

```

101

102

### API Response Handling

103

104

Handle and inspect HTTP responses from API requests.

105

106

```typescript { .api }

107

interface APIResponse {

108

/** Get response status */

109

status(): number;

110

/** Get status text */

111

statusText(): string;

112

/** Get response URL */

113

url(): string;

114

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

115

ok(): boolean;

116

/** Get response headers */

117

headers(): { [key: string]: string };

118

/** Get response header array */

119

headersArray(): { name: string; value: string }[];

120

/** Get single header value */

121

headerValue(name: string): Promise<string | null>;

122

/** Get all values for header */

123

headerValues(name: string): Promise<string[]>;

124

125

/** Get response body as text */

126

text(): Promise<string>;

127

/** Get response body as JSON */

128

json(): Promise<any>;

129

/** Get response body as buffer */

130

body(): Promise<Buffer>;

131

/** Dispose response */

132

dispose(): Promise<void>;

133

}

134

```

135

136

**Usage Examples:**

137

138

```typescript

139

const response = await apiContext.get('/api/data');

140

141

// Check response status

142

if (response.ok()) {

143

const data = await response.json();

144

console.log('Success:', data);

145

} else {

146

console.error('Error:', response.status(), response.statusText());

147

const errorText = await response.text();

148

console.error('Error body:', errorText);

149

}

150

151

// Inspect headers

152

const contentType = await response.headerValue('content-type');

153

const headers = response.headers();

154

console.log('Content-Type:', contentType);

155

console.log('All headers:', headers);

156

```

157

158

### Request/Response Interception

159

160

Intercept and modify network requests and responses.

161

162

```typescript { .api }

163

interface Page {

164

/** Set route handler for URL pattern */

165

route(url: string | RegExp | (url: URL) => boolean, handler: RouteHandler, options?: PageRouteOptions): Promise<void>;

166

/** Remove route handlers */

167

unroute(url: string | RegExp | (url: URL) => boolean, handler?: RouteHandler): Promise<void>;

168

/** Remove all route handlers */

169

unrouteAll(options?: PageUnrouteAllOptions): Promise<void>;

170

}

171

172

interface BrowserContext {

173

/** Set route handler for context */

174

route(url: string | RegExp | (url: URL) => boolean, handler: RouteHandler, options?: BrowserContextRouteOptions): Promise<void>;

175

/** Remove route handlers */

176

unroute(url: string | RegExp | (url: URL) => boolean, handler?: RouteHandler): Promise<void>;

177

/** Remove all route handlers */

178

unrouteAll(options?: BrowserContextUnrouteAllOptions): Promise<void>;

179

}

180

181

type RouteHandler = (route: Route, request: Request) => Promise<void> | void;

182

183

interface Route {

184

/** Get the request being routed */

185

request(): Request;

186

/** Fulfill request with custom response */

187

fulfill(response: RouteFulfillResponse): Promise<void>;

188

/** Abort request with error */

189

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

190

/** Continue request, optionally modified */

191

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

192

/** Fetch original request */

193

fetch(options?: RouteFetchOptions): Promise<APIResponse>;

194

}

195

196

interface RouteFulfillResponse {

197

/** Response status */

198

status?: number;

199

/** Response headers */

200

headers?: { [key: string]: string };

201

/** Response body */

202

body?: string | Buffer;

203

/** Content type */

204

contentType?: string;

205

/** Response path (file) */

206

path?: string;

207

}

208

209

interface RouteContinueOverrides {

210

/** Override URL */

211

url?: string;

212

/** Override method */

213

method?: string;

214

/** Override headers */

215

headers?: { [key: string]: string };

216

/** Override post data */

217

postData?: string | Buffer;

218

}

219

```

220

221

**Usage Examples:**

222

223

```typescript

224

// Mock API responses

225

await page.route('/api/users', async (route) => {

226

await route.fulfill({

227

status: 200,

228

contentType: 'application/json',

229

body: JSON.stringify([

230

{ id: 1, name: 'John' },

231

{ id: 2, name: 'Jane' }

232

])

233

});

234

});

235

236

// Block specific requests

237

await page.route('**/*.png', async (route) => {

238

await route.abort();

239

});

240

241

// Modify requests

242

await page.route('/api/**', async (route, request) => {

243

const headers = {

244

...request.headers(),

245

'Authorization': 'Bearer test-token'

246

};

247

248

await route.continue({ headers });

249

});

250

251

// Conditional routing

252

await page.route('/api/data', async (route, request) => {

253

if (request.method() === 'POST') {

254

await route.fulfill({

255

status: 201,

256

body: '{"success": true}'

257

});

258

} else {

259

await route.continue();

260

}

261

});

262

```

263

264

### Network Events & Monitoring

265

266

Monitor network activity and handle network events.

267

268

```typescript { .api }

269

interface Page {

270

/** Listen for request events */

271

on(event: 'request', listener: (request: Request) => void): void;

272

/** Listen for response events */

273

on(event: 'response', listener: (response: Response) => void): void;

274

/** Listen for request finished events */

275

on(event: 'requestfinished', listener: (request: Request) => void): void;

276

/** Listen for request failed events */

277

on(event: 'requestfailed', listener: (request: Request) => void): void;

278

}

279

280

interface Request {

281

/** Get request URL */

282

url(): string;

283

/** Get request method */

284

method(): string;

285

/** Get request headers */

286

headers(): { [key: string]: string };

287

/** Get POST data */

288

postData(): string | null;

289

/** Get POST data as buffer */

290

postDataBuffer(): Buffer | null;

291

/** Get POST data as JSON */

292

postDataJSON(): any | null;

293

/** Get resource type */

294

resourceType(): string;

295

/** Get redirected from request */

296

redirectedFrom(): Request | null;

297

/** Get redirected to request */

298

redirectedTo(): Request | null;

299

/** Get request failure */

300

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

301

/** Get request timing */

302

timing(): ResourceTiming;

303

/** Get response */

304

response(): Promise<Response | null>;

305

/** Check if request is navigation */

306

isNavigationRequest(): boolean;

307

/** Get request frame */

308

frame(): Frame;

309

}

310

311

interface Response {

312

/** Get response URL */

313

url(): string;

314

/** Get response status */

315

status(): number;

316

/** Get status text */

317

statusText(): string;

318

/** Check if response is OK */

319

ok(): boolean;

320

/** Get response headers */

321

headers(): { [key: string]: string };

322

/** Get response body */

323

body(): Promise<Buffer>;

324

/** Get response text */

325

text(): Promise<string>;

326

/** Get response JSON */

327

json(): Promise<any>;

328

/** Get request that produced this response */

329

request(): Request;

330

/** Get response frame */

331

frame(): Frame;

332

/** Get server address */

333

serverAddr(): { ipAddress: string; port: number } | null;

334

/** Get security details */

335

securityDetails(): SecurityDetails | null;

336

}

337

338

interface ResourceTiming {

339

startTime: number;

340

domainLookupStart: number;

341

domainLookupEnd: number;

342

connectStart: number;

343

secureConnectionStart: number;

344

connectEnd: number;

345

requestStart: number;

346

responseStart: number;

347

responseEnd: number;

348

}

349

350

interface SecurityDetails {

351

issuer?: string;

352

protocol?: string;

353

subjectName?: string;

354

validFrom?: number;

355

validTo?: number;

356

}

357

```

358

359

**Usage Examples:**

360

361

```typescript

362

// Monitor all requests

363

page.on('request', request => {

364

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

365

});

366

367

// Monitor responses

368

page.on('response', response => {

369

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

370

});

371

372

// Monitor failed requests

373

page.on('requestfailed', request => {

374

console.log('Failed:', request.url(), request.failure()?.errorText);

375

});

376

377

// Analyze network activity

378

const requests: Request[] = [];

379

page.on('request', request => requests.push(request));

380

381

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

382

383

// Get all API requests

384

const apiRequests = requests.filter(req =>

385

req.url().includes('/api/') && req.resourceType() === 'xhr'

386

);

387

388

console.log(`Made ${apiRequests.length} API requests`);

389

```

390

391

### WebSocket Handling

392

393

Handle WebSocket connections and messages.

394

395

```typescript { .api }

396

interface Page {

397

/** Listen for WebSocket events */

398

on(event: 'websocket', listener: (webSocket: WebSocket) => void): void;

399

}

400

401

interface WebSocket {

402

/** Get WebSocket URL */

403

url(): string;

404

/** Check if WebSocket is closed */

405

isClosed(): boolean;

406

/** Wait for WebSocket event */

407

waitForEvent(event: 'close' | 'framereceived' | 'framesent' | 'socketerror', options?: WaitForEventOptions): Promise<any>;

408

409

/** Listen for frame received */

410

on(event: 'framereceived', listener: (payload: WebSocketFrame) => void): void;

411

/** Listen for frame sent */

412

on(event: 'framesent', listener: (payload: WebSocketFrame) => void): void;

413

/** Listen for close event */

414

on(event: 'close', listener: () => void): void;

415

/** Listen for socket error */

416

on(event: 'socketerror', listener: (error: string) => void): void;

417

}

418

419

interface WebSocketFrame {

420

/** Frame payload */

421

payload: string | Buffer;

422

/** Frame opcode */

423

opcode: number;

424

}

425

426

interface WebSocketRoute {

427

/** Get WebSocket URL */

428

url(): string;

429

/** Connect to WebSocket with handler */

430

connectToServer(): Promise<void>;

431

/** Close WebSocket */

432

close(options?: { code?: number; reason?: string }): Promise<void>;

433

/** Send frame to server */

434

send(message: string | Buffer): void;

435

436

/** Listen for messages from page */

437

onMessage(handler: (message: string | Buffer) => void): void;

438

/** Listen for close from page */

439

onClose(handler: () => void): void;

440

}

441

```

442

443

**Usage Examples:**

444

445

```typescript

446

// Monitor WebSocket connections

447

page.on('websocket', ws => {

448

console.log('WebSocket created:', ws.url());

449

450

ws.on('framereceived', frame => {

451

console.log('Received:', frame.payload);

452

});

453

454

ws.on('framesent', frame => {

455

console.log('Sent:', frame.payload);

456

});

457

458

ws.on('close', () => {

459

console.log('WebSocket closed');

460

});

461

});

462

463

// Route WebSocket connections

464

await page.routeWebSocket('/ws', ws => {

465

ws.onMessage(message => {

466

console.log('Message from page:', message);

467

// Echo message back

468

ws.send(`Echo: ${message}`);

469

});

470

});

471

```

472

473

## Types

474

475

### HTTP Configuration Types

476

477

```typescript { .api }

478

interface APIRequestNewContextOptions {

479

/** Base URL for requests */

480

baseURL?: string;

481

/** Extra HTTP headers */

482

extraHTTPHeaders?: { [key: string]: string };

483

/** HTTP credentials */

484

httpCredentials?: HTTPCredentials;

485

/** Ignore HTTPS errors */

486

ignoreHTTPSErrors?: boolean;

487

/** Proxy settings */

488

proxy?: ProxySettings;

489

/** Client certificates */

490

clientCertificates?: ClientCertificate[];

491

/** User agent */

492

userAgent?: string;

493

/** Timeout for requests */

494

timeout?: number;

495

}

496

497

interface PageRouteOptions {

498

/** Times to handle route */

499

times?: number;

500

}

501

502

interface RouteFetchOptions {

503

/** Override URL */

504

url?: string;

505

/** Override method */

506

method?: string;

507

/** Override headers */

508

headers?: { [key: string]: string };

509

/** Override post data */

510

postData?: string | Buffer;

511

/** Request timeout */

512

timeout?: number;

513

}

514

515

interface WaitForEventOptions {

516

/** Event timeout */

517

timeout?: number;

518

/** Predicate function */

519

predicate?: Function;

520

}

521

```