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

Created on 19 Jul 2016  路  4Comments  路  Source: enzymejs/enzyme

Hi there,

We use an approach similar to the one described here 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 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, 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

docs help wanted

Most helpful comment

Not only are the Enzyme docs advocating a JSDOM anti-pattern, but they now seem to be using an old API as well. Since this config seems so fundamental to running Enzyme, an update would be much appreciated.

All 4 comments

I think this documentation on setting up JSDOM to use mount() on Node is still wrong. I'm getting the following error when I try running the setup script:

/Users/avrameisner/Development/admin_api/compiled/test/client/setupJSDOM.js:8
Object.keys(document.defaultView).forEach(function (property) {
       ^

TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at Object.<anonymous> (/Users/avrameisner/Development/admin_api/compiled/test/client/setupJSDOM.js:8:8)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at /Users/avrameisner/Development/admin_api/node_modules/mocha/bin/_mocha:345:3
    at Array.forEach (native)
    at Object.<anonymous> (/Users/avrameisner/Development/admin_api/node_modules/mocha/bin/_mocha:344:10)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:425:7)
    at startup (bootstrap_node.js:146:9)
    at bootstrap_node.js:540:3
error Command failed with exit code 1.

Instead of Object.keys, you should be using Object.getOwnPropertyDescriptors and applying all of those - which would catch all non-enumerables too.

Not only are the Enzyme docs advocating a JSDOM anti-pattern, but they now seem to be using an old API as well. Since this config seems so fundamental to running Enzyme, an update would be much appreciated.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blainekasten picture blainekasten  路  3Comments

abe903 picture abe903  路  3Comments

amcmillan01 picture amcmillan01  路  3Comments

andrewhl picture andrewhl  路  3Comments

heikkimu picture heikkimu  路  3Comments