Jest cannot parse error with Jest + Enzyme testing in reactjs - reactjs

I am facing issue with jest testing..
Basically I have made configuration with following steps:
script in package.json:
"jest": {
"scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
"moduleFileExtensions": [
"js",
"json",
"jsx"
],
"moduleNameMapper": {
"^.*[.](jpg|JPG|gif|GIF|png|PNG|less|LESS|css|CSS)$": "EmptyModule"
},
"preprocessorIgnorePatterns": [
"/node_modules/"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/EmptyModule.js"
]
},
"peerDependencies": {
"babel-core": "6.x | ^7.0.0-0"
}
And in jest-script-preprocessor.js
import babelJest from 'babel-jest'
module.exports = {
process: (src, filename) => {
return babelJest.process(src, filename)
.replace(/^require.*\.less.*;$/gm, '')
}
}
Let me know valuable way to get it resolve.

Related

Jest encountered an unexpected token in React (error by personal npm library)

I made a test code (just render and console)
import React from 'react';
import { render } from '#testing-library/react';
import { CheckExperienceHistory } from './CheckExperienceHistory';
import '#testing-library/jest-dom/extend-expect';
it('name validation', async () => {
beforeAll(() => console.log('--- start test ---'));
render(<CheckExperienceHistory />);
})
then, I got error when npm run test
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/stefancho/WebstormProjects/my-project/node_modules/wink_commons/dist/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import * as API from './api';
^
SyntaxError: Unexpected token *
12 | import Alert from 'antd/lib/alert';
13 |
> 14 | import { Download } from 'some-library';
| ^
15 |
16 | import {action} from '../../../redux/actions/index';
17 | import {api, service} from '../../configs/';
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (src/javascript/members/components/member/CheckExperienceHistory.js:14:1)
so I added tranformIgnorePatterns to package.json, but it didn't work (same error)
// package.json
"jest": {
"roots": [
"<rootDir>/src"
],
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts"
],
"setupFiles": [
"react-app-polyfill/jsdom"
],
"setupFilesAfterEnv": [
"<rootDir>/src/setupTests.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
"testEnvironment": "jest-environment-jsdom-fourteen",
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"node_modules/(?!(some-library)/)",
"^.+\\.module\\.(css|sass|scss)$"
],
"modulePaths": [],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"web.js",
"js",
"web.ts",
"ts",
"web.tsx",
"tsx",
"json",
"web.jsx",
"jsx",
"node"
],
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
]
},
"babel": {
"presets": [
"react-app"
]
}
I think, jest attempt to parse some-library (this is personal library) but it failed to compile it, and I'm wondering why transformIgnorePatterns is not work.

SyntaxError: Unexpected token export while running tests in Jest with components having amcharts4

Geeting error: Unexpected token export while running tests in Jest with components having amcharts4
export { System, system } from "./.internal/core/System";
^^^^^^
SyntaxError: Unexpected token export
> 1 | import * as am4core from "#amcharts/amcharts4/core";
| ^
2 | import * as am4charts from "#amcharts/amcharts4/charts";
3 | import * as am4maps from "#amcharts/amcharts4/maps";
4 | import am4geodata_worldLow from "#amcharts/amcharts4-geodata/worldLow";
"jest": "24.9.0"
"#amcharts/amcharts4": "^4.10.19"
"typescript": "^3.9.5"
Following is jest config in the package.json file :(Using create-react-app for the project & ejected it)
"jest": {
"roots": [
"<rootDir>/src"
],
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts"
],
"setupFiles": [
"react-app-polyfill/jsdom",
"<rootDir>\\src\\__mocks__\\dom.js",
"<rootDir>\\src\\__mocks__\\reactrouter.js"
],
"setupFilesAfterEnv": [
"#testing-library/jest-dom/extend-expect"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
"testEnvironment": "jest-environment-jsdom-fourteen",
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"node_modules/(?!#amcharts/amcharts4/)",
"^.+\\.module\\.(css|sass|scss)$"
],
"modulePaths": [
"<rootDir>/src/",
"<rootDir>/node_modules/"
],
"moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/src/__mocks__/styleMock.js"
},
"moduleFileExtensions": [
"web.js",
"js",
"web.ts",
"ts",
"web.tsx",
"tsx",
"json",
"web.jsx",
"jsx",
"node"
],
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
]
}
Cause: babel-jest uses babel configuration that is loaded based on the location of the file that is going to be transformed. After ejecting create-react-app your package.json probably contains:
"babel": {
"presets": [
"react-app"
]
}
which makes import/export statements work for your files, but #amcharts/amcharts4 does not have that setting in its package.json nor does it have .babelrc and so no import/export transformation takes place.
Solution: You can update your Jest config to transform #amcharts in a more specific way:
Add relevant babel plugin: npm install -D #babel/plugin-transform-modules-commonjs
Update jest config in your package.json - redirect #amcharts transformation to custom transformer. (I also changed transformIgnorePatterns so that they work for Windows.)
"transform": {
"#amcharts[/\\\\].+\\.(js|jsx|ts|tsx)$": "<rootDir>/config/jest/babelTransformImportExport.js",
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"node_modules[/\\\\](?!#amcharts[/\\\\]amcharts4[/\\\\])",
"^.+\\.module\\.(css|sass|scss)$"
],
Create config/jest/babelTransformImportExport.js:
const babelJest = require("babel-jest");
module.exports = babelJest.createTransformer({
plugins: [require.resolve("#babel/plugin-transform-modules-commonjs")],
babelrc: false,
configFile: false,
});
Tests should be running now.
Edit: As Subrato Patnaik mentioned (using amcharts with jest), amcharts use APIs such as SVGPathElement which aren't yet available in Jest test environment (JSDOM - issue #2128). In other words, your tests won't probably work, if you're using standard mounting. But they might work if you are using e.g. enzyme and its shallow rendering.
If you don't use enzyme or it doesn't work, then as the last resort, you can try to simply define missing APIs in a minimalistic way and see whether it is sufficient:
Change setupFiles in jest config to:
"setupFiles": [
"react-app-polyfill/jsdom",
"<rootDir>/config/jest/setup.js"
],
Create config/jest/setup.js:
class SVGGraphicsElement extends SVGElement {}
class SVGGeometryElement extends SVGGraphicsElement {}
class SVGPathElement extends SVGGeometryElement {}
Object.assign(global, {
SVGGraphicsElement,
SVGGeometryElement,
SVGPathElement,
});
PS: If you are using pnpm instead of npm/yarn, then you will need to update transformIgnorePatterns to:
"node_modules[/\\\\](?!(|\\.pnpm[/\\\\]#amcharts.*node_modules[/\\\\])#amcharts[/\\\\]amcharts4[/\\\\])",
otherwise the old regexp would match (and therefore ignore) paths such as node_modules/.pnpm/#amcharts+amcharts4#4.10.21/node_modules/#amcharts/amcharts4/core.js

Solving linter error- 'shallow' is not defined no-undef

