enzymejs / enzymejs/enzyme

Instructions for setting up jsdom (globals) contradict jsdom's docs

Open
#507 4 comments 8 reactions 0 assignees View on GitHub
docs help wanted
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.