-
-
Notifications
You must be signed in to change notification settings - Fork 535
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
Worker registered on different ports in Testcafe #335
Comments
Hi - random person here. Just a few notes on this - I was trying to see if any of the changes I helped introduced into the 0.20.5 release impacted this. I had to remove The current issue with this is that it was actually broken(maybe?) pre 0.20.5? The problem is in Script URL: https://localhost:1337/mockServiceWorker.js I'm working on seeing if I can solve it quickly, but that's the starting info. |
@msutkowski (aka Random person). actually that's the correct port. testcafe runs tests through a proxy. you'll notice it uses the same port w/ no problems on 0.20.4. that's what the file located at testcafe/registerServiceWorker.js is doing, it ensures that MSW is properly registered as a service worker w/ the correct URL w/out the proxy stuff that testcafe does. |
@benmonro Understood! What I was trying to say is that the absoluteWorkerUrl and worker.scriptURL have to match with 0.20.5. Previously, this wasn't actually enforced and would've called worker.start() on whatever serviceWorker was registered whether it was msw or not, and could've been unintended behavior for sure (ex: if you registered two workers at once for whatever reason, it never would've worked assuming msw was registered second). Here is a temporary solution: worker.start({
serviceWorker: {
url: "https://localhost:1337/mockServiceWorker.js"
}
}) in your if (!url.includes("mockServiceWorker")) {
return getProxyUrl.apply(this, arguments);
} I'd have that I'm going to spend a few more minutes on seeing if I can figure out what this issue is, but it has nothing to do with the proxy/msw from what I can tell. I'm in the reactiflux discord under the same user name if you want to look at this together - would be happy to jump on a liveshare or whatnot with a fellow san diegan 🎉 . If not, I'll update what I find here (if anything). |
would love to what's the url for the discord? |
https://discord.gg/reactiflux - i'm normally active in the #redux channel, but i'm the only msutkowski on there. |
damn ok i'm a dummy how do i find you on here lol, i'm benmonro |
Just wanted to leave a note where we left off here: the issue is basically getting the proxy, service worker registration, and test cafe to all play nicely. The reason this worked previously is that the check on worker.scriptURL and absoluteWorkerUrl wasn't 'strict'. The reason it's 'breaking' now is that these are different - one is registed on the proxy port, while the other is on the port react runs on (3000 vs 1337). Current options: hack around test cafe some more to see if there is a way to get it's config options to not chew things up like in the screenshot above, or by introducing an additional configuration parameter to bail out of the strict scriptURL check. Going to tinker more tomorrow and see if we can come up with a good idea for this unless someone might have other thoughts. Things we discussed: 1) adding a |
@msutkowski thanks again for following up and spending time. I think a 3rd option we discussed was to treat the default as non strict mode too? To be clear I'm totally fine with all 3 options though I'd probably lean towards option 1. |
Thanks for the insights on this, @msutkowski! One thing I fail to understand is why it resolves absolute worker URL to port If a worker script URL is different, I would suggest to specify an explicit worker registration URL in the options to worker.start({
serviceWorker: {
url: "https://localhost:1337/mockServiceWorker.js"
}
}) This is not a workaround, you are specifying where to register and expect the worker. If this approach solves the issue, I'd choose it. |
It doesn't solve it though because then it'll won't resolve when the page goes to download the script. It actually creates a different problem. |
@kettanaito It's a confusing situation and I think @benmonro can definitely explain it better than me but I'll try to shed some light: basically, setting the |
Yeah, so in a nutshell, testcafe controls everything through a proxy server it sets up to run your tests called 'hammerhead.' Hammerhead allows testcafe to control the page during a test in the browser directly. But yeah a side effect of this is that they have to change all urls to go through their proxy to avoid CORS issues and other such problems. So that's why we discussed option 2 above, a proxyUrl config option as a way to identify if msw is being served through a proxy. The problem is if we just set serviceWorker.url to the testcafe url (testcafe has an api So to summarize how I got testcafe & msw to play nice together:
This allows MSW to be registered at the correct URL to intercept fetches to So if we set serviceWorker.url to the URL in 2) then hammerhead will actually try to fetch from that (on the backend) and it will be a circular reference that won't be resolved, so MSW never get's injected into the page. That's why either a hopefully that makes sense. :) |
Thank you for clarifying on this, @msutkowski, @benmonro. I see now. Since previously we were less strict in resolving the worker registration, we mistakingly disregarded a worker URL, which allowed MSW to pick up a worker registration at a different URL than the current location. This is what made it work in the previous versions, but fails now with the strict worker registration check. That being said, I'd treat the current registration retrieval logic as expected behavior: msw/src/setupWorker/start/utils/getWorkerByRegistration.ts Lines 5 to 20 in a126de2
The fact that we used to resolve with a registration that was not necessarily the one you provisioned in your app was a bug, and thus a patch version release. I would be careful in introducing new options to cover this, for them not to be workarounds for the sake of unexpected behavior support. @benmonro is it possible to configure Testcafe to register the worker at I'm sorry if I can't be of more help in this question, since the entire proxy setup of Testcafe introduces much bigger problems that the ones it tries to solve. I can yet again recommend to dive into their setup and find a way to register workers and handle root-level requests as a regular app does. |
@kettanaito would you be opposed to option 1 or 2 above? |
@benmonro Can you try something out for me? I found a way to 'trick' hammerhead... but first, please don't laugh at how ridiculous this is 😅 _app.js
const absoluteWorkerUrlParts = ['https',':','//','localhost:1337','/','mockServiceWorker.js']
worker.start({
serviceWorker: {
url: absoluteWorkerUrlParts.join('')
}
}).then(() => {
console.log('msw is ready!', navigator.serviceWorker.getRegistration().then(res => console.log('Got reservations:', res)))
setMswReady(true)
}); registerServiceWorker.js
const getProxyUrl = window["%hammerhead%"].utils.url.getProxyUrl;
window["%hammerhead%"].utils.url.getProxyUrl = function () {
// "localhost:1337/<sha>/http://localhost:3000"
// fetch(/todos)
const url = arguments[0];
if (!url.includes("/mockServiceWorker")) {
return getProxyUrl.apply(this, arguments);
}
return url;
}; I observed that hammerhead is basically just regex-ing strings or URL instances and rewriting the strings in place (maybe!), not executing functions, and then rewriting the resulting string... so it seems like building the URL will sidestep that rewriting stuff it does. I could be totally offbase here, but this is working for me on both of my machines. I ran this with the --debug-mode flag and without - both were successful. Even though this should work, it still seems brittle? Let me know what you think. |
Lol sure will try later tonight. Still feels like a proxy URL or strict mode option would be a better option but I will try this when I get home |
I looked at this a bit more. Although we can make it work like this, I think a discussion about a Code changes would look like: const getWorkerByRegistration = (registration, absoluteWorkerUrl, strict = true) => {
const allStates = [
registration.active,
registration.installing,
registration.waiting,
];
const existingStates = allStates.filter(Boolean);
const mockWorker = existingStates.find((worker) => {
if (strict) {
return worker.scriptURL === absoluteWorkerUrl;
} else {
const workerFileName = absoluteWorkerUrl.split('/').pop();
return worker.scriptURL.includes(workerFileName)
}
});
return mockWorker || null;
}; And we'd just have to add a config option to I did test the above code with @benmonro 's project, and it works fine. Prevents the need to specify the Happy to open a PR and add docs if you're interested. |
here's maybe a 4th option. if we pass in an absolute URL in the config options, use the |
yeah i'm totally fine w/ the strict option as well. |
I think your 4th option is achieving basically the same thing as the |
all good, i just throw ideas out, i agree, let's go w/ strict mode! works for me |
oh btw @msutkowski that array.join hack totally works. LOVE IT (but yeah no) hahahaha. funny story, today at work my coworker got it to work using unicode characters haha. but then we tried it in prod mode and it failed, we're guessing because webpack optimizes that out. |
I threw up a quick draft of this idea with more understandable naming to help the discussion. I'm still not 100% sold on the idea that |
Yeah in my view, |
Yea, I agree with you. I've thrown up a matching PR into the docs site as well for this flag assuming it moves forward. If anyone has any additional feedback, let me know and I'd be happy to address it. |
@kettanaito any thoughts on @msutkowski 's approach and PR? Would really like to see it go in |
@benmonro hey. The current state of the PR is great, I've asked to verify the error message, which I'd be thankful for you to do as well, if you have a minute. If the error message is okay, and the CI is green, it's approved. |
I'm working on verifying this now - I have to update the example repo to be compatible with the new types before it'll run. Will update shortly. |
Sgtm. I trust Matt. |
Describe the bug
i am now using msw in testcafe w/ no problems as of 0.20.4 (was thinking I should add a recipe for this to your docs, if you want let me know and I'll open a PR).
However, when i upgrade to 0.20.5, it appears that mocking is not working.
Environment
msw: 0.20.4 & 5
nodejs: 12
yarn: latest
To Reproduce
Steps to reproduce the behavior:
yarn
yarn testcafe
note, it works w/ this version as it's using 0.20.4
yarn add -D msw@0.20.5
Expected behavior
A clear and concise description of what you expected to happen.
mocks work. :)
Screenshots
If applicable, add screenshots to help explain your problem.
The text was updated successfully, but these errors were encountered: