Upgrade to [email protected]
jsdom v6.0.0 introduced some backwards incompatible changes, and has a changelog here, but is supposed to be much faster. v6.1.0 also adds "basic implementations of HTMLMediaElement and HTMLVideoElement"
EDIT: looks like upgrading to [email protected] makes 240 tests fail :scream:
It looks like jsdom is breaking since 5.4.0 (current version is 5.3.0). I get many of the same error:
TypeError: dom.HTMLDocument is not a function
at createDocument (src/document.js:446:19)
@assaf, I would be happy to help if you don't have time, but I confess I don't know much about jsdom. Could you give some hints ?
- For instance, why you are calling
jsdom/lib/jsdom/browser/Windowinstead ofjsdom.env? - There are quite a lot of patches to jsdom. Are they work-around for issues that may be fixed now, or did you just intend to add more features ?
- What is your opinion about the amount of work to properly upgrade to jsdom 6. Do you think some refactor is needed ? in which areas ?
- Zombie is a more complete emulation of a web browser, so it deals with things like windows/tabs, event loops, WebSocket, etc. It reuses much of JSDOM, but it needs direct access to window/document/etc, stuff you can't do with the simplified public API.
- Some of these add features, some of these fix issues in jSDOM, and some of these fix issues in JSDOM necessary for Zombie to work correctly.
- I've never upgraded to JSDOM 6 before, so I have no idea what it takes.
@assaf I'm running into an issue trying to run some tests with [email protected] with node v0.12.0
>> const defineGetter = require("../utils").defineGetter;
>> ^^^^^
>> SyntaxError: Use of const in strict mode.
>> at exports.runInThisContext (vm.js:73:16)
>> at Module._compile (module.js:443:25)
>> at Object.Module._extensions..js (module.js:478:10)
>> at Module.load (module.js:355:32)
>> at Function.Module._load (module.js:310:12)
>> at Module.require (module.js:365:17)
>> at require (module.js:384:17)
>> at Object.<anonymous> (../js/node_modules/zombie/node_modules/jsdom/lib/jsdom/living/index.js:22:1)
>> at Module._compile (module.js:460:26)
>> at Object.Module._extensions..js (module.js:478:10)
>> at Module.load (module.js:355:32)
>> at Function.Module._load (module.js:310:12)
>> at Module.require (module.js:365:17)
>> at require (module.js:384:17)```
Node 4.x or later
@assaf Is this because I'm running a legacy version of node on macbook?
Yes, you cannot run Zombie on older versions of Node
@assaf Thanks that worked :)
Hi @assaf,
I finally had some time investigate on this jsdom migration issue. I found something weird in jsdom/browser/Windows.js, where we have the below error:
TypeError: dom.HTMLDocument is not a function
at createDocument (src/document.js:446:19)
dom is a variable imported from the living module:
var dom = require("../living");
I guess you know it well because it's patched heavily in Zombie. The issue is that, at this point, dom is an empty object \o/
If you look at this module, it should contain a LOT of properties. So I inserted a log at the end of ..\living\index.js and another one after its import in Windows.js. I got the log in Windows.js before the one in living.js. In other words, living.js is imported after Windows.js (\o/ again).
I suspect there is an issue somewhere in the modules' dependency graph. So to force Node resolving living.js before anything else, I added at the top of zombie/index.js:
require('jsdom');
and guess what... it works !
That looks dirty however, and I especially dislike the idea of writing a piece of code and not know why/how it works. So i'm asking for your help there :-)
For the time beeing, I'm will work on fixing the little issues about migrating jsdom to 5.4.0. My ultimate goal is to get the 7.1.0 working... because it fixes an annoying issue for me.
Cheers
All right, now I'm making progress in upgrading jsdom, version by version. It appears that it complies more and more to the DOM specifications. So it sometimes break things which were not compliant.
My work there consists in updating the JSDOM hotpatches when they bring new features already supported by Zombie (unless Zombie implementation is more compliant - see below) and fixing the unit tests which are using the DOM API in a wrong way.
Here are the breaking changes (to write in the changelog). I'll update the list later:
jsdom 5.4.0
- Element.setAttribute now expects two arguments, even for setting properties (such as "checked", "disabled"...): https://developer.mozilla.org/fr/docs/Web/API/Element/setAttribute
Things to keep in mind
- jsdom implements window.postMessage since 5.5.0, but does not support the source and origin attributes. For the time beeing, I had to keep the monkey patch, and move it somewhere else to keep it working.
You could submit the patch to jsdom instead of continuing to monkeypatch in zombie :). I think we even have an open issue for origin.
I should, I agree, but I'm not good enough, really. :-) Honestly, I don't have much time and zombie is not a piece of cake for a newbie like me.
Let's tackle the monkeypatches after the upgrade is finished. I don't event know if I'll succeed to go to 7.1.0. I have been able to go to 5.6.1 so far.
At last! I have been able to upgrade JSDOM to 6.5.1 (see the above PR)
I had an issue on my app (some jquery plugin which was crashing) which is now fixed by this upgrade, so I'm happy :-)
Only, I couldn't upgrade to jsdom 7.x.x completly. It mostly works (see my fork) but I still had red tests on XHR (which is not a surprise because XHR was completly rewritten in this version). So... on this part I need help. Especially, with jsdom's raw xhr implementation, cookies and redirects (among other things) do not work anymore. And I can't figure out why.
@assaf Please ignore the PR #982 ... it was including too many commits. The #990 should be fine. Could you let me know if/when you plan to merge it? We are already using this code base at my company.
Lack of update to latest version of jsdom means we can't use things like quill.js within zombie, because it requires node traversal (it assumes an implementation of createTreeWalker). @assaf is there anything we can do to get this in? For now I'm having to monkey patch zombie in a Pipeline.addHandler...
http://stackoverflow.com/questions/35132394/quill-js-and-zombie-js/35165809#35165809
I am setting up an Unit Tests for Reactjs, using mocha, jsdom and cheerio, however I am getting below error. Could any one help me in resolving this.
TypeError: this.implementation.$DocumentImpl add Feature is not a function
Below is my test file content.
/** @jsx React.DOM */
var React = require("react/addons"), ReactTestUtils = React.addons.TestUtils; var Label = require("../src/scripts/components/footer"); var assert = require("assert"); var jsdom = require('jsdom').jsdom;
global.initDOM = function () { console.log("init test dom"); var jsdom = require('jsdom'); global.window = jsdom.jsdom().createWindow('
'); global.document = window.document; global.navigator = window.navigator; }global.cleanDOM = function() { console.log("clean test dom"); delete global.window; delete global.document; delete global.navigator; }
describe("Label Test", function() {
beforeEach(function() {
initDOM();
});
afterEach(function() {
cleanDOM();
});
it("Footer Test", function() {
var label = ReactTestUtils.renderIntoDocument(<footer><div><div>Tesco.com 2016 All rights reserved</div></div></footer>);
assert.equal(label, "Tesco.com 2016 All rights reserved");
});
});
@chaituckr, you are not using zombie, are you? Anyway, I suggest you to open a separate ticket for your issue, either in jsdom or zombie.
Please upgrade JSDOM to version 9. There is a bug in JSDOM 7.2.2 used by current zombie:
TypeError: val.replace is not a function
at core.(anonymous function).set value [as value] (D:\dev\zombie-webdriver\node_modules\jsdom\lib\jsdom\level2\html.js:1211:19)
Test case:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>TEST</title>
</head>
<body>
<textarea id="t"></textarea>
<script>
var textarea = document.getElementById('t');
textarea.value = 1; // will throw TypeError: val.replace is not a function
</script>
</body>
</html>