mswjs / msw

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

Calling a custom protocol breaks request interception #1047

Closed slowselfip closed 2 years ago

slowselfip commented 2 years ago

Describe the bug

If a link to a custom protocol (i.e. mailto:) is triggered on a page, then the mock service worker stops intercepting requests.

Environment

To Reproduce

Steps to reproduce the behavior:

  1. Go to: https://codesandbox.io/s/quirky-browser-yjijd
  2. Click on the Start Polling button
  3. Notice that the responses gets intercepted by the mock service worker
  4. Click on anchor tag with the custom protocol mailto: href
  5. Notice that the interceptions stops as the polling continues

Expected behavior

That the mock service worker continues to intercept the calls

kettanaito commented 2 years ago

Hey, @slowselfip.

I believe the current behavior is correct. Link references are not captured by Service Worker because they direct to new resources without fetching them. When I click on the mailto: link in your sandbox (btw, thank you for preparing that), I'm directed to my mailing client, losing the context of the sandbox. That's the correct behavior.

Service Workers can only intercept requests issued on a page. Hyperlinks, image/video/iframe sources, and other references that do not trigger requests in a browser are not captured. You can test it yourself by adding a breakpoint to the fetch event handler in the mockServiceWorker.js file, reloading the sandbox, and clicking on the mailto: link. Notice how the breakpoint doesn't get called because there's no request to trigger it.

slowselfip commented 2 years ago

I think you missunderstood the purpose of the report. It’s not to intercept the mailto, it’s that the original intercept that is handling the api-call stops working even though the page is still polling that endpoint.

kettanaito commented 2 years ago

Then I'm not able to reproduce that behavior. Can it be because I've got a mailing client configured? As I said previously, clicking on the mailto: link redirects me to another page, unloading the sandbox (so, expectedly, polling stops as I'm no longer on that page).

Are you able to click on the anchor element without triggering the navigation?

kettanaito commented 2 years ago

I've just tested this sandbox in another browser without any mailing clients configured. Clicking on the anchor opens my mailing client in another browser, preserving the sandbox. The polling keeps going after this, as the page's context wasn't destroyed.

slowselfip commented 2 years ago

Yes that is basically how all custom protocols that are hooked up to apps on my system, macos big sierra, works. It does not leave the page, the app is opened and the page continues in the background. Maybe it’s possible for me to upload a video demoing this later.

kettanaito commented 2 years ago

Perhaps one thing I may recommend that will narrow the debugging scope: could you clone and run your sandbox locally? Sometimes there are issues when running MSW worker on platforms that have their own workers (like Codesandbox does). To ensure that there's no influence on the way our worker functions, running it in isolation locally would be beneficial.

slowselfip commented 2 years ago

The reason I created this issue report with the example code sandbox was that I noticed this behaviour in one of our application at work. I was testing it locally after bumping msw to latest version.

Background info: We have a custom protocol for an app that handles digital signing in Sweden and it’s very much standard here. When we’re starting a signing process, the user may open their signing client (usually an app on their mobile phone) directly from the page. This is not a problem in prod as we’re not mocking the endpoints there. But in integration tests we’re relying on msw. We can of course disable the custom protocol when running msw but this whole thing caught me of guard and I spent some time investigate it. So I just wanted to raise the issue to inform about it.

Thanks for taking the time to investigate it. We have a WR so that’ll do.

Going to check on that sponsor link now. ✌️

kettanaito commented 2 years ago

That's a valid concern. Interacting with custom protocols must not interfere with the request interception, given the page's context is preserved. I don't think the protocol interaction is the issue, though. Resources that are not requested will not be handled by the worker, so clicking on mailto: or arbitrary-protocol: links doesn't trigger the "fetch" even in the worker to cause any kind of trouble. Perhaps try looking into the surrounding parts of the mocking setup and your app logic that may cause the mocks to break? Maybe there are some exceptions going on that could stir the investigation into the right direction.

Going to check on that sponsor link now. ✌️

Huge thanks for sponsoring MSW! 🎉

mackelito commented 1 year ago

@slowselfip did you ever solve the problem? I guess you had the same problem as I described in https://github.com/mswjs/msw/issues/1697

slowselfip commented 1 year ago

I didn’t solve it no. I just added an ”if msw is active don’t do the window.location.href assignment to trigger the custom protocol”-condition. It was more of a side effect really and not necessary for the tests to run. But it did catch me off guard and it took some time to find out what was happening. That’s why I thought to mention it here. Hope you’ll find a way around it as well.