[Bug]: navigator.serviceWorker.controller returns null in Firefox
Version
1.52.0
Steps to reproduce
When navigating to pages that use service workers in Firefox (v137), navigator.serviceWorker.controller incorrectly returns null, even though a service worker instance is active and controlling the page. This seems to happen in case the service worker does not fetch the request but synchronously returns to the browser. This issue does not happen in the real version of Firefox, and it also was not an issue in the previous versions of playwright.
To reproduce the issue, I implemented a test page https://savory-castle-64.app.baqend.com/playwright-issue/ on which a simple service worker gets installed that fetches all HTML pages except for "/blacklisted" path.
- Open https://savory-castle-64.app.baqend.com/playwright-issue/ with playwright Firefox (v137)
- Open the inspector and paste
(await navigator.serviceWorker.getRegistrations())[0]into the console to see that a service worker is active - Click on the "Navigate to blacklisted page" button
- Enter
navigator.serviceWorker.controllerin the console and see that it returns null - Revalidate that the service worker is still active with
(await navigator.serviceWorker.getRegistrations())[0] - Navigate back to landing page which is served by the service worker
- Enter
navigator.serviceWorker.controllerin the console and see that it returns the service worker instance as expected
Expected behavior
navigator.serviceWorker.controller should return the active service worker instance for every page load
regardless of if the page was served by the service worker.
Actual behavior
navigator.serviceWorker.controller returns null in case the page was not served by the service worker
Additional context
Service worker code
self.addEventListener('fetch', (event) => {
const { request } = event;
// Only handle HTML requests
const isHTML = request.headers.get('accept')?.includes('text/html');
if (!isHTML) {
return;
}
const url = new URL(request.url);
// Skip handling for the /blacklisted route
if (url.pathname.includes('/blacklisted')) {
// Do nothing — let the browser handle the fetch
return;
}
// For all other HTML requests, respond with a fetch
event.respondWith(fetch(request));
});
Environment
System:
OS: macOS 15.6
CPU: (8) arm64 Apple M1
Memory: 143.16 MB / 16.00 GB
Binaries:
Node: 22.13.1 - ~/.nvm/versions/node/v22.13.1/bin/node
npm: 8.11.0 - ~/IdeaProjects/speed-kit/node_modules/.bin/npm
Languages:
Bash: 3.2.57 - /bin/bash
npmPackages:
playwright: 1.52.0 => 1.52.0
Might be related to this: https://bugzilla.mozilla.org/show_bug.cgi?id=1320796