I am using JEST and Enzyme. In my eslint file I have added jest as true under env. But I get a lint error for shallow as I have included it globally. Error is- error 'shallow' is not defined no-undef
setupTests.js
//as we are accessing our application with a http://localhost prefix, we need to update our jest configuration
import { shallow, render, mount, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// React 16 Enzyme adapter
configure({ adapter: new Adapter() });
// Make Enzyme functions available in all test files without importing
global.shallow = shallow;
global.render = render;
global.mount = mount;
.eslintrc
{
parser: "babel-eslint",
"extends": ["airbnb"],
"env": {
"browser": true,
"jest": true
},
"rules": {
"max-len": [1, 200, 2, {ignoreComments: true}],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"no-underscore-dangle": [0, { "allow": [] }],
"jsx-a11y/label-has-associated-control": [
"error", {
"required": {
"every": [ "id" ]
}
}
],
"jsx-a11y/label-has-for": [
"error", {
"required": {
"every": [ "id" ]
}
}
]
}
}
app.test.js
import React from 'react';
import { LoginFormComponent } from '../../components';
describe('LoginForm', () => {
const loginform = shallow(<LoginFormComponent />);
it('renders correctly', () => {
expect(loginform).toMatchSnapshot();
});
});
package.json
"scripts": {
"dev": "webpack-dev-server --historyApiFallback true --port 8888 --content-base build/",
"test": "jest",
"lint": "eslint ./src",
"lintfix": "eslint ./src --fix"
},
"jest": {
"verbose": true,
"testURL": "http://localhost/",
"transform": {
"^.+\\.js$": "babel-jest"
},
"setupFiles": [
"./setupTests.js"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
},
The error comes in my app.test.js where I am trying to use shallow. Do I have to add something in my eslint config for enzyme the way I have made jest as true?
How about add global statement? eslint no-undef docs
/*global someFunction b:true*/
/*eslint no-undef: "error"*/
var a = someFunction();
b = 10;
or set global on .eslintrc (eslint global)
{
"globals": {
"shallow": true,
"render": true,
"mount": true
}
}
Updated .eslintrc
{
parser: "babel-eslint",
"extends": ["airbnb"],
"env": {
"browser": true,
"jest": true
},
"globals": {
"shallow": true
},
"rules": {
"max-len": [1, 200, 2, {ignoreComments: true}],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"no-underscore-dangle": [0, { "allow": [] }],
"jsx-a11y/label-has-associated-control": [
"error", {
"required": {
"every": [ "id" ]
}
}
],
"jsx-a11y/label-has-for": [
"error", {
"required": {
"every": [ "id" ]
}
}
]
}
}
Since globals are only used in test files the best practise is not to set them globally but only for the test files. That can be done by using overrides property with proper files glob:
overrides: [
{
files: "*.test.js",
globals: {
shallow: true,
render: true,
mount: true,
},
},
],
Full .eslintrc after addition in the snippet.
{
"parser": "babel-eslint",
"extends": ["airbnb"],
"env": {
"browser": true,
"jest": true
},
"rules": {
"max-len": [1, 200, 2, { "ignoreComments": true }],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"no-underscore-dangle": [0, { "allow": [] }],
"jsx-a11y/label-has-associated-control": [
"error",
{
"required": {
"every": ["id"]
}
}
],
"jsx-a11y/label-has-for": [
"error",
{
"required": {
"every": ["id"]
}
}
]
},
"overrides": [
{
"files": "*.test.js",
"globals": {
"shallow": true,
"render": true,
"mount": true
}
}
]
}

Unable to use webpack alias with Jest testing - Invariant Violation: Target container is not a DOM element

I've created a new repo that replicates this problem found here: https://github.com/davidRoussov/jest-webpack-alias
It's a React app bootstrapped using create-react-app, but it has been ejected. The error I'm getting when I run npm run test is this:
FAIL src\components\Parent.test.js
● Test suite failed to run
Invariant Violation: Target container is not a DOM element.
at invariant (node_modules/fbjs/lib/invariant.js:42:15)
at Object.<anonymous> (src/index.js:7:20)
at Object.<anonymous> (src/components/Parent.js:2:14)
at Object.<anonymous> (src/components/Parent.test.js:2:15)
at process._tickCallback (internal/process/next_tick.js:103:7)
The component being tested, Parent.js:
import React, { Component } from 'react';
import Child from '#/components/Child';
class Parent extends Component {
render() {
return (
<div>
<Child/>
</div>
);
}
}
export default Parent;
The test, Parent.test.js:
import React from 'react';
import Parent from './Parent';
import renderer from 'react-test-renderer';
it('renders correctly', () => {
const tree = renderer.create(
<Parent/>
).toJSON();
expect(tree).toMatchSnapshot();
});
For the webpack config I've only added:
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
And:
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
'#': resolve('src')
},
The Jest config:
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
"setupFiles": [
"<rootDir>/config/polyfills.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.js?(x)",
"<rootDir>/src/**/?(*.)(spec|test).js?(x)"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js|jsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"
],
"moduleDirectories": ["node_modules"],
"modulePaths": ["src"],
"moduleNameMapper": {
"^#(.*)$": "<rootDir>/src",
"^react-native$": "react-native-web"
},
"moduleFileExtensions": [
"web.js",
"js",
"json",
"web.jsx",
"jsx",
"node"
]
},
Jest does not produce errors if import Child from '#/components/Child'; is replaced with import Child from './Child';
I hope it's not too late, you forgot to substitute the captured regex groups in the path , like so:
"moduleNameMapper": {
"^#(.*)$": "<rootDir>/src/$1",
},
Link to the documentation

Jest: get undefined on import some module

I'm making some test to redux with jest but I got sucked because Auth module appears as undefined.
import { auth as Auth } from 'Services/firebase'
export const signIn = (email, password) => {
console.log(Auth) // It get's undefined
return dispatch => {
dispatch(signInInit())
Auth.signIn(email, password, (user) => {
dispatch(push('/'))
return dispatch(signInSuccess(user))
}, (error) => {
return dispatch(signInError(error))
})
}
}
This is the jest configuration:
"jest": {
"collectCoverage": true,
"coverageDirectory": "<rootDir>/coverage",
"verbose": true,
"coveragePathIgnorePatterns": [
"<rootDir>/node_modules"
],
"modulePaths": [
"<rootDir>/src"
],
"moduleFileExtensions": [
"js"
],
"moduleDirectories": [
"node_modules",
"src"
],
"modulePathIgnorePatterns": [
"<rootDir>/public"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|svg|ttf|woff|woff2)$": "<rootDir>/src/components/__mocks__/fileTransformer.js",
"^Components(.*)$": "<rootDir>/src/components",
"^Data(.*)$": "<rootDir>/src/data",
"^Hocs(.*)$": "<rootDir>/src/hocs",
"^Scenes(.*)$": "<rootDir>/src/scenes",
"^Services(.*)$": "<rootDir>/src/services",
"^Styles(.*)$": "<rootDir>/src/styles"
}
Really can't understand why this is happening, well any clue will be very welcome.

Resources