Stubbing and mocking network responses lets you make tests deterministic and fast, even when backends are unreliable or unavailable. Playwrightβs routing APIs allow you to intercept requests and provide custom responses for specific endpoints.
Intercepting and Fulfilling Requests
You can use page.route or context.route to match certain URLs and respond with mock data. This is ideal for simulating success and error states without depending on real services.
// stubbing-api-responses.spec.ts
import { test, expect } from '@playwright/test';
test('shows products from a stubbed API', async ({ page }) => {
await page.route('**/api/products', async route => {
const mockResponse = {
status: 200,
contentType: 'application/json',
body: JSON.stringify([
{ id: 1, name: 'Mocked Laptop' },
{ id: 2, name: 'Mocked Headphones' },
]),
};
await route.fulfill(mockResponse);
});
await page.goto('https://demo.myshop.com/products');
await expect(page.getByText('Mocked Laptop')).toBeVisible();
await expect(page.getByText('Mocked Headphones')).toBeVisible();
});
You can also selectively call route.continue() to let some requests reach the real backend while stubbing only particular cases.
Common Mistakes
Mistake 1 β Mocking all APIs in every test
This reduces realism.
β Wrong: Never running any tests against real or staging environments.
β Correct: Use a mix of stubbed and real calls depending on the risk and purpose of each suite.
Mistake 2 β Using fragile URL patterns for routes
This causes inconsistent behaviour.
β Wrong: Matching entire query strings that change frequently.
β Correct: Use stable path segments or tags to identify endpoints.