mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.91k stars 517 forks source link

MSW leaves cypress component test runner in a loop #744

Open yannbf opened 3 years ago

yannbf commented 3 years ago

Describe the bug

Cypress 7 recently released an interesting feature called component test runner. It allows to mount a component and run it in isolation, rather than having to run the entire application. I was trying to use it with MSW (which would be awesome!), but for some reason, starting the service worker makes the test behave weirdly, becoming flaky, sometimes looping and causing trouble.

Environment

To Reproduce

Steps to reproduce the behavior:

before, check this repro: https://github.com/yannbf/msw-cypress-component-issue

  1. yarn
  2. yarn cy
  3. Select Login.test.jsx
  4. Check the comments in https://github.com/yannbf/msw-cypress-component-issue/blob/main/src/components/Login.test.jsx#L9. As soon as you remove the start of the service worker, the tests flow naturally. When you add them, there's something weird that results in cypress runner looping.

Expected behavior

MSW should not impact cypress

Screenshots

2021-05-22 at 23 00 45 - Amber Beaver

surfer19 commented 1 year ago

Ref: NextJS issues

I found when using basePath in nextConfig (e.g. /foo), you need to set serviceWorker.options.scope to /foo otherwise the scope will be set to /foo/ which wont match your root page.

    worker.start({
      serviceWorker: {
        options: { scope: '/foo' },
        url: '/foo/mockServiceWorker.js',
      },
    });

See: validateWorkerScope.ts. '/foo'.startsWith('/foo/') will always be false.

@Jaesin yes, this might fix the issue with referencing worker file but it doesn't solve infinite rerender isssue :(

lydemann commented 1 year ago

Has anybody had luck with modifying the Angular webpack config to make this work or other kinds of workarounds?

lydemann commented 12 months ago

I tried with the esbuild builder in Angular 16 and it still went looping when I was fetching the MSW service worker.

reintroducing commented 6 months ago

@lmiller1990 I ran up against this over the weekend in a React/Vite project as well. I posted a very easily reproducible example in this issue (https://github.com/mswjs/msw/issues/1560#issuecomment-2096591978) which is really barebones but demonstrates the issue clearly. I don't think this is only an Angular issue, it seems to be an issue in React as well.

lmiller1990 commented 6 months ago

@reintroducing I suspect you are probably correct. I'm sorry I am unable to help debug this one -- I am shifting my focus nowadays, and am not working on Cypress or in the JS ecosystem right now.

reintroducing commented 6 months ago

@lmiller1990 thats unfortunate, I’ve corresponded with you in a few issues over the years and always appreciated your approach and positive attitude. Thank you for that over the years. Is there someone else I can reach out to about this that can help?

lmiller1990 commented 6 months ago

I'm not sure, this is a very specific issue to Cypress and MSW from the looks of things. Someone with a deep understanding of how to debug Cypress' network layer is probably the best bet, but I think it'll be difficult to get someone to look at this, considering Cypress already has and will likely push you to using their own cy.intercept() feature.

Good luck!

lydemann commented 6 months ago

Would be nice if there atleast were a nice way to map the MSW configuration to cy.intercept().

I see there is this project https://github.com/deshiknaves/cypress-msw-interceptor#readme

But that seems to work the other way around: use cy.intercept() syntax to map to MSW configuration.

surfer19 commented 6 months ago

One of the best thing about msw, it simplifies way how to define and share mocks with single config over different type of tests. I could define one mock for unit + integration tests and it works like a charm. Why the hack cypress won't allow it to close E2E loop? Why I need to do extra configuration just because of cypress?? Annoying