enzymejs / enzyme

JavaScript Testing utilities for React
https://enzymejs.github.io/enzyme/
MIT License
19.96k stars 2.01k forks source link

react-dom is an implicit dependency in order to support react@0.13-14. #695

Closed doque closed 7 years ago

doque commented 7 years ago

Hi, I'm trying to run a very simple test using mocha:

Spec file:

import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';

import Header from './index.js';

describe('Header', () => {

  let wrapper;

  beforeEach(() => {
    shallow(<Header name="Hello" />);
  });

  it('mounts correctly', () => {
    expect(wrapper.is('header')).to.be.truthy();
  });
});

Output:


➜  component-library git:(master) ✗ npm test

> component-library@1.0.0 test component-library
> mocha --require ./test-setup.js src/**/*spec.js

react-dom is an implicit dependency in order to support react@0.13-14. Please add the appropriate version to your devDependencies. See https://github.com/airbnb/enzyme#installation
component-library/node_modules/enzyme/build/react-compat.js:113
      throw e;
      ^

Error: proxies not supported on this platform. On v8/node/iojs, make sure to pass the --harmony_proxies flag
    at new global.Proxy (component-library/node_modules/harmony-reflect/reflect.js:2116:13)
    at Object.<anonymous> (component-library/node_modules/react-dom/lib/SyntheticEvent.js:188:22)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/react-dom/lib/SyntheticCompositionEvent.js:13:22)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/react-dom/lib/BeforeInputEventPlugin.js:16:33)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/react-dom/lib/ReactDefaultInjection.js:14:30)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/react-dom/lib/ReactDOM.js:16:29)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/react-dom/index.js:3:18)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at component-library/node_modules/enzyme/build/react-compat.js:109:18
    at Object.<anonymous> (component-library/node_modules/enzyme/build/react-compat.js:192:5)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/enzyme/build/Utils.js:62:20)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/enzyme/build/MountedTraversal.js:31:14)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/enzyme/build/ReactWrapper.js:35:25)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/node_modules/enzyme/build/index.js:6:21)
    at Module._compile (module.js:410:26)
    at Module._extensions..js (module.js:417:10)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (component-library/src/components/Header/spec.js:2:1)
    at Module._compile (module.js:410:26)
    at loader (component-library/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (component-library/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at /usr/local/lib/node_modules/mocha/lib/mocha.js:219:27
    at Array.forEach (native)
    at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:216:14)
    at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:468:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:403:18)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:442:10)
    at startup (node.js:136:18)
    at node.js:966:3
npm ERR! Test failed.  See above for more details.

I've uploaded a gist with my dependencies.

Any ideas what I'm doing wrong here?

Thank you.

ljharb commented 7 years ago

What version of node are you using? it looks like the error is actually in harmony-reflect, a dependency of yours (and since using --harmony is a horrifically bad idea, you probably don't need that dep)

doque commented 7 years ago

Hi, I'm using v2.4.6.

ljharb commented 7 years ago

Um, node v2? That'd be io.js - are you sure?

doque commented 7 years ago

Oh, sorry, mixed up my digits here - v4.2.6.

doque commented 7 years ago

Oh, and just for the record, here is the required test-setup.js

ljharb commented 7 years ago

And what version of jsdom? What's your package.json look like? Do you use harmony-reflect in your own code?

doque commented 7 years ago

I've added my dependencies in the OP: https://gist.github.com/doque/57fe0cbbb0d57a76cca2f515eca786fb

I'm not using harmony-reflect anywhere.

ljharb commented 7 years ago

And just to be absolutely sure - can you also provide a gist of your npm ls output?

doque commented 7 years ago

Sure, but that command is failing with this error message:

npm ERR! extraneous: archy@1.0.0 component-library/node_modules/archy
npm ERR! extraneous: caching-transform@1.0.1 component-library/node_modules/caching-transform
npm ERR! extraneous: default-require-extensions@1.0.0 component-library/node_modules/default-require-extensions
npm ERR! extraneous: istanbul-lib-hook@1.0.0-alpha.4 component-library/node_modules/istanbul-lib-hook
npm ERR! extraneous: istanbul-lib-instrument@1.3.0 component-library/node_modules/istanbul-lib-instrument
npm ERR! extraneous: istanbul-lib-report@1.0.0-alpha.3 component-library/node_modules/istanbul-lib-report
npm ERR! extraneous: istanbul-lib-source-maps@1.1.0 component-library/node_modules/istanbul-lib-source-maps
npm ERR! extraneous: istanbul-reports@1.0.0 component-library/node_modules/istanbul-reports
npm ERR! extraneous: merge-source-map@1.0.3 component-library/node_modules/merge-source-map
npm ERR! extraneous: node-pre-gyp@0.6.31 component-library/node_modules/node-pre-gyp
npm ERR! extraneous: resolve-from@2.0.0 component-library/node_modules/resolve-from
npm ERR! extraneous: spawn-wrap@1.2.4 component-library/node_modules/spawn-wrap
npm ERR! extraneous: test-exclude@3.2.2 component-library/node_modules/test-exclude

Yields this output before the error message: https://gist.github.com/doque/d96297bc322652416d48ad0a167cd4ae

ljharb commented 7 years ago

That output can be resolved by running npm prune, but that shouldn't impact this issue either way.

batjko commented 7 years ago

We're encountering the same thing as of today.

> mocha server/test-helpers/jsdom-browser.js "src/**/*.spec.js*"

react-addons-test-utils is an implicit dependency in order to support react@0.13-14. Please add the appropriate version to your devDependencies. See https://github.com/airbnb/enzyme#installation
/home/pmetzdorf/IdeaProjects/datavis/node_modules/enzyme/build/react-compat.js:132
      throw e;
      ^
Error: Cannot find module 'react-dom/lib/ReactTestUtils'
    at Function.Module._resolveFilename (module.js:455:15)

Any recent updates on the test utils maybe?

ljharb commented 7 years ago

Yes, react 15.4 removed ReactTestUtils from react-dom. However, react-addons-test-utils (and enzyme) handles this just fine, unless your dependencies aren't correct.

batjko commented 7 years ago

@ljharb Well, it worked just fine last week, so I am assuming my dependencies should be as normal. I have Enzyme 2.4.1, react-addons-test-utils 15.3.2 (and React and ~React-DOM 15.3.2~ as well), so I don't think I'm encountering the 15.4 issue.

Edit:

Actually, I just did an npm ls and found that the test utils are actually at 15.4, while everything else was still on 15.3.2. Replacing it with the 15.3.2 version solved the issue. What should I change about my dependencies to be able to support the 15.4 version?

doque commented 7 years ago

I've found the solution. We're using mock-css-modules, which requires mocha to run with --harmony-proxies parameters. Once added, tests run through fine.

batjko commented 7 years ago

Ideally, I'd like to have this re-opened, please. I am not using mock-css-modules.

doque commented 7 years ago

Did you try passing the parameter to your test runner?

batjko commented 7 years ago

Thanks for re-opening, @doque . My error varies slightly in that it doesn't complain about proxies or adding the harmony flag. So I think it's caused by something else.

And since it all worked fine until the TestUtils got upgraded to 15.4, it's an issue that should be fixed either by Enzyme, which doesn't handle that update properly, or by the Test Utils project if the error originates there.

ljharb commented 7 years ago

@batjko if you check package.json, npm ls, and the contents of node_modules, what versions are react, react-dom, and react-addons-test-utils? Do you have more than one copy of any of them?

batjko commented 7 years ago

Yes, I did check npm ls and, as mentioned above, I found that react and react-dom were on 15.3.2 while react-addons-test-utils was suddenly on 15.4. For now I had to revert the latter back to 15.3.2. Should I instead look at upgrading react and react-dom to 15.4?

ljharb commented 7 years ago

Ah, sorry, I'd missed your edit. Yes, all three need to be on the same version at all times. If you want to upgrade one, upgrade the other two as well.

doque commented 7 years ago

Just as a side note - Using the latest version of node, I did not need to add the --harmony-proxies flag anymore.

batjko commented 7 years ago

@ljharb Thanks for confirming. I am surprised that only the test utils were updated then, as in our package.json all three are saved as @^15.3.2, so I would have thought if Facebook updated the whole lot, they would all upgrade when you do an npm install.

Either way, I'm good. Happy to close this one off.

heldrida commented 7 years ago

I'm getting this same error, tried to solve it in different ways; seems to have started happening randomly, tried to revert back to previous versions from weeks ago and the error is triggered. Nuked the node_modules and installed (when reverted back). Not sure what I'm missing.

the actual error in the console.log:

react-dom is an implicit dependency in order to support react@0.13-14. Please add the appropriate version to your devDependencies. See https://github.com/airbnb/enzyme#installation

events.js:160
      throw er; // Unhandled 'error' event
      ^
Invariant Violation: EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.
    at invariant (/Users/Helder/www/foobar-kiosk/node_modules/fbjs/lib/invariant.js:44:15)
    at Object.injectEventPluginOrder (/Users/Helder/www/foobar-kiosk/node_modules/react-dom/lib/EventPluginRegistry.js:151:66)
    at Object.EventPluginHub.injection.injectEventPluginOrder (/Users/Helder/www/foobar-kiosk/node_modules/react-dom/lib/ReactTestUtils.js:361:29)
    at Object.inject (/Users/Helder/www/foobar-kiosk/node_modules/react-dom/lib/ReactDefaultInjection.js:49:33)
    at Object.<anonymous> (/Users/Helder/www/foobar-kiosk/node_modules/react-dom/lib/ReactDOM.js:27:23)
    at Module._compile (module.js:571:32)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/Helder/www/foobar-kiosk/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Function.Module._load (/Users/Helder/www/foobar-kiosk/node_modules/mock-require/index.js:23:22)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/Helder/www/foobar-kiosk/node_modules/react-dom/index.js:3:18)
    at Module._compile (module.js:571:32)

the package.json:

{
  "name": "zxxzzxzx",
  "version": "1.0.0",
  "description": "zxzxzzxzxzx",
  "main": "gulpfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "author": "Helder O.",
  "license": "ISC",
  "bugs": {
    "url": ""
  },
  "homepage": "",
  "devDependencies": {
    "babel-core": "^6.13.2",
    "babel-eslint": "^6.1.2",
    "babel-loader": "^6.2.5",
    "babel-polyfill": "^6.23.0",
    "babel-preset-es2015": "^6.13.2",
    "babel-preset-react": "^6.11.1",
    "chai": "^3.5.0",
    "cheerio": "^0.22.0",
    "compression-webpack-plugin": "^0.3.2",
    "css-loader": "^0.23.1",
    "enzyme": "^2.4.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.9.0",
    "gsap": "^1.19.1",
    "gulp": "^3.9.1",
    "gulp-mocha": "^3.0.1",
    "gulp-plumber": "^1.1.0",
    "gulp-s3": "^0.3.0",
    "gulp-util": "^3.0.7",
    "html-webpack-plugin": "^2.22.0",
    "jsdom": "^9.5.0",
    "lodash": "^4.15.0",
    "mocha": "^3.0.2",
    "mocha-jsdom": "^1.1.0",
    "mock-require": "^2.0.1",
    "node-sass": "^3.8.0",
    "nodemon": "^1.11.0",
    "open": "0.0.5",
    "react": "^15.3.1",
    "react-addons-test-utils": "^15.3.1",
    "react-dom": "^15.3.1",
    "react-hot-loader": "^1.3.0",
    "react-redux": "^4.4.5",
    "react-router": "^2.7.0",
    "react-router-redux": "^4.0.5",
    "redux": "^3.5.2",
    "redux-mock-store": "^1.2.0",
    "redux-promise": "^0.5.3",
    "redux-thunk": "^2.1.0",
    "s3": "^4.4.0",
    "sass-loader": "^4.0.0",
    "sockjs-client": "^1.1.1",
    "style-loader": "^0.13.1",
    "testdom": "^2.0.0",
    "webpack": "^1.13.2",
    "webpack-dev-server": "^1.15.0",
    "webstomp-client": "^1.0.3",
    "yargs": "^6.6.0",
    "zombie": "^4.2.1"
  },
  "dependencies": {
    "express": "^4.14.0"
  }
}

and the test spec example below:

require('testdom')('<html><body></body></html>')

import React from 'react'
import { expect } from 'chai'
import { shallow, mount, render } from 'enzyme'
import configureStore from 'redux-mock-store'
import InitialScreen from '../../src/js/containers/initialScreen'
import Keyboard from '../../src/js/containers/Keyboard'
import mock from 'mock-require'

// mock gsap
mock('gsap', {
  TimelineLite: function () {
    return null
  },
  TweenLite: {
    fromTo: function () {
      return null
    }
  }
})

// provide the store (mock store)
const mockStore = configureStore()
const getState = {
  reservation: {},
  user: {
    user_typed_code: ''
  },
  whoami: {
    carrierBagPrice: '',
    carrierBagSku: '',
    kioskCollectionPoint: '',
    storeName: '',
    storeNumber: ''
  }
} // replace this with necessary state
const store = mockStore(getState)
const props = {
  store: store
}

describe('The reservation number input box', function () {
  it('should exist', function () {
    const wrapper = mount(<InitialScreen {...props} />)
    expect(wrapper.find('[name="collect-reservation-code"]')).to.have.length(1)
  })
  it('should start empty', function () {
    const wrapper = mount(<InitialScreen {...props} />)
    expect(wrapper.find('input[name="collect-reservation-code"]').props().value).to.equal('')
  })
})

describe('The Keyboard container', function () {
  const totalKeys = 37
  it('should have a total of ' + totalKeys + ' keys', function () {
    const wrapper = mount(<Keyboard />)
    expect(wrapper.find('.row span')).to.have.length(totalKeys)
  })
})
ljharb commented 7 years ago

@heldrida using "mock require" functionality often breaks things in unanticipated ways. Can you reproduce the error without using that?