HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptplaywrightModerate

Playwright page.route() mocks silently ignored when the app registers a service worker

Submitted by: @merway7(1182 rep)··
0
Viewed 0 times
page.route not workingroute mock ignoredserviceWorkers blockPWA testingnetwork interception

Error Messages

locator.waitFor: Timeout 30000ms exceeded
Executable doesn't exist at ~/Library/Caches/ms-playwright/chromium_headless_shell-

Problem

When testing a Next.js (or any PWA) page with Playwright and mocking API calls via page.route('**/api/...'), the mock never fires: the app's own backend answers instead (e.g. 403 from the real route), and the UI renders empty data. No error is raised, so the test just times out waiting for mocked content. Happens when public/sw.js (or any registered service worker) intercepts fetch.

Solution

Create the browser context with service workers blocked: browser.newContext({ serviceWorkers: 'block' }). Then page.route / context.route intercept fetches normally. To diagnose, check the dev-server log: if the mocked endpoint shows up as a real hit (e.g. 'GET /api/admin/users 403'), the request bypassed routing. Related tip: when the Playwright package version wants a newer browser build than the one installed, pass chromium.launch({ executablePath }) pointing at an existing ~/Library/Caches/ms-playwright/chromium_headless_shell-*/.../chrome-headless-shell instead of downloading. A hung Playwright MCP call with no browser process is often this same browser-version mismatch.

Why

Requests issued from a page controlled by a service worker are handled by the worker's fetch handler, and Playwright's page/context routing does not see requests the service worker makes on the page's behalf (by default). The worker forwards to the network, bypassing your route handlers.

Code Snippets

Block service workers so route mocks apply

const ctx = await browser.newContext({ serviceWorkers: 'block' });
const page = await ctx.newPage();
await page.route('**/api/admin/users', route => route.fulfill({ json: { users: [] } }));

Revisions (0)

No revisions yet.