Stryker: Cannot find module 'setupDevtools' from 'setup.js'

Created on 21 Apr 2018  ·  31Comments  ·  Source: stryker-mutator/stryker

Summary

I use a react-native project with typescript and jest.
When I tried to install stryker and run it, I have the following message :

````
Cannot find module 'setupDevtools' from 'setup.js'

  at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:169:17)
  at Object.<anonymous> (../../node_modules/react-native/jest/setup.js:30:1)

      ● Test suite failed to run

````

But when I use jest, I don't have any error.
Is something wrong with my config or is it a real issue ?

Stryker config

Stryker

module.exports = (config) => {
  config.set({
    // Test runners
    testRunner: 'jest',
    jest: {
      config: require('./jest.config.js'),
    },

    // Transpilers
    transpilers: ['typescript', 'babel'],
    tsconfigFile: 'tsconfig.json',
    babelrcFile: '.babelrc',

    // Reporters
    reporter: ['clear-text', 'progress'],
    coverageAnalysis: 'off',

    // Files
    files: [
      'src/**/*',
      'jest/**/*',
      '__mocks__/**/*',
    ],

    // Mutations
    mutator: 'typescript',
    // mutate: ['src/**/*.ts?(x)', '!src/**/*.container.ts', '!src/**/*.d.ts', '!**/index.ts'],
  });
};

Jest
````js
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
transform: {
'\.(js|jsx)$': '/node_modules/babel-jest',
'\.(ts|tsx)$': '/node_modules/ts-jest/preprocessor.js',
'\.(gql|graphql)$': '/node_modules/jest-transform-graphql',
},
transformIgnorePatterns: [
'node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@bam.tech/react-native-(root-siblings|modalbox)|static-container|react-navigation)',
],
testRegex: '(/__tests__/.|\.(test|spec))\.(ts|tsx|js|jsx)$',
testPathIgnorePatterns: ['\.snap$', '/node_modules/', '/stryker-tmp/'],
cacheDirectory: '.jest/cache',
moduleNameMapper: {
'^[./a-zA-Z0-9$_-]+\.(jpg|png|gif|eot|svg|ttf|woff|woff2|mp4|webm)$':
'/jest/FileStub.js',
},
collectCoverageFrom: [
'src//
.{js|ts|tsx|jsx}',
'!src/
/.container.ts',
'!src//
.d.ts',
'!
/index.ts',
],
setupTestFrameworkScriptFile: '/jest/setupTests.js',
};

````

Babel
js { "presets": ["react-native", "react-native-stage-0/decorator-support"] }

Stryker environment

"stryker": "^0.22.4",
"stryker-api": "^0.16.1",
"stryker-babel-transpiler": "^0.4.2",
"stryker-jest-runner": "^0.6.0",
"stryker-typescript": "^0.10.2",

But also

"babel-core": "^6.26.0",
"babel-jest": "22.4.1",
"babel-preset-react-native": "4.0.0",
"babel-preset-react-native-stage-0": "^1.0.1",
"jest": "22.4.2",
"ts-jest": "^22.4.1",
"typescript": "^2.7.2"

Your Environment

| software | version(s)
| ---------------- | -------
| node | 9.5.0
| npm | 5.6.0
| Operating System | macOS High Sierra

☠ stale

Most helpful comment

@mickaelw It's an issue with type in your dependencies.
You ask for types/react 16.7.3 but enzyme is still using types/react 16.4.13 in you yarn.lock.

I made a PR, it's not the best fix but it's enough.
https://github.com/mickaelw/test-stryker/pull/1

@nicojs In this PR, yarn test works for me, but not yarn stryker

All 31 comments

Thanks for opening this issue!
Where is the setup.js file located?

What happens when you remove the files property from your Stryker config?

@simondel
Same error without the files property.

setup.js is located in node_modules/react-native/jest. First lines of this files are
````
const mockComponent = require.requireActual('./mockComponent');

require.requireActual('../Libraries/polyfills/babelHelpers.js');
require.requireActual('../Libraries/polyfills/Object.es7.js');
require.requireActual('../Libraries/polyfills/error-guard');

global.__DEV__ = true;

