playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Bug]: navigator.serviceWorker.controller returns null in Firefox

Open KevT2017 opened this issue 5 months ago • 1 comments

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.

  1. Open https://savory-castle-64.app.baqend.com/playwright-issue/ with playwright Firefox (v137)
  2. Open the inspector and paste (await navigator.serviceWorker.getRegistrations())[0] into the console to see that a service worker is active
  3. Click on the "Navigate to blacklisted page" button
  4. Enter navigator.serviceWorker.controller in the console and see that it returns null
  5. Revalidate that the service worker is still active with (await navigator.serviceWorker.getRegistrations())[0]
  6. Navigate back to landing page which is served by the service worker
  7. Enter navigator.serviceWorker.controller in 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

KevT2017 avatar Aug 13 '25 14:08 KevT2017

Might be related to this: https://bugzilla.mozilla.org/show_bug.cgi?id=1320796

emil-todirascu avatar Aug 19 '25 13:08 emil-todirascu