Instructions for setting up jsdom (globals) contradict jsdom's docs
- Dominant language
- JavaScript
- Stars
- 19.8k
- Forks
- 2k
- PR merge metrics
- No merged PRs in 30d
Description
Hi there,
We use an approach [similar to the one described here](https://github.com/airbnb/enzyme/blob/master/docs/guides/jsdom.md) in order to expose `document` and `window` globals to the Node global object.
Unfortunately, we just had an issue where we upgraded `jsdom` to `9.4.0`, and several DOM globals stopped being exposed (`FormData`, `Event`). They changed these properties to be non-enumerable. We were able to fix it in our app by just referencing `window.FormData`, `window.Event`, etc.
jsdom's official approach about setting browser globals in a Node environment is "this is wrong and you shouldn't do it": https://github.com/tmpvar/jsdom/wiki/Don't-stuff-jsdom-globals-onto-the-Node-global
They suggest a couple of workarounds. Using `window` explicitly is the approach we took. Another approach is wrapping your entire test bundle and executing it inside a JSDom function. _(aside: I'm still not sure how to stitch this together with webpack, babel, etc. [Their example](https://github.com/tmpvar/jsdom/wiki/Don't-stuff-jsdom-globals-onto-the-Node-global#an-example-in-a-test-runner) mixes `require` and filesystem reads, which doesn't feel right vs. `import` statements.)_
jsdom's reasoning for avoiding exposing these globals is:
> "[it] causes all these properties to be shared not only across all your tests, but across your entire Node.js process."
But to make things interesting, [there's also this bit from Enzyme's docs](https://github.com/airbnb/enzyme/blob/master/docs/guides/jsdom.md#describewithdom-api-and-clearing-the-document-after-every-test), which says React doesn't play nicely when you start switching out `document` in between tests:
> In previous versions of enzyme, there was a public describeWithDOM API which loaded in a new JSDOM document into the global namespace before every test, ensuring that tests were deterministic and did not have side-effects.
>
> This approach is no longer recommended. React's source code makes several assumptions about the environment it is running in, and one of them is that the global.document that is found at "require time" is going to be the one and only document it ever needs to worry about. As a result, this type of "reloading" ends up causing more pain than it prevents.
We're kind of stuck between a rock and a hard place here, with `enzyme` saying "don't do this" and `jsdom` saying "don't do that".
Any feedback from other enzyme users in the same position, or clarity from the maintainers, would be much appreciated.
References:
https://github.com/tmpvar/jsdom/issues/1551
https://github.com/rstacruz/jsdom-global/issues/6
https://github.com/rstacruz/jsdom-global/pull/7#issuecomment-230321646
https://github.com/tmpvar/jsdom/issues/1549#issue-163608781
Contributor guide
Research direction
Start with docs/guides/jsdom.md and compare its global setup instructions with jsdom's linked guidance and the reported jsdom 9.4.0 behavior. Review the referenced Enzyme and jsdom discussions before proposing a direction; done means the setup guidance is consistent, explains the supported approach, and covers the affected globals.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- documentation, testing-qa
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100