global.Promise = require.requireActual('promise');
global.regeneratorRuntime = require.requireActual('regenerator-runtime/runtime');

global.requestAnimationFrame = function(callback) {
return setTimeout(callback, 0);
};
global.cancelAnimationFrame = function(id) {
clearTimeout(id);
};

jest
.mock('setupDevtools')
.mock('npmlog');

// there's a __mock__ for it.
jest.setMock('ErrorUtils', require('ErrorUtils'));

jest
.mock('InitializeCore', () => {})
.mock('Image', () => mockComponent('Image'))
.mock('Text', () => mockComponent('Text'))
.mock('TextInput', () => mockComponent('TextInput'))
.mock('Modal', () => mockComponent('Modal'))
.mock('View', () => mockComponent('View'))
.mock('RefreshControl', () => require.requireMock('RefreshControlMock'))
.mock('ScrollView', () => require.requireMock('ScrollViewMock'))
````

If I remove .mock('setupDevtools), I have the same error for InitializeCore, then for Image, ...

If I comment all this file, I have the following error

Couldn't find preset "es2015" relative to directory "/Users/vincentl/Theodo/foodi/node_modules/request/node_modules/hawk"

But in this case jest doesn't work either.

It seems to be an older issue with jest and react-native (https://www.google.fr/search?q=setupdevtools+from+setup.js)

NB : I found the setupDevtools.js file in node_modules/react-native/Libraries/Core/Devtools with the following code
````
/**

  • Copyright (c) 2015-present, Facebook, Inc.
  • All rights reserved.
    *
  • This source code is licensed under the BSD-style license found in the
  • LICENSE file in the root directory of this source tree. An additional grant
  • of patent rights can be found in the PATENTS file in the same directory.
    *
  • @providesModule setupDevtools
  • @flow
    */
    'use strict';

type DevToolsPluginConnection = {
isAppActive: () => boolean,
host: string,
port: number,
};

type DevToolsPlugin = {
connectToDevTools: (connection: DevToolsPluginConnection) => void,
};

let register = function () {
// noop
};

if (__DEV__) {
const AppState = require('AppState');
const WebSocket = require('WebSocket');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an

  • error found when Flow v0.54 was deployed. To see the error delete this
  • comment and run Flow. */
    const reactDevTools = require('react-devtools-core');
    const getDevServer = require('getDevServer');

// Initialize dev tools only if the native module for WebSocket is available
if (WebSocket.isAvailable) {
// Don't steal the DevTools from currently active app.
// Note: if you add any AppState subscriptions to this file,
// you will also need to guard against AppState.isAvailable,
// or the code will throw for bundles that don't have it.
const isAppActive = () => AppState.currentState !== 'background';

// Get hostname from development server (packager)
const devServer = getDevServer();
const host = devServer.bundleLoadedFromServer
  ? devServer.url.replace(/https?:\/\//, '').split(':')[0]
  : 'localhost';

reactDevTools.connectToDevTools({
  isAppActive,
  host,
  // Read the optional global variable for backward compatibility.
  // It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
  port: window.__REACT_DEVTOOLS_PORT__,
  resolveRNStyle: require('flattenStyle'),
});

}
}

module.exports = {
register,
};
````

Would there be a way for you to share code? Or is the project based on a public quickstart project that we could perhaps use to find the issue?

@simondel
I made this for you.

git clone [email protected]:VincentLanglet/StrykerTest.git
cd StrykerTest
yarn

Jest works

yarn test:unit 

Stryker does not

yarn stryker

Awesome thanks! I'll try it out tomorrow :)

I'm having some issues reproducing this. When I run your repo on my machine (node 8, npm 5, Windows 10) I get the following message from Stryker:

    Couldn't find preset "es2015" relative to directory "C:\\dev\\tryouts\\StrykerTest\\node_modules\\hawk"

      at ../../node_modules/babel-core/lib/transformation/file/options/option-manager.js:293:19
          at Array.map (<anonymous>)
      at OptionManager.resolvePresets (../../node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
      at OptionManager.mergePresets (../../node_modules/babel-core/lib/transformation/file/options/option-manager.js:264:10)
      at OptionManager.mergeOptions (../../node_modules/babel-core/lib/transformation/file/options/option-manager.js:249:14)
      at OptionManager.init (../../node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
      at File.initOptions (../../node_modules/babel-core/lib/transformation/file/index.js:212:65)
      at new File (../../node_modules/babel-core/lib/transformation/file/index.js:135:24)
      at Pipeline.transform (../../node_modules/babel-core/lib/transformation/pipeline.js:46:16)

This got me wondering, why does your project use babel? Can't you use the typescript compiler to transform your js files?

In the case of Stryker the config transpilers: ['typescript', 'babel'] will feed all your files to the TypeScript transpiler and then hand all files to the Babel transpiler. This is probably not what you want.

After I removed babel from the project, I did get an error that relates to the error you have:

    Cannot find module '../transforms/transform-dynamic-import' (While processing preset: "C:\\dev\\tryouts\\StrykerTest\\node_modules\\babel-preset-react-native\\index.js")

      at getPreset (../../node_modules/babel-preset-react-native/configs/main.js:77:18)
      at Object.<anonymous> (../../node_modules/babel-preset-react-native/configs/main.js:91:14)

I'll investigate this further.

@simondel Thanks for the time you takes

I don't really know and can't explain why we need babel. We are starting using typescript on our project and still having some js files. For example, index.js, setupTest.js, ..., and running yarn test:unit without babel will return

/home/vincentl/Perso/StrykerTest/jest/setupTests.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Enzyme from 'enzyme';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

How did you remove babel from the project ?

And I'm not sure because I could only try tomorrow, but I think my real react-native project won't correctly run and build on IOS and Android without babel. For information, we're using this package. I'll check tomorrow.

But I'm surprised the provided repository does not produce error about setupDevtools on your computer.
I tried on Mac / Node 9.5 and Linux / Node 8.4 and I got it every time.

I need to comment the  node_modules/react-native/jest/setup.js from line 29 to the EOF to get the error you had

Couldn't find preset "es2015" relative to directory "/home/vincentl/Perso/StrykerTest/node_modules/request/node_modules/hawk"

In this case, if I remove setupTestFrameworkScriptFile from the jest config and use the test

expect(true).toBe(true);

It works !!!

But then, I removed

transpilers: ['typescript', 'babel'],
tsconfigFile: 'tsconfig.json',
babelrcFile: '.babelrc',

Still works ! Why ? It makes me confused.

Ok, if I go back and look at the preset error.
I found out the issue came from the following lines of setupTest.js

const mockDocumentForEnzymeMount = () => {
  const jsdom = require('jsdom');

  const { JSDOM } = jsdom;

  const { document } = new JSDOM('').window;
  global.document = document;
};
mockDocumentForEnzymeMount();

But then, if i run yarn add babel-preset-es2015, I have the error

/home/vincentl/Perso/StrykerTest/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js: missing super() call in constructor
         95 | 
         96 |   class XMLHttpRequest extends XMLHttpRequestEventTarget.interface {
      >  97 |     constructor() { // eslint-disable-line constructor-super
            |     ^
         98 |       const theThis = Object.create(new.target.prototype);
         99 |       XMLHttpRequestEventTarget.setup(theThis);
        100 |       theThis.upload = XMLHttpRequestUpload.create();

I found this issue and try quickly yarn add [email protected] and now I have the error

Button should render the button
        Error: Cannot find module 'Text' from 'react-native-implementation.js'
    at Resolver.resolveModule (/home/vincentl/Perso/StrykerTest/node_modules/jest-resolve/build/index.js:169:17)

I'll will keep investiguate tomorrow or this week-end.

But I don't think that is a solution for me cause during this time, yarn test:unit does not work with the error

Invariant Violation: __fbBatchedBridgeConfig is not set, cannot invoke native modules

And if I don't comment the  node_modules/react-native/jest/setup.js from line 29 to the EOF, tests pass but Stryker ask me for setupDevtools...

Ok, seems like I don't need babel for running application, but I need it for using jest, https://github.com/kulshekhar/ts-jest#react-native

I have the same error with:
Stryker config:

module.exports = config => {
    config.set({
        packageManager: 'yarn',
        testRunner: 'jest',
        jest: {
            projectType: 'react-ts',
            config: require('./configuration/jest.config.js')
        },
        mutator: 'typescript',
        tsconfigFile: 'tsconfig.json',
        transpilers: [],
        reporters: [
            'html',
            'clear-text',
            'progress',
            'dashboard'
        ],
        coverageAnalysis: 'off',
        mutate: [
            'src/**/*.ts'
        ]
    })
}

And Jest config:

module.exports = {
    preset: 'react-native',
    rootDir: '..',
    setupFiles: [
        '<rootDir>/configuration/jest.setup.js'
    ],
    snapshotSerializers: [
        'enzyme-to-json/serializer'
    ],
    moduleFileExtensions: [
        'ts',
        'tsx',
        'js'
    ],
    transform: {
        '^.+\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js',
        '\\.(ts|tsx)$': 'ts-jest'
    },
    testMatch: [
        '<rootDir>/__tests__/**/?(*.)+(spec|test).ts?(x)'
    ],
    testPathIgnorePatterns: [
        '\\.snap$',
        '<rootDir>/node_modules/'
    ],
    collectCoverageFrom: [
        '<rootDir>/src/**/*.{ts,tsx}'
    ],
    coveragePathIgnorePatterns: [
        '<rootDir>/__tests__/'
    ],
    coverageDirectory: '<rootDir>/jest/coverage',
    coverageReporters: [
        'html',
        'text',
        'text-summary'
    ]
}

| Package | Version |
| ------------- |:-------------:|
| Node | 8.11 & 10.9 |
| React Native | 0.56 |
| TS | 3.0.3 |
| Jest | 23.5.0 |
| Stryker | 0.29.1 |

@VincentLanglet did you find any solution to this? Facing the same issue

@oferRounds No sorry

I will try to figure out what's wrong before this year is done. Thanks for your patience

I've spent a couple of hours trying to reproduce this issue, but couldn't. I'm not experienced with Jest or React.

Can anyone create a public repo that reproduces this issue? Any help will be much appreciated. We really want these kind of use cases to work before we publish version 1. Thanks in advance ❤️

I had this old repo https://github.com/VincentLanglet/StrykerTest

But now it give the error :

/Users/vincentl/Perso/StrykerTest/node_modules/react-native/jest/setup.js: babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
    Invalid variable access: console

Yeah, I get that error as well, with regular tests. Any other reproduction repo? Or can you update it to work again? Sorry, but really can't do much without reproduction steps.

@nicojs I have this very light repo: https://github.com/mickaelw/test-stryker

Sorry in advance for iOS and Android folders

@mickaelw I've cloned the repo, but yarn test isn't working for me:

$ yarn test
yarn run v1.12.3
$ jest --config configuration/jest.config.js
 FAIL  __tests__/test.spec.tsx
  ● Test suite failed to run

    TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
    __tests__/test.spec.tsx:14:29 - error TS2605: JSX element type 'App' is not a constructor function for JSX elements.
      Property 'context' is missing in type 'App' but required in type 'ElementClass'.

    14         const app = shallow(<App/>)
                                   ~~~~~~

      node_modules/@types/enzyme/node_modules/@types/react/index.d.ts:315:9
        315         context: any;
                    ~~~~~~~
        'context' is declared here.

 PASS  __tests__/test2.spec.ts

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.972s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Any ideas?

@nicojs yes, I think it's rxjs-tslint dependency. You can remove all ^ in the package.json and re install all package with the good version

Let me know if it's better ;)

@mickaelw It's an issue with type in your dependencies.
You ask for types/react 16.7.3 but enzyme is still using types/react 16.4.13 in you yarn.lock.

I made a PR, it's not the best fix but it's enough.
https://github.com/mickaelw/test-stryker/pull/1

@nicojs In this PR, yarn test works for me, but not yarn stryker

I've been able to reproduce the error without Stryker, just plain jest + react-native. I've opened up an issue at react-native. Hopefully there is a solution. https://github.com/facebook/react-native/issues/22823

@nicojs Great job ! Thanks

@nicojs Cool! Do you have a workaround?

They closed the issue and redirect us to :
https://github.com/facebook/jest/issues/1477
https://github.com/facebook/jest/issues/5356
https://github.com/facebook/jest/pull/7549

It seems to be a jest issue. But if it is, why did this happen in this context with react-native and not automatically with react or other libraries @nicojs ?

@VincentLanglet you're closing this issue, is it fixed for you?

I don't know why only react-native is effected by this.

@nicojs Since it's a react-native/jest issue, I was thinking a stryker issue was not necessary.

Ok, in that case I would like to keep this issue open for now, so we don't lose track of it.

The good news is that a lot of people seem effected. So hopefully, it will be fixed soon.

As a workaround, I guess you _could specify files_ and _disable symlinkNodeModules_.

The files array should look something like this:

files: [
  '*.*', 
  'node_modules/react-native/**', 
  'node_modules/other-required-node-module/**', 
  'src/**', 
  'test/**'
]

However, it will take a lot of time to populate each sandbox. You should be careful to not include too much node_modules in your sandbox.

Any updates on this issue? Or any workaround?
Using [email protected]

I'm afraid the workaround that I specified is the only one for now. The issue in Jest is being tracked here:

https://github.com/facebook/jest/issues/5356

In hindsight, setting symlinkNodeModules to files might be enough to fix the issue see #1564.

I set the symlinkNodeModules to false (not to files ;) but I get another error:

ERROR InitialTestExecutor One or more tests resulted in an error:
    Test runner crashed. Tried twice to restart it without any luck. Last time the error message was: Error: : ● Validation Error:

  Module <rootDir>/node_modules/react-native/jest/preprocessor.js in the transform option was not found.
         <rootDir> is: /Users/rang/Documents/Workspace/ReactNativeWorkspace/react-native-skeleton/.stryker-tmp/sandbox4155167

  Configuration Documentation:
  https://jestjs.io/docs/configuration.html

● Validation Error:

  Module <rootDir>/node_modules/react-native/jest/preprocessor.js in the transform option was not found.
         <rootDir> is: /Users/rang/Documents/Workspace/ReactNativeWorkspace/react-native-skeleton/.stryker-tmp/sandbox4155167

  Configuration Documentation:
  https://jestjs.io/docs/configuration.html

Error: : ● Validation Error:

  Module <rootDir>/node_modules/react-native/jest/preprocessor.js in the transform option was not found.
         <rootDir> is: /Users/rang/Documents/Workspace/ReactNativeWorkspace/react-native-skeleton/.stryker-tmp/sandbox4155167

  Configuration Documentation:
  https://jestjs.io/docs/configuration.html

● Validation Error:

  Module <rootDir>/node_modules/react-native/jest/preprocessor.js in the transform option was not found.
         <rootDir> is: /Users/rang/Documents/Workspace/ReactNativeWorkspace/react-native-skeleton/.stryker-tmp/sandbox4155167

  Configuration Documentation:
  https://jestjs.io/docs/configuration.html

    at ChildProcess.worker.on (/Users/rang/Documents/Workspace/ReactNativeWorkspace/react-native-skeleton/node_modules/@stryker-mutator/core/src/child-proxy/ChildProcessProxy.js:100:68)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at emit (internal/child_process.js:772:12)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
15:14:53 (28469) ERROR StrykerCli an error occurred Error: Something went wrong in the initial test run
    at InitialTestExecutor.validateResult (/Users/rang/Documents/Workspace/ReactNativeWorkspace/react-native-skeleton/node_modules/@stryker-mutator/core/src/process/InitialTestExecutor.js:85:15)
    at InitialTestExecutor.run (/Users/rang/Documents/Workspace/ReactNativeWorkspace/react-native-skeleton/node_modules/@stryker-mutator/core/src/process/InitialTestExecutor.js:40:14)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

Any idea how to make it works?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

simondel picture simondel  ·  17Comments

trollepierre picture trollepierre  ·  18Comments

jeznag picture jeznag  ·  17Comments

Chowarmaan picture Chowarmaan  ·  18Comments

Djaler picture Djaler  ·  20Comments