web-locks icon indicating copy to clipboard operation
web-locks copied to clipboard

Issues using in jsdom environment

Open bienzaaron opened this issue 1 year ago • 1 comments

Hey there, I'm running into the following error occasionally during my CI runs when running in a jsdom/happy-dom environment.

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Uncaught Exception ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
ReferenceError: window is not defined
 ❯ e._setLocalTime node_modules/navigator.locks/dist/index.cjs.js:1:2930

 ❯ Timeout._onTimeout node_modules/navigator.locks/dist/index.cjs.js:1:2665
 ❯ listOnTimeout node:internal/timers:573:17
 ❯ processTimers node:internal/timers:514:7

This error originated in "index3.spec.js" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:
- cancel timeouts using clearTimeout and clearInterval
- wait for promises to resolve using the await keyword

I believe this is due to the way the heartbeat file works (https://github.com/aermin/web-locks/blob/main/src/heartBeat.ts#L26 and https://github.com/aermin/web-locks/blob/main/src/polyfill.ts#L96, I've gotten stack traces that point to both of these), where it sets up intervals that access window.

I think the root of the issue is there's a race condition between when the jsdom environment and window get cleaned up, and when these intervals get cleaned up.

There are a couple ways I think this can be solved:

  1. jsdom (or my tests) should ensure unload handlers are called when the jsdom environment is cleaned up - they currently don't https://github.com/jsdom/jsdom/issues/1584. This is also the same in happy-dom, another dom implementation used often in testing frameworks
    • if I explicitly intercept calls to addEventListener for unload event listeners and call them, the test becomes much more stable
  2. expose an entrypoint in this module which explicitly allows setting up and tearing down the polyfill, and all associated timers/handles.

bienzaaron avatar Apr 15 '24 20:04 bienzaaron

If you are amenable to 2, I would be happy to submit a PR.

bienzaaron avatar Apr 15 '24 20:04 bienzaaron