I have a high order component that uses some Components from Blueprint/core and I've been trying to test it using Mocha and Enzyme. But, for some reason, when I try running my tests, they break and say I don't have DocumentFragment from dom4.max.js.
Package version: 1.4.0
OS versions: Ubuntu 16.04
/node_modules/dom4/build/dom4.max.js:141
-> DocumentFragmentPrototype = window.DocumentFragment && DocumentFragment.prototype
DocumentFragment is not defined
@lucantini you must include typings for dom4, it's a core dependency of the library.
@blueprintjs/core v1.4.0 actually includes an NPM dependency on @types/dom4: https://github.com/palantir/blueprint/blob/master/packages/core/package.json#L9
@giladgray I'm using the 1.4.0 version of @blueprint/core and this problem still occurs.
the fix is to include @types/dom4 in your TypeScript compilation context, whatever that means for your project.
@types/dom4 installed?sorry hold up, if this is a _runtime_ error then you need to import "dom4" directly in your application so the polyfills will be included.
final clarification:
if you import { X } from "@blueprintjs/core" (root import) then dom4 will be included automatically. if instead you import { X } from "@blueprintjs/core/dist/components/..." (relative import) then dom4 is _not_ included automatically and __you must do so yourself__.
Classic NPM.
We do not use TypeScript in our project :(
We are importing from root, as you said above:
import { Spinner } from '@blueprint/core'
In that case we don't need to import dom4 directly, right? It comes as a devDependency from blueprint itself - I tried importing dom4 anyway and it didn't worked either.
It's worth mentioning that this problem only occurs when we run our tests. The component works perfectly otherwise.
are you doing something special in your test setup that might exclude dom4? or perhaps you're running code before dom4 has loaded? or not running in a real browser environment? which file produces the error above?
this issue is beginning to seem very specific to your project setup and there's little I can do beyond telling you that this is a dom4 issue.
global.document = jsdom('');
global.window = document.defaultView;
Object.keys(document.defaultView).forEach((property) => {
if (typeof global[property] === 'undefined') {
global[property] = document.defaultView[property];
}
});
This is our test configuration with jsdom. Do you think this can be the problem by any means?
ah yes JSDom... this is why we don't use it internally yet. i tried setting up jsdom + dom4 and had some serious trouble because dom4 expects a "real browser" which jsdom just barely isn't.
sorry, i can't offer any more support for this 馃槩 . but i would love to hear if you're successful making dom4 work with JSDom, because we'd like to migrate to it too.
You could try shimming DocumentFragment, here's an example: https://github.com/barberboy/dom-elements/blob/d12ce3dd2e49e3e928e1501f6b9cbaa82385c217/src/index.js#L24
dom4 should also handle this more nicely -- let's file an issue / send a PR to add better support for jsdom
Can you show me an example of using dom4 instead of jsdom to configure both window and document? I ain't able to find it.
sorry, i haven't done it either. i suggest prodigious googling to understand how the two can play together.
Same issue, a lot of people use that kind of config: jsdom + enzyme + mocha/jest, it could be called a standard.
We've hit this same issue while attempting to integrate blueprint into our app this week. Our setup is the standard jsdom + enzyme + mocha.
This worked for me:
const keys = [
'DocumentFragment',
'Event',
'KeyboardEvent',
'MouseEvent'
]
keys.forEach((key) => {
global[key] = document.defaultView[key]
})
global.self = document.defaultView
Good job @gimenete, thanks a lot .
Your solution saved my life :)
@lucantini It seems that not all properties in document.defaultView are enumerable. So some properties like DocumentFragment are missing because are not returned by Object.keys or a for-in loop. Check my previous comment.
Most helpful comment
This worked for me: