enzyme.mount with jsdom v16 throws TypeError: Illegal invocation

Created on 21 Aug 2020  ·  6Comments  ·  Source: enzymejs/enzyme

It loooks like Enzyme doesn't work with jsdom v16.

I use Jest + Enzyme + jsdom.
Jsdom setted up by this instruction:
https://github.com/enzymejs/enzyme/blob/master/docs/guides/jsdom.md

I try to run test that doesn't do nothing, only mount a react element.

test('me test', () => {
  const wrapper = enzyme.mount(<div>test</div>);
});

It worked fine with jsdom v15. But after update to jsdom v16 it fails with "TypeError: Illegal invocation"

My environment

| library | version
| ------------------- | -------
| enzyme | 3.11.0
| react | 16.8.6
| react-dom | 16.8.6
| adapter | enzyme-adapter-react-16 1.15.3

invalid question

All 6 comments

Any additional stack trace?

I made a tiny example repo with my environment to reproduce an issue: https://github.com/ingvar-snow/ezyme-jsdom-trouble-example

And this is a stacktrace:

 FAIL  ./example.test.tsx
  example
    ✕ test (47 ms)

  ● example › test

    TypeError: Illegal invocation

       6 | 
       7 |   test.only('test', () => {
    >  8 |     const wrapper = enzyme.mount(<div>test</div>);
         |                            ^
       9 |   });
      10 | 
      11 | });

      at HTMLDivElement.get nodeType [as nodeType] (node_modules/jsdom/lib/jsdom/living/generated/Node.js:460:15)
      at isValidContainer (node_modules/react-dom/cjs/react-dom.development.js:24640:27)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:24826:8)
      at getFiber (node_modules/enzyme-adapter-react-16/src/detectFiberTags.js:14:12)
      at detectFiberTags (node_modules/enzyme-adapter-react-16/src/detectFiberTags.js:76:15)
      at ReactSixteenAdapter.createMountRenderer (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:431:19)
      at ReactSixteenAdapter.createRenderer (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:786:51)
      at new ReactWrapper (node_modules/enzyme/src/ReactWrapper.js:113:32)
      at Object.mount (node_modules/enzyme/src/mount.js:10:10)
      at Object.<anonymous> (example.test.tsx:8:28)

@ingvar-snow exactly the same here, did you get a solution?

devDependencies:

"@babel/cli": "^7.11.6",
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "babel-jest": "^26.3.0",
    "coveralls": "^3.0.9",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.4",
    "eslint": "^7.9.0",
    "eslint-config-airbnb": "^18.0.1",
    "eslint-plugin-import": "^2.18.2",
    "eslint-plugin-jest": "^23.0.4",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-react": "^7.14.3",
    "eslint-plugin-react-hooks": "^2.3.0",
    "jest": "^26.4.2",
    "jsdom": "^16.4.0",
    "prop-types": "^15.7.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"

setup.js

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { JSDOM } from 'jsdom';

configure({ adapter: new Adapter() });


const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;

function copyProps(src, target) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target),
  });
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};
global.requestAnimationFrame = function requestAnimationFrame(callback) {
  return setTimeout(callback, 0);
};
global.cancelAnimationFrame = function cancelAnimationFrame(id) {
  clearTimeout(id);
};
copyProps(window, global);

 TypeError: Illegal invocation

      59 |     };
      60 |
    > 61 |     const wrapper = mount(<Wrapper />);
         |                     ^
      62 |     wrapper.unmount();
      63 |
      64 |     expect(window.document.removeEventListener).toHaveBeenCalled();

      at HTMLDivElement.get nodeType [as nodeType] (node_modules/jsdom/lib/jsdom/living/generated/Node.js:460:15)
      at isValidContainer (node_modules/react-dom/cjs/react-dom.development.js:24640:27)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:24826:8)
      at getFiber (node_modules/enzyme-adapter-react-16/src/detectFiberTags.js:14:12)
      at detectFiberTags (node_modules/enzyme-adapter-react-16/src/detectFiberTags.js:76:15)
      at ReactSixteenAdapter.createMountRenderer (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:455:19)
      at ReactSixteenAdapter.createRenderer (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:810:51)
      at new ReactWrapper (node_modules/enzyme/src/ReactWrapper.js:113:32)
      at mount (node_modules/enzyme/src/mount.js:10:10)
      at Object.<anonymous> (tests/index.js:61:21)

Has a long time since I've created my jest setup.js, and I set that with jsdom as described in the documentation about jsdom requirement to use mount out of the browser.

const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;

function copyProps(src, target) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target),
  });
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};
global.requestAnimationFrame = function requestAnimationFrame(callback) {
  return setTimeout(callback, 0);
};
global.cancelAnimationFrame = function cancelAnimationFrame(id) {
  clearTimeout(id);
};
copyProps(window, global);

I believe that it used to solve a problem that was happening with the enzyme's versions before 3.11.0 and right now it isn't happening anymore.

I removed that jsdom configuration from my setup.js and my test ran well.

@ingvar-snow i was able to use your repo and reproduce the issue, thanks!

The issue is indeed related to the JSDOM code, because you're using jsdom 16 - if you downgrade to jsdom v10-v15, everything works fine.

Was this page helpful?
0 / 5 - 0 ratings