Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File watching does not execute actual code changes when site under test utilizes Service Workers. #702

Open
brian-mann opened this issue Oct 3, 2017 · 35 comments
Labels
existing workaround type: enhancement Requested enhancement of existing feature type: unexpected behavior User expected result, but got another

Comments

@brian-mann
Copy link
Member

brian-mann commented Oct 3, 2017

Related to #686.

It's possible the application under test ends up using Server Workers to inadvertently cache the files Cypress uses to serve spec files. This prevents changes to the spec files from ever being updated.

Prior to the beginning of all tests we should clear the Service Worker cache and then add a new cy command and add this to lifecycle rules cy.clearServiceWorkerCache().

We could make this command print out all the cache keys it cleared.

Workaround:

before(function () {
  // run this once before all code
  return window.caches.keys().then(function(cacheNames) {
    return Promise.all(
      cacheNames.map(function(cacheName) {
        return window.caches.delete(cacheName);
      })
    );
  })
})
@brian-mann brian-mann added the type: enhancement Requested enhancement of existing feature label Oct 3, 2017
@brian-mann brian-mann self-assigned this Oct 3, 2017
@brian-mann
Copy link
Member Author

Additionally seeing problems with ServiceWorkers caching the /__ root client path which prevents Cypress from being served entirely.

@brian-mann
Copy link
Member Author

Another potential lifecycle command we could add at the beginning of each test, and then subsequently at the end of all tests is something like: cy.clearServiceWorkerRegistrations()

The implementation for that might look something like:

window.navigator.serviceWorker.getRegistrations()
.then(function(registrations) {
  return Promise.map(registrations, function(registration) {
    return registration.unregister()
  })
})

@brian-mann
Copy link
Member Author

We could even indefinitely prevent service workers from ever being registered by doing:

cy.visit("https://testy.gift/", {
  onBeforeLoad: function(win) {
    const promise = new Promise(function(resolve) {});
    return win.navigator.serviceWorker.register = function() {
      return promise;
    }
  }
})

@brian-mann
Copy link
Member Author

We need to make a decision here. Currently ServiceWorkers end up generating very confusing behavior in Cypress which is hard for new (and even old) users to debug.

Proposal

  1. Prevent ServiceWorkers from ever being generated by default.
  2. Add two new commands above to enable clearing cache + registrations before each test + after all the tests finish
  3. Add a new config property: enableServiceWorkers: false by default (?)

When we enable lifecycle events this could potentially conflict...

@HenrikJoreteg
Copy link

so as a workaround as long as it doesn't cache the stuff at /__ we're good right? I could tweak the SW to reflect that.

@brian-mann
Copy link
Member Author

Yes, you could. That is the only request of Cypress' that you are caching accidentally.

@e-monkey
Copy link

e-monkey commented Dec 21, 2017

The workaround does not work for me:

Error: Failed to execute 'keys' on 'CacheStorage': Only secure origins are allowed (see: https://goo.gl/Y0ZkNV).

Because this error occurred during a 'before all' hook we are skipping all of the remaining tests.
    at Context.
  • Operating System: Windows 10 Pro, Fall Creators Update, 1709, Build 16299.125
  • Cypress Version: 1.4.0
  • Browser Version: Chrome 63 / Electron 53

The test files only update, when i close cypress or when i manually clear the cache through the Chrome settings.

Did not found a way to solve it or another workaround.

@mxstbr
Copy link

mxstbr commented Jun 26, 2018

Prevent ServiceWorkers from ever being generated by default.

I want to be able to e2e test my serviceworker's behavior, so I'd hate to see this happen. I'd love to see an API to clear the caches before each test run though!

@jennifer-shehane
Copy link
Member

@mxstbr What behavior of the service worker are you testing? We'd like to hear your more about your use case so we can properly address our side.

@mxstbr
Copy link

mxstbr commented Jul 12, 2018

Caching of frontend assets and potentially web push notifications?

@cdaringe
Copy link

cdaringe commented Aug 9, 2018

another hack i used was to have my web-app detect cypress. my CSP is already no-frame, so, in dev mode w/ the csp off, i can sniff for if (window !== window.parent) { ... } and just turn off service worker registration. window.Cypress is also a thing...

@rcrichton
Copy link

rcrichton commented Oct 12, 2018

I solved the issues I was having by updating my navigation fallback config in sw-precache. This is what I added:

navigateFallbackWhitelist: [/^\/[^_]+$/], // fallback for anything that doesn't start with /__ which is used by cypress

@mackelito
Copy link

Still no workaround to clear service worker?

@abigailcauchi
Copy link

abigailcauchi commented Nov 5, 2018

@mackelito I've managed to unregister all service workers before each test in one of my specs like this:

beforeEach(() => {
  if (window.navigator && navigator.serviceWorker) {
    navigator.serviceWorker.getRegistrations()
    .then((registrations) => {
      registrations.forEach((registration) => {
        registration.unregister()
      })
    })
  }
})

@brandynprasad
Copy link

@abigailcauchi This snippet helped me, thank you.

The application I'm working heavily relies on service workers. I noticed my cypress spec files would pass when run independently, but when I chose to run all specs the browser launched by cypress would fail to load some pages (resulting in failed assertions!).

After unregistering service workers in my before hooks, my specs are running much faster and passing consistently. Thank you again.

@cypress-bot cypress-bot bot added stage: ready for work The issue is reproducible and in scope and removed stage: proposal 💡 No work has been done of this issue labels Jun 4, 2019
@jennifer-shehane jennifer-shehane added stage: proposal 💡 No work has been done of this issue type: unexpected behavior User expected result, but got another existing workaround labels Jun 4, 2019
@jennifer-shehane jennifer-shehane removed the stage: proposal 💡 No work has been done of this issue label Jun 4, 2019
@vrknetha
Copy link

vrknetha commented Jul 8, 2020

I have disabled the service workers when 'window.Cypress' but still it is not working. Anything on this yet.

@mikerich
Copy link

I came across this issue yesterday. I found I could get around it in Chrome by going to Dev Tools->Application->Service Workers and checking the 'Bypass for network' checkbox. Not ideal but it got me moving again so I could see changes I made to my test. Changing "watchForFileChanges" did not affect this issue.

Not an issue when running from the command line. Only from the test runner.

App is React/Gatsby/PWA using gatsby-plugin-offline (a workbox wrapper)

@davidjeddy
Copy link

Any plans regarding this? We are working on a PWA app and working around this is proving to be cumbersome as of the moment, we always have to manually clear Application Cache for our changes to take effect.

Same here. Just spent the better part of two days figuring out the root cause of our Cypress/Lighthouse tests failing. (using https://github.com/mfrachet/cypress-audit). We have to manually checkbox Bypass for network for the evaluations to work as expected. It appears the setting stays in the chrome instance controlled by Cypress, independent of the a users chrome session.

@nicholaschiang
Copy link

I'm using a service worker to handle authentication by intercepting fetch requests and appending a JWT in their Authentication headers (as @nkbt described). Without that service worker, the app doesn't know if it's logged in or not.

Currently during development, I always open up developer tools and check the "Allow service workers over HTTP" box like so:
image

With Cypress, I can do the same thing when running cypress open and actually viewing the browser, but I don't know how to change the browser settings for Electron or headless Chrome when Cypress runs on my CI server.

Any suggestions for how to ensure that service workers are allowed over HTTP in the headless browser that cypress run uses?

@nicholaschiang
Copy link

Nevermind, I seem to have fixed my own issue by serving to localhost instead of 0.0.0.0 (Chrome seems to only be able to allow service workers over HTTP when they come from localhost).

@RaviH
Copy link

RaviH commented Jan 9, 2021

Hi, any update on this?

@nicholaschiang
Copy link

Related to #15670.

@csvan
Copy link

csvan commented Dec 12, 2021

Related: #16192

@kylemh
Copy link

kylemh commented Mar 24, 2022

There doesn't seem to be a workaround for this for me...

Cypress.on('window:before:load', win => {
  if (window.navigator && 'serviceWorker' in window.navigator) {
    window.navigator.serviceWorker.getRegistrations().then(registrations => {
      registrations.forEach(r => r.unregister());
    });
  }

  // @ts-ignore
  delete win.navigator.__proto__.ServiceWorker;
  // @ts-ignore
  delete win.navigator.serviceWorker;
});

but the service worker still registers

@cypress-bot cypress-bot bot added stage: backlog and removed stage: ready for work The issue is reproducible and in scope labels Apr 29, 2022
@KseniaCHG
Copy link

Hello, I am a little junior and I've been struggling with this a lot, the solution is simple - clear cache in a browser that Cypress is using. Version Cypress 12.7.0 hope that helps :)

aneesa-saleh added a commit to aneesa-saleh/restaurant-reviews-qa that referenced this issue Sep 23, 2023
Prevent unexpected behaviour with service workers. See: cypress-io/cypress#702
@ohlori
Copy link

ohlori commented Nov 13, 2023

I have encountered this just now. Cypress version 13.5.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
existing workaround type: enhancement Requested enhancement of existing feature type: unexpected behavior User expected result, but got another
Projects
None yet
Development

No branches or pull requests