Msw: Hard reload fails to use the service worker if there's another client connected

Created on 27 Apr 2020  路  11Comments  路  Source: mswjs/msw

Remember the hard reload issue? #98 well, it looks like I get that exact same issue with the latest msw (0.14.1) if I have two browser tabs open on the site.

bug

All 11 comments

Hey. I'm sorry you're experiencing this issue again... I will create the test scenario you've mentioned, and see what's wrong.

Thanks! I'm really impressed by the high-quality test setup you have in this project. Very impressive 馃憤

Thank you! 馃槉Means a lot to me. I've been providing the test-should-resemble-usage pattern into my projects for some time now, and it never let me down. With MSW it pushed the setup a step further, with each test scenario being a 1-1 actual code a user would write + WDS and Puppeteer behind the scenes.

Following up on our discussion in #98, your suggestion with getting all registrations is a good one. Basically, navigator.serviceWorker.getRegistrations() returns the list of registered Service Workers for the current client. I'm trying to prune that list, if there is no navigator.serviceWorker.controller, which indicates a hard reload:

if (!navigator.serviceWorker.controller) {
  const [, registrations] = await until(() => {
    return navigator.serviceWorker.getRegistrations()
  })

  await Promise.all(
    registrations.map((registration) => registration.unregister()),
  )
}

Although I can successfully unregister all active registrations upon hard reload, and the proceed with registering a new one, it doesn't solve the hard reload issue when there are multiple clients opened.

What _does_ seem to resolve the issue at the first sight is doing a page reload when there is no Service Worker controller:

if (!navigator.serviceWorker.controller) {
  location.reload()
}

Technically this means a regular reload after a forced reload, which results into Service Worker controlling the client as usual. Although it reads like two reloads, I cannot notice any difference in a browser's behavior when this logic is enabled, it looks like a single reload to the user.

I've published a location.reload() fix in 0.15.1. Could you please update and let me know how it behaves? Thanks.

Hmmm... That isn't working. From my debugging it looks like mockRegistrations is []

image

And I do have two instances of the app open:

image

Thanks for reporting back. I think I'll switch to Bookshelf app and try to debug there. Will keep this thread updated with what I find.

I've found out the logic that resolved an absolute URL of the registered worker had an invalid regular expression that resulted into :// (protocol ending) to be transformed.

Fixed here (https://github.com/open-draft/msw/commit/9176d504b187d402a87656c0e105a89e16baf87b#diff-f21eb60764a0558fa61b186907da249c), released in 0.15.2. I've tried this patch on Bookshelf app, and can confirm that hard reload does not affect the mocking for both single page and multiple pages open.

Issued a pull request: https://github.com/kentcdodds/bookshelf/pull/45

Awesome! Worked great for me. Thank you very much :)

Glad to hear that!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hauptrolle picture hauptrolle  路  4Comments

otaciliolacerda picture otaciliolacerda  路  3Comments

dashed picture dashed  路  4Comments

slowselfip picture slowselfip  路  3Comments

danielstreit picture danielstreit  路  3Comments