Optional chaining issues when running test with jest - reactjs

I am trying to run a test with Jest and I'm currently using jsx and tsx (changing from js to ts) in my react app but when I run my tests, all jsx tests are successful except those in tsx with optional blocking. I always get an error Unexpected token on my input that looks like
...
<Input
value={parent?.child}
...
this is my jest config
{
"verbose": true,
"roots": [
"<rootDir>/app"
],
"setupFiles": [
"./config/webpack/jest/config.js"
],
"moduleNameMapper": {
"^components(.*)": "<rootDir>/app/javascript/components$1",
"^utils(.*)": "<rootDir>/app/javascript/utils$1",
"^types(.*)": "<rootDir>/app/javascript/types$1",
"\\.(css|pcss|scss)$": "<rootDir>/spec/__mocks__/styleMock.js",
"\\.(gif|ttf|eot|svg|png)$": "<rootDir>/spec/__mocks__/fileMock.js"
},
"snapshotSerializers": [
"<rootDir>/node_modules/enzyme-to-json/serializer"
],
"testRegex": "(/__tests__/.*|\\.(test))\\.(ts|tsx|js|jsx)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx"
],
"transform": {
"\\.[jt]sx?$": "babel-jest"
}
}
What could be the problem how can I work with optional chaining and jest?

For me the issue was that in my tsconfig.json, I was using "lib": ["ES2020"], which was in conflict with my node version. Changing node version to v14 solved the issue.
Here you'll find a link with lib targets with node versions:
https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping

change tsconfig.json using "lib": ["ES2020"], "target": "ES2020", also worked for me. Tks

Related

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

React CRA with typescript not working with eslint

I am trying to integrate linting into an app created using CRA which uses typescript.
Steps to reproduce on terminal
create-react-app my-app --typescript
./node_modules/.bin/eslint --init
select : To check syntax, find problems, and enforce code style
select : JavaScript modules (import/export)
select : React
y for does your project use typescript
select : Browser
Popular style guide used is airbnb
My .eslintrc json file looks like the following
{
"env": {
"browser": true,
"es6": true
},
"extends": [
"airbnb"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "#typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"react",
"#typescript-eslint"
],
"rules": {
"semi":"warn"
}
}
I usually check if the lint works by removing semi colon to see if vs code highlights.
However it does not happen.
Adding the following snippet to settings.json on VS code works.
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
There are two types of setting ESLint in React CRA.
Local ESLint (Only affect the Editor such as VSCode)
ESLint when Compiling (When running yarn start and saving file)
As there are too much (not needed) information on the internet, I created an article about this in a much simpler way in here.

Bable Not Compiling JSX for Jest/React

Im trying to setup unit testing with JEST for React.
My current set up is inside Package.json:
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest"
},
"moduleFileExtensions": [
"js",
"json",
"jsx"
]
}
And then inside .babelrc I have:
{
"plugins": ["syntax-dynamic-import", "transform-runtime"],
"presets": [
[
"es2015",
{
"modules": false
}
],
"react"
],
"env": {
"test": {
"presets": ["es2015", "react"]
}
}
}
I then run npm test, and it then starts run jest. However, it will error/Fail with :
Test suite failed to run with a error at
componentDidMount=()=>{
| ^
25 | window.addEventListener('scroll', this.handleScroll)
26 | }
This is telling me that while the test enters the correct Component, it eventually stops at some es2015 syntax.
Do I have something set up wrong? It seems that babelrc is NOT actually transpiling before JEST tries to run its test? Is this correct?
My .babelrc is at the root level.
You're missing the transform-class-properties babel plugin. Static class properties are not part of ES2015 and need a separate plugin.

react storybook jest snapshots leads to an error Cannot find module '../../package' from 'node.js'

I want to combine storybooks and jest snapshot testing, but I don't get it working.
As soon as I follow the doc and add the Snapshot.test.js, it leads to following error, when I run npm test.
FAIL ./Storyshots.test.js Test suite failed to run
Cannot find module '../../package' from 'node.js'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
at Object.<anonymous> (node_modules/babel-core/lib/api/node.js:60:16)
anyone has a clue / hint if this is a failure of implementation or a bug?
thnx a lot!
this is my jest configuration, it my gives a hint?
"jest": {
"rootDir": "",
"transform": {
".*": "<rootDir>/node_modules/babel-jest"
},
"moduleFileExtensions": [
"js",
"jsx"
],
"collectCoverage": false,
"collectCoverageFrom": [
"**/*.{js,jsx}",
"!**/node_modules/**",
"!**/vendor/**"
],
"coverageDirectory": "<rootDir>/coverage",
"setupTestFrameworkScriptFile": "<rootDir>/jestSetup.js",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"moment",
"jasmine-expect-jsx",
"fbjs",
"enzyme",
"expect",
"cheerio",
"htmlparser2",
"lodash",
"domhandler",
"object.assign",
"define-properties",
"function-bind",
"object-keys",
"object.values",
"es-abstract"
]
},
I had this same problem and my solution was add "json" into "moduleFileExtensions", just like this:
...
"moduleFileExtensions": [
"js",
"jsx",
"json"
],
...
Seems like the file 'package' was not a js[x] file, but a json one, and jest refused to load it.

classnames_1.default is not a function when testing with Jest

I am facing issue with running test cases on Jest when classnames ( https://www.npmjs.com/package/classnames ) library is being used :
It throws error : classnames_1.default is not a function
It is working with webpack on website itself.. so i don't want to change import.
I have an option to mock classnames for test to provide similar behaviour. Is there any other way to solve this issue ?
Has anyone faced this issue ?
Here is my jest configuration in package.json :
"jest": {
"globals": {
"API_HOST": "",
"DEV": false
},
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/XXX-framework/jestTypeScriptPreProcessor.js"
},
"testRegex": "(/tests/.*|\.(test|spec))\.(js|jsx|ts|tsx)$",
"transformIgnorePatterns": [],
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"automock": false,
"clearMocks": true,
"resetMocks": true,
"coverageThreshold": {
"global": {
"branches": 50,
"functions": 50,
"lines": 50,
"statements": 50
}
},
"modulePaths": [
"<rootDir>/src",
"<rootDir>/node_modules/XXX-framework/src"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react/",
"<rootDir>/node_modules/react-dom/",
"<rootDir>/node_modules/react-addons-test-utils/",
"<rootDir>/node_modules/enzyme/",
"<rootDir>/node_modules/XXX-framework/"
]
}
Thanks
You are probably using css-loader, so it works with Webpack. The problem is that Jest doesn't load your CSS files with css-loader and it's your responsibility to tell Jest how to load CSS files. One way to do that is using identity-obj-proxy.
Do npm i -D identity-obj-proxy (or use yarn to install if you like)
and add this config to your Jest config file
"moduleNameMapper": {
"^.+\\.css$": "identity-obj-proxy"
}
You can find more detail in this document.

Resources