Skip to contentPlayForge

How do I mock an API response in Playwright?

Written by Jatin Thacker, Automation Architect · Updated

Call page.route() with a pattern for the API address and answer the request with route.fulfill({ json }), before the page makes the call. The page then receives your data instead of the server's, so you can test states such as an empty list or one particular product.

This answer is one piece of Chapter 24: Mocking the Network.

  • Mocking APIs in UI Tests
  • Network Interception & API Mocking
  • Recording and Replaying Traffic with HAR
  • Build: A Mocked Error State

Mocking lets a UI test control what the server says. Real data changes, and some states, such as an empty list, a server error or one unusual record, are hard to produce on demand. With a route in place, the page shows exactly what you sent.

page.route() takes a URL pattern and a handler. The pattern **/api/products* matches the products call whatever its query string. In the handler, route.fulfill({ json }) replies with that object as JSON, and the request never reaches the server. Register the route before goto() or the action that triggers the call, otherwise the request has already gone. To change a real response rather than replace it, call route.fetch() first and edit the result.

One catch: Playwright can only route requests it sees on the network. The practice app normally answers its API from a service worker inside the browser, which Playwright cannot see, so the example pins ?mock=static. On sites that use a service worker, the docs suggest serviceWorkers: 'block'.

In the example, the Live products table on the API Lab page showed one row, the intercepted item at ₹11,900.

mock-api.spec.js(https://practice.learnplayforge.com)
import { test, expect } from '@playwright/test'; test('the products table renders a mocked API response', async ({ page }) => { await page.route('**/api/products*', async (route) => { const json = { page: 1, limit: 6, total: 1, pages: 1, items: [{ sku: 'ROUTED-1', name: 'Intercepted Item', category: 'Test', priceInr: 11900 }], }; await route.fulfill({ json }); }); await page.goto('/api-lab.html?mock=static&seed=42'); await page.getByRole('button', { name: 'Refresh products' }).click(); const rows = page.getByTestId('live-product-row'); await expect(rows).toHaveCount(1); await expect(rows).toContainText('Intercepted Item'); await expect(rows).toContainText('₹11,900'); });
Output
1 passed (2.0s)
Test yourself
A test calls page.goto(), and then page.route() for the API the page fetches as it loads. Why does the page still show real data?

Practised in the full course: the drill Mocking an unloaded page.

See the chapter

AI can write the test now. The job is knowing whether it checks anything. That's what the course teaches, one chapter at a time.

163 lessons · 226 drills · start free

← All questions

Training a team? Talk to us.