Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Mocha rendering, DOMException Wrong Document

Using React 13.2 and looking to test lifecyles with a setup like the one shown on this gist. If I don't stop subsequent renders (via the shouldComponentUpdate method) then anything causes a render (after the initial) explodes with a DOMException Wrong Document:

     DOMException: Wrong document
 at core.Node.insertBefore (D:\development\projects\fsm\node_modules\jsdom\lib\jsdom\level1\core.js:583:13)
 at core.Node.insertBefore (D:\development\projects\fsm\node_modules\jsdom\lib\jsdom\level2\events.js:326:32)
 at insertChildAt (D:\development\projects\fsm\node_modules\react\lib\DOMChildrenOperations.js:34:14)
 at Object.DOMChildrenOperations.processUpdates (D:\development\projects\fsm\node_modules\react\lib\DOMChildrenOpertions.js:106:11)

JSDOM bails because the parent node is not a document and it don't share the same owner document as the child being inserted. Yeah. How could the owning document be anything other than that the global unless React is doing something funky under the hood.

Just surprised that I don't see more people having a similar problem? There is nothing odd-ball with my Mocha setup nor the JSX components being rendered. Plus the initial render goes fine.

like image 325
Matthew Campbell Avatar asked Feb 15 '26 18:02

Matthew Campbell


1 Answers

Update for node 4

With node 4 we can use the latest jsdom and solve this issue in a better way, e.g. using testdom.

This is how I test a React 0.13 component with mocha on node 4:

import testDom from "testdom";
import { expect } from "chai";

testDom("<html><body></body></html>");
const React = require("react/addons");
const MyTestableComponent = require("../src/MyTestableComponent");
const ExecutionEnvironment = require("react/lib/ExecutionEnvironment");
ExecutionEnvironment.canUseDOM = true;

describe("MyTestableComponent", () => {
   it("works!", () => {
       const component = <MyTestableComponent />;
       expect(true).to.equal(true);
   })
})

Note that we should require rather than import React and the component.


Previous answer

I could fix this issue by following the OP's own comment to the question.

Since React stores the document in an internal variable when it is required, we need to remove React from the require.cache object, before requiring it again:

var jsdom = require("jsdom").jsdom;
var React, TestUtils;

describe("Example", function() {

  beforeEach(function() {
    // remove react from the require cache
    for (var key in require.cache) {
      if (key.match(/\/node_modules\/react\//)) {
        delete require.cache[key];
      }
    }

    // init the DOM
    global.document = jsdom("<html><head><script></script></head><body></body></html>");
    global.window = document.parentWindow;

    // require react again    
    React = require("react/addons");
    TestUtils = React.addons.TestUtils;

  });

  // my tests...

});
like image 126
gpbl Avatar answered Feb 17 '26 08:02

gpbl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!