Open jmverges opened 2 years ago
Hey, @jmverges. Thanks for reporting this.
We have a listener on the beforeunload
event that signals the worker that the current client is being closed:
I think despite you preventing the unload in your listener, the one from the library is still getting called.
You may want to consider using event.stopPropagation()
in your listener:
window.addEventListener("beforeunload", function(e) {
const confirmationMessage = "Msw will not work from this point";
e.returnValue = confirmationMessage;
+ // Prevent other listeners on "beforeunload" from executing.
+ e.stopPropagation();
return confirmationMessage;
});
Since you're likely adding your listener after MSW has done so, yours will execute first, so you're able to control whether the beforeunload
event propagates down the listeners chain.
Please, give this a try and let me know.
Thanks for your quick response @kettanaito As soon as I read it I though it would work, however after I gave it a try, the 'beforeunload' from MSW is executed before mine. Not sure if I can handle the order of the events from my code. I'm registering msw as a plugin in nuxt3 I though this would be executed before my page but, maybe is not?
I'm having the same problem.
The order beforeunloads
are executed is the order in which they are registered, so msw's beforeunload is executed first before e.stopImmediatePropagation or e.stopPropagation is executed in the application.
Is there any way to do this? Like restarting the worker when beforeunloading?
I tried to start the worker again beforeunload, but the following error occurred.
I'm experiencing the same issue with the author. Has anyone solved this issue?
Same here :P - as described evt.preventDefault() is not working, because it is to late. Any updates?
I think i figured a way to do it. I have a React app and it is a little unconventional for it.
Add an IIFE outside a component, so it mounts immediately on js load. As it loads only once, we don't even need to remove the event listener.
(function () {
const handleOnBeforeUnload = (e: BeforeUnloadEvent) => {
const getIsDirty = () => Boolean(sessionStorage.getItem("isDirty"));
if (!getIsDirty()) return;
e.stopImmediatePropagation();
e.preventDefault();
};
window.addEventListener("beforeunload", handleOnBeforeUnload, {
capture: true,
});
})();
Inside a component you can update the session storage in order be able to show the page reload confirmation
useEffect(() => {
sessionStorage.setItem("isDirty", isDirty ? "1" : "");
return () => sessionStorage.removeItem("isDirty");
}, [isDirty]);
Doing it this way, allows the event listener to be attached before the msw one, so doing e.stopImmediatePropagation()
means we can trigger our code before the msw one.
Describe the bug
I have some code in my page that hooks in beforeunload and then the user can cancel and stay in the page or leave the page. If the user decides to stay in the page msw gets broken.
Environment
msw: 0.35.0
nodejs: v17.4.0
npm: 8.3.1
nuxt 3
vite
Firefox 98.0b
To Reproduce
Steps to reproduce the behavior:
Add some code like:
Cancel and remain in the page Trigger some mocked mutation
Expected behavior
Mutation should be triggered
Screenshots
I can go to .vite generated code and delete those lines and then the mutation is triggered.