This builds on request interception, so it is also something you run on a local project rather than in the editor here. The technique is standard on real teams, and interviewers ask about its trade-off often.
Your manager asks a reasonable question: "What does the app show when the server is down?"
You want to test it, but you cannot break the real server just to run a test.
Playwright lets you answer the request yourself. This is called mocking or stubbing: your test gives a fake answer instead of letting the request reach the real server.
await page.route('**/api/contacts', async (route) => {
await route.fulfill({
status: 500,
contentType: 'application/json',
body: JSON.stringify({ error: 'Server error' }),
});
});
await page.goto('/');
await expect(page.getByTestId('error-banner')).toContainText('Something went wrong');
Let's read it. page.route says "catch requests to this address". The function receives a route object, and route.fulfill answers it with whatever you want. The real server is never called.
Set this up before page.goto, or the page will load before your rule exists.
You can use the same trick for other situations that are hard to create: an empty list, a list with 500 items, or a very slow answer so you can check your loading spinner.
Now the part many people skip. Mocking has a real cost.
A mocked test does not check the server at all. If the backend team renames a field from name to fullName, your mock still returns name, so your test still passes. Your suite is green and your app is broken.
I worked with a team that mocked almost every request, because it made the suite fast and steady. It was fast and steady for months. Then an API change went out, every screen showed empty names, and all their tests were green while support answered angry emails.
So split the job:
- Mock the situations that are hard to create: errors, empty states, huge lists, slow responses.
- Do not mock your main happy path. Let at least one test reach the real server, so an API change breaks something.
Remember this: mock to reach a state you cannot create easily. Always keep one real path.
Reference: Mock APIs.