Cannot setup `babel-plugin-rewire` for React tests - reactjs

I'm trying to setup babel-plugin-rewire so that in my Jest tests I can generate a small test snapshot for a wrapper component instead of having a huge one with all the child components in it.
The settings seem all to be correct but I get the following error:
ReferenceError: Wrapper is not defined
at _get_original__ (app\components\Wrapper\tests\index.te
st.js:22:2168)
at _get__ (app\components\Wrapper\tests\index.test.js:22:
1912)
at Suite.<anonymous> (app\components\Wrapper\tests\index.
test.js:8:82)
at Object.<anonymous> (app\components\Wrapper\tests\index
.test.js:6:1)
at process._tickCallback (internal\process\next_tick.js:103:7)
package.json
"babel": {
"presets": [
[
"latest",
{
"es2015": {
"modules": false
}
}
],
"react"
],
"env": {
"test": {
"plugins": [
"babel-plugin-rewire",
"transform-es2015-modules-commonjs",
"dynamic-import-node"
]
...
"devDependencies": {
...
"babel-plugin-rewire": "^1.1.0",
webpack.base.babel.js
(common webpack configuration -same in webpack.basetest.babel.js)
module: {
loaders: [{
test: /\.js$/, // Transform all .js files required somewhere with Babel
loader: 'babel-loader?plugins=babel-plugin-rewire',
exclude: /node_modules/,
query: options.babelQuery,
},
My Test
for the Wrapper component that contains a Header child component:
import React from 'react';
import { shallow } from 'enzyme';
import Wrapper from '../index';
describe('<Wrapper />', () => {
console.log('Debugging >>> ' + JSON.stringify(Wrapper)); // Wrapper is defined but blows up here ##
// beforeEach(() => {
// Wrapper.__Rewire__('Header', class extends React.Component {
// render(){ return <div {...this.props}>TEST only the wrapper!!</div> }
// });
// })
// it('renders correctly', () => {
// const tree = shallow( <Wrapper myProps={testData.myProps} /> );
// expect(tree.html()).toMatchSnapshot();
// });
...
});
Thanks
UPDATE:
If I comment out in Wrapper the JSX where Header is used (even leaving the import for Header as it is) Wrapper.__Rewire__ becomes defined and therefore the beforeEach doesn't throw errors anymore.

Related

Jest encountered an unexpected token SyntaxError: Cannot use import statement outside a module

I am trying to write a test for a react component, the component is a part of an application that uses FIrebase, Please see the test code.
/** #jest-environment jsdom */
/* eslint-disable react/display-name */
import {render} from '#testing-library/react';
import WorkForm from '../../components/WorkFlow/WorkForm';
jest.mock('../../UI/PwFormButtons', () => ({
PWSaveButton: () => <div data-testId="saveButton">Mocked PWSaveButton</div>,
}));
test("If work from render show save button", () => {
const {getByTestId} = render(<WorkForm
isNew={true}
workflowData={{}}
setShowFlowContainer={() => {}}
newWorkFlow={() => {}}
user={{}}
setShowModal={() => {}}
updateWorkFlow={() => {}}
/>);
expect(getByTestId("saveButton")).toBeInTheDocument();
})
I keep getting a Firebase error, please see below.
/Users/rayonhunte/Documents/GitHub/alert-manager/packages/config-ui/node_modules/firebase/app/dist/index.esm.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { registerVersion } from '#firebase/app';
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | import { initializeApp } from 'firebase/app';
| ^
2 | import {getFirestore} from 'firebase/firestore';
3 | import {getAuth} from 'firebase/auth';
4 | import { getStorage } from 'firebase/storage';
I was also getting that error with react form hooks but after the lib update, it was resolved, that's not working with Firebase.
I am using react testing lib and Jest for testing and this is a NextJS and TypeScript application.
Any help would be appreciated.
Jest config file
module.exports = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
};
babel file
{
"env": {
"development": {
"presets": [
"next/babel"
]
},
"production": {
"presets": [
"next/babel"
]
},
"test": {
"presets": [
"#babel/env",
"#babel/react",
"#babel/preset-typescript",
],
"plugins": [
[
"#babel/plugin-transform-modules-commonjs",
{
"allowTopLevelThis": true
}
]
]
}
}
}

Jest import issue for react js app with custom imports prefix for workerize-loader

I am facing an issue with setting up tests for react app with Jest.
I am using workerize-loader! library to import modules into webworkers.
On tests that use the import worker from workerize-loader!./path/to/file are barking on import of the test. I tried with a custom loader, in the jest.condig.js file but that did not work. When I run the default testing script provided by the react app setup it cannot find the imports in the files. But the code when it runs works alright.
I need help with importing the modules inside of the test suite of jest
Basic test
import React from "react";
import {cleanup, fireEvent, render } from "#testing-library/react";
import App from "./App";);
afterEach(cleanup);
test("basic test", () => {
const { container } = render(<App />);
const linkElement = container.firstChild;
expect(linkElement).toBeInTheDocument();
});
Configuration
jest.config.js
module.exports = {
preset: 'ts-jest',
verbose: true,
testEnvironmentOptions: {
url: 'http://localhost/'
},
testEnvironment: 'jsdom',
transform: {
'workerize-loader(\\?.*)?!(.*)': '<rootDir>/workerize-jest.js',
'^.+\\.(js|jsx)$': 'babel-jest',
'^.+\\.(ts|tsx)?$': 'ts-jest',
},
unmockedModulePathPatterns: [
'node_modules',
],
moduleNameMapper: {
'workerize-loader(\\?.*)?!(.*)': 'identity-obj-proxy'
},
};
.babelrc
{
"plugins": [
"syntax-dynamic-import",
"#babel/transform-runtime"
],
"presets": [
[
"es2015",
{
"modules": true
}
],
"react",
"stage-0"
],
"env": {
"start": {
"presets": [
"react-hmre"
]
},
"test": {
"presets": [
[
"es2015",
{
"modules": true
}
],
"react",
"stage-0"
]
}
}
}
Error message on react-scripts test
Cannot find module 'workerize-loader!./workers/css.worker'
In file
> 2 | import worker from 'workerize-loader!./workers/css.worker';
workerize-jest.js
module.exports = {
process(src, filename) {
return `
async function asyncify() { return this.apply(null, arguments); }
module.exports = function() {
const w = require(${JSON.stringify(filename.replace(/^.+!/, ''))});
const m = {};
for (let i in w) m[i] = asyncify.bind(w[i]);
return m;
};
`;
}
};

Test with enzyme: Unexpected token in mount()

I'm trying to make enzyme tests in react.
I make this simple test that mount a import component and check the states:
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import WorkOutForm from './workOutForm';
describe('<WorkOutForm>', () => {
describe('workoutForm component', () => {
it('should start a new workoutForm with empty state', () => {
const component = mount(<WorkOutForm />);
expect(component).toEqual({})
expect(component.state().tempoGasto).toEqual(null)
expect(component.state().tipoAtividade).toEqual(null)
expect(component.state().data).toEqual(null)
component.unmount()
})
})
})
But when i run npm run test i get:
Jest encountered an unexpected token const component =
mount()
I try to make like the doc but i can't see my error.
Obs: i follow the jest getting started and i run:
npm i --save babel-jest #babel/core #babel/preset-env --dev
i added a babel.config.js file in the root with this content:
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
and this is my webpack:
module: {
loaders: [{
test: /.js[x]?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react', '#babel/preset-env'],
plugins: ['transform-object-rest-spread']
}
}, {
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
}, {
test: /\.woff|.woff2|.ttf|.eot|.svg*.*$/,
loader: 'file'
},
]
}
Please try adding the following in your package.json jest config:
"transform": {
"\\.js$": "<rootDir>/node_modules/babel-jest"
},
Make sure you install the babel-jest package first

React App with Jest - Jest encountered an unexpected token

I'm trying to test a component using the react-test-renderer library and i'm getting this error.
Header.test.js:
import ReactShallowRenderer from "react-test-renderer/shallow";
import React from "react";
import Header from "../../components/Header/Header";
test("should render Header correctly", () => {
const renderer = new ReactShallowRenderer();
renderer.render(<Header />);
// Returning the render output of the jsx
console.log(renderer.getRenderOutput());
});
That's my jest config:
"jest": {
"verbose": true,
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.(css|scss|less)$": "jest-css-modules"
}
My babelrc:
{
"env": {
"development": {
"plugins": ["transform-es2015-modules-commonjs"]
},
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}

"ReferenceError: waitForElement is not defined" when testing react.js

I am testing with Jest and react-testing-library a component that is calling an async function. When I run the test I get the error ReferenceError: waitForElement is not defined
Following this instructions I have tried:
without the useBuiltinsoption in .babelrc, including #babel/polyfill at the top of the app.test.jsx file, , and without #babel/polyfill in the entry array in webpack.config.js. I get the error ReferenceError: waitForElement is not defined from the test run but the application compiles succesfully
with useBuiltIns: 'entry', including #babel/polyfill at the top of the app.test.jsx file, and without #babel/polyfill in the entry array in webpack.config.js . I get Cannot find module 'core-js/modules/es6.array.every' from 'app.test.jsx' and the application fails to compile.
with useBuiltIns: 'entry', NOT including #babel/polyfill at the top of the app.test.jsx file, and WITH #babel/polyfill in the entry array in webpack.config.js. I get the error ReferenceError: waitForElement is not defined from the test run and the application fails to compile.
Here is the code from case 1:
imports in app.test.jsx
import '#babel/polyfill';
import React from 'react';
import { render, fireEvent, cleanup } from 'react-testing-library';
import AppContainer from '../components/AppContainer';
test in app.test.jsx
test('State change', async () => {
const { debug, getByLabelText, getByTestId, getByText } = render(<AppContainer />);
fireEvent.change(getByLabelText('testfield'), { target: { value: 'Hello' } });
fireEvent.click(getByTestId('button'));
await waitForElement(() => getByText('return value'));
debug();
});
webpack.config.js
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
},
],
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html',
}),
],
};
.babelrc
{
"presets": ["#babel/preset-env", "#babel/preset-react"],
"plugins": [
[
"#babel/plugin-proposal-class-properties",
{
"loose": true
}
]
]
}
I am expecting the waitForElement function to be awaiting for the "return value" text to appear in a second textfield, and then the debug() function to print the page html code. Instead I get the above mentioned errors.
You have to import waitForElement from react-testing-library:
import { render, waitForElement } from 'react-testing-library'
There's no need to install dom-testing-library because RTL depends on it already.
Ok, I solved the problem. I was missing the dom-testing-library dependency.
Here is the working solution.
Install dom-testing library: npm install --save-dev dom-testing-library.
In app.test.jsximport waitForElement and #babel/polyfill:
import '#babel/polyfill';
import { waitForElement } from 'dom-testing-library';
The rest of the code is as in case 1 above.

Resources