I've got an issue with react-testing-library with my React project on TypeScript.
I've been searching on many websites an answer, checking tutorials but I'm really stuck and can't find the answer, changing some configurations on babel.config.js, tsconfig.json and jest.config.js, installing new packages (not sure if I had to install @types for testing-library for example) but I'm not expert with all of this and I'm lost.
I've tried an easy test and it says :
Unexpected token, expected "," (11:47)
9 | describe('Test SectionTitle', () => {
10 | test('renders message', () => {
> 11 | const { getByText } = render(<SectionTitle tag="h1">Mon titre</SectionTitle>)
| ^
12 |
13 | expect(getByText('Mon titre')).toBeInTheDocument()
14 | })
The structure of my project is as belows :
.
├── public # Where build files are (shoudn't be this way)
├── src # Source files (alternatively `lib` or `app`)
│ ├── assets # All images
│ ├── components # All the components
│ │ ├── component.spec.ts # Test files
│ │ ├── component.styled.ts # Style of the component with styled-components
│ │ ├── component.tsx # Component file
│ │ └── index.ts # Choose what to export
│ ├── routes # All routes with react-router-dom
│ ├── screens # All screens
│ │ ├── screen.spec.ts # Test files
│ │ ├── screen.styled.ts # Style of the screen with styled-components
│ │ ├── screen.meta.tsx # Meta tag of the screen with react-helmet
│ │ ├── screen.tsx # Screen file
│ │ └── index.ts # Choose what to export
│ ├── sitemap # Sitemap generator (issue about missing some parameters, changefreq, priority, lastmod etc.)[https://github.com/kuflash/react-router-sitemap/issues/39]
│ ├── style # Helpers, utils, variables CSS, global style etc
│ ├── index.tsx # Index file
│ ├── setupTests.ts # Packages to be imported for tests
└── README.md
└── webpack.config.js # Config of webpack
└── babel.config.js # Config of babel
└── jest.config.js # Config of jest
└── tsconfig.json # Config for TypeScript like imported paths with '@'
└── custom.d.ts # Adding Custom Type Definitions
└── .prettierrc # Rules for prettier
└── .prettierignore # Files to be ignored for prettier
└── .gitignore # Files to be ignored for git
└── package.json # List of packages and commands to run with yarn
└── yarn.lock # Packages in the node_modules folder
Here's my package.json dependencies and scripts :
{
"dependencies": {
"framer-motion": "^1.11.0",
"react": "^16.13.1",
"react-cookie-consent": "^5.0.1",
"react-dom": "^16.13.1",
"react-ga": "^3.0.0",
"react-helmet": "^6.0.0",
"react-router-dom": "^5.1.2",
"styled-components": "^5.1.0"
},
"scripts": {
"prebuild": "yarn run sitemap",
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development",
"sitemap": "babel-node src/sitemap/sitemap-builder.js",
"test": "jest -c jest.config.js --watch"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"./src/**/*.{ts,tsx}": [
"prettier --write ."
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.6",
"@babel/node": "^7.10.1",
"@babel/plugin-transform-typescript": "^7.10.1",
"@babel/preset-env": "^7.9.6",
"@babel/preset-react": "^7.10.1",
"@testing-library/jest-dom": "^5.11.0",
"@testing-library/react": "^10.4.3",
"@types/jest": "^26.0.3",
"@types/node": "^14.0.14",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/react-helmet": "^6.0.0",
"@types/react-router-dom": "^5.1.5",
"@types/styled-components": "^5.1.0",
"@types/testing-library__jest-dom": "^5.9.1",
"@types/testing-library__react": "^10.2.0",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.3",
"file-loader": "^6.0.0",
"husky": "^4.2.5",
"jest": "^26.1.0",
"lint-staged": "^10.2.2",
"prettier": "^2.0.5",
"react-router-sitemap": "^1.2.0",
"source-map-loader": "^0.2.4",
"style-loader": "^1.2.1",
"ts-jest": "^26.1.1",
"ts-loader": "^7.0.3",
"tsconfig-paths-webpack-plugin": "^3.2.0",
"typescript": "~3.7.2",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.11.0"
}
}
Here's my jest.config.js :
module.export = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
transform: {
"^.+\\.tsx?$": "ts-jest"
},
roots: ['<rootDir>/src'],
testMatch: ['<rootDir>/src/**/>(*.)spec.{ts, tsx}'], // finds test
moduleFileExtensions: ['ts', 'tsx', 'json', 'node'],
testPathIgnorePatterns: ['/node_modules/', '/public/'],
setupFilesAfterEnv: '<rootDir>/src/setupTests.ts'
};
Here is my setupTests.ts :
import '@testing-library/jest-dom/extend-expect'
import '@testing-library/react/cleanup-after-each'
This is my tsconfig.json :
{
"compilerOptions": {
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"target": "es5",
"module": "commonjs",
"rootDir": "src",
"outDir": "public",
"jsx": "react",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": "src",
"paths": {
"@assets/*": [
"assets/*"
],
"@components/*": [
"components/*"
],
"@routes/*": [
"routes/*"
],
"@screens/*": [
"screens/*"
],
"@style/*": [
"style/*"
]
}
},
"include": [
"src",
"custom.d.ts"
]
}
This is my babel.config.js :
module.exports = {
presets: ["@babel/preset-env", "@babel/preset-react"],
plugins: ["@babel/plugin-transform-typescript"]
};
This is my webpack.config.js :
const path = require("path");
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
resolve: {
extensions: [".tsx", ".ts", ".js"],
plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })]
},
devServer: {
contentBase: path.join(__dirname, "public"),
compress: true,
port: 3000,
historyApiFallback: true,
publicPath: '/'
},
entry: path.resolve(__dirname, "src", "index.tsx"),
output: {
path: path.resolve(__dirname, "public"),
filename: "bundle.js",
publicPath: '/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: ["babel-loader"]
},
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [{ loader: "ts-loader" }]
},
{
test: /\.css$/,
use: [{ loader: "style-loader" }, { loader: "css-loader" }]
},
{
test: /\.(png|svg|jpg|gif)$/i,
use: ["file-loader"]
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
}
]
}
};
The component SectionTitle.tsx :
import React from 'react'
import SectionTitleWrapper from './SectionTitle.styled'
interface IProps {
children: JSX.Element[] | JSX.Element | string
tag: 'h1' | 'h2'
}
const SectionTitle = (props: IProps) => <SectionTitleWrapper as={props.tag}>{props.children}</SectionTitleWrapper>
export default SectionTitle
And the test SectionTitle.spec.tsx :
import React from 'react'
import { render, cleanup } from '@testing-library/react'
import SectionTitle from './SectionTitle'
afterEach(cleanup)
describe('Test SectionTitle', () => {
test('renders message', () => {
const { getByText } = render(<SectionTitle tag="h1">Mon titre</SectionTitle>)
expect(getByText('Mon titre')).toBeInTheDocument()
})
})
To summarize, the website is working, the build is working too but not the tests :/ Thanks in advance for helping me !