Playwright Network Interception
Playwright's Network Interception is a very useful capability in automated testing and web scraping scenarios, allowing us to intercept, modify, and simulate network requests and responses.
Playwright providespage.route()andpage.on('request') / page.on('response')and other APIs, which can:
- Intercept requests: decide whether to allow, modify URL/headers/body, or directly return mock responses.
- Monitor requests/responses: view request URL, method, headers, response status code, response body, etc.
- Simulate network errors: block requests, return error codes, test the application's fault tolerance logic.
Common use cases:
- Mock API: run front-end UI tests without back-end APIs.
- Modify requests: for example, add token, test abnormal headers.
- Performance debugging: count requests, response time.
- Error injection: simulate server errors such as 500/404.
Intercept requests:page.route()
await page.route('**/api/todos', async route => {
// 拦截匹配的请求
console.log('拦截到请求:', route.request().url());
// 1. 直接放行(继续请求)
await route.continue();
// 2. 修改请求
// await route.continue({ headers: { ...route.request().headers(), 'X-Test': 'true' } });
// 3. 返回 mock 响应
// await route.fulfill({
// status: 200,
// contentType: 'application/json',
// body: JSON.stringify([{ id: 1, text: 'mock todo', done: false }]),
// });
// 4. 拒绝请求
// await route.abort();
});
Parameter description:
page.route(url, handler): register an interceptor,urlsupports string, regex or**wildcard.route.request(): get the request object.route.continue([options]): allow the request, can modify method, headers, postData.route.fulfill(response): directly return a forged response.route.abort([errorCode]): abort the request, common error codes such as"failed","aborted","timedout"。
Monitor requests and responses
// 监听所有请求
page.on('request', req => {
console.log(`➡️ 请求: ${req.method()} ${req.url()}`);
});
// 监听所有响应
page.on('response', async res => {
console.log(`⬅️ 响应: ${res.status()} ${res.url()}`);
});
// 获取响应 body
const response = await page.waitForResponse('**/api/data');
console.log('响应内容:', await response.text());
Common methods:
request.url()/request.method()/request.headers()/request.postData()response.status()/response.headers()/response.text()/response.json()
Simulate network environment
Examples
// Simulate network error
await page.route('**/*.png', route => route.abort('failed'));
// Simulate delay
await page.route('**/api/**', async route => {
await new Promise(r => setTimeout(r, 2000));
await route.continue();
});
</pre>
<hr>
<h2>Complete Example: Mock API</h2>
import { test, expect } from '@playwright/test';
test('Intercept and mock API', async ({ page }) => {
// Intercept /api/todos request and return fixed data
await page.route('**/api/todos', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([
{ id: 1, text: 'Playwright Learning', done: false },
{ id: 2, text: 'Write automated tests', done: true },
]),
});
});
await page.goto('https://example-todo-app.com');
const items = await page.locator('.todo-item').allTextContents();
console.log('Loaded todo items:', items);
// Assert UI displays mock data
await expect(page.locator('.todo-item')).toHaveCount(2);
await expect(page.locator('.todo-item').first()).toContainText('Playwright Learning');
});
await page.route('**/*.png', route => route.abort('failed'));
// Simulate delay
await page.route('**/api/**', async route => {
await new Promise(r => setTimeout(r, 2000));
await route.continue();
});
</pre>
<hr>
<h2>Complete Example: Mock API</h2>
import { test, expect } from '@playwright/test';
test('Intercept and mock API', async ({ page }) => {
// Intercept /api/todos request and return fixed data
await page.route('**/api/todos', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([
{ id: 1, text: 'Playwright Learning', done: false },
{ id: 2, text: 'Write automated tests', done: true },
]),
});
});
await page.goto('https://example-todo-app.com');
const items = await page.locator('.todo-item').allTextContents();
console.log('Loaded todo items:', items);
// Assert UI displays mock data
await expect(page.locator('.todo-item')).toHaveCount(2);
await expect(page.locator('.todo-item').first()).toContainText('Playwright Learning');
});
Network Interception Related APIs
| API | Purpose | Common parameters/description |
|---|---|---|
page.route(url, handler) |
Register request interception | urlCan be string/regex/wildcard |
route.request() |
Get request object | ReturnsRequest |
route.continue([options]) |
Allow request, can modify | { method, headers, postData } |
route.fulfill(response) |
Return custom response | { status, headers, body, contentType } |
route.abort([errorCode]) |
Abort request | Common:'failed', 'aborted', 'timedout' |
page.unroute(url, handler?) |
Remove interception rule | |
page.on('request', cb) |
Monitor request | |
page.on('response', cb) |
Monitor response | |
request.url()/method()/headers()/postData() |
Request information | |
response.status()/headers()/text()/json() |
Response information | |
page.waitForResponse(urlOrPredicate) |
Wait for specific response | Can pass URL or function |