Using React stroybook as Jest test - reactjs

I have a React storybook and what to use it as my test cases
I have a "loader.js" that import all the stories
import sourceBasic from 'raw-loader!./Basics/foo.js?sourceMap';
import Basic from './Basics/foo';
const tree = {
Basics:[
{
title:'Creating and applying a style',
source:sourceBasic, element:Basic
},
{ .... }
],
[ .... ],
....
}
export default tree
I use the raw-loader and sourceMap to show the source with the element in storybook
This works great.
My problem is when I try to import with Jest
FAIL ./index.test.js
● Test suite failed to run
Cannot find module 'raw-loader!./Basics/foo.js?sourceMap' from 'load.js'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:179:17)
at Object.<anonymous> (example/stories/load.js:2:34)
The test file
import React from 'react';
import renderer from 'react-test-renderer';
import load from './example/stories/load'
for(const groupName in load ){
const groupArray = load[groupName];
describe(groupName, () => {
for(const item of groupArray ){
test(item.title, () => {
const elem = renderer.create(item.element);
expect(elem.toJSON()).toMatchSnapshot();
}) // END test
} // END for
}) // END describe
} // END for
Thanks for your help
UPDATE
The update and working stroybook as test is implemented on the project react-outline
You can clone it(react-outline), npm install and then npm test to see it in action.
Here is the output on travis :)

If you don't care about the raw-source and want to mock it. You can use the moduleNameMapper under your Jest setting within your package.json.
This will let you intercept all require/import based on a regex match.
Add to your package.json:
...
"dependencies": {
...
},
...
"jest": {
"globals": {
"__TEST__": true
},
"moduleNameMapper": {
"\\.(css|jpg|png)$": "<rootDir>/empty-module.js",
"^raw-loader": "<rootDir>/empty-module.js"
},
"testPathIgnorePatterns": [
"/node_modules/"
],
"verbose": true
}
}

Related

Why do i get this error, Cannot use import statement outside a module

so im trying to make a test for my component a simple test that shows if the component was rendered
test('Should render the movie info', () => {
renderWithContext(<MovieInfo movie={mockMovies[0]} />);
expect(screen.getByText('Terrifier 2')).toBeInTheDocument();
});
but i get this error:
SyntaxError: Cannot use import statement outside a module
the problem seems to have be about axios some how because it happens when trying to import axios.
> 2 | import axios from 'axios';
| ^
i have a jest.config.js file like this.
const { compilerOptions } = require('./tsconfig.json');
const { pathsToModuleNameMapper } = require('ts-jest');
const { default: tsjPreset } = require('ts-jest');
module.exports = {
transform: {
...tsjPreset.transform,
'+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2|pdf)$':
'jest-transform-stub',
'^.+\\.ts?$': 'ts-jest',
},
moduleDirectories: ['src', 'node_modules'],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'],
transformIgnorePatterns: ['node_modules/(?!(axios)/)'],
};
and i have installed ts-jest, #types/jest and jest-transform-stub as dependencies
i have looked on the internet and this seems to be about some jest config that im doing wrong but nothing i do works
I solved this by adding this to my package.json i think its a hacky way of doing it but is the only way it worked for me.
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\"",

React + Rollup - 'r is not defined'

Final edit: Thanks everyone for your help, however ultimately it was easier for me to transition to Webpack and Storybook. I'm leaving my original question untouched just in case it helps anyone in the future. Also, if anyone stumbles upon any issues configuring these (like I did), the link to the GitHub repo is below.
I'm creating a small lib using React and Rollup and trying to test locally with a CRA-powered project, however I'm facing this issue when importing a component from my library. I don't know if the problem is in my configuration or if this is a bug.
Uncaught ReferenceError: r is not defined
at Object.../dist/bundle.js (index.jsx:44)
Imported "Message" component where the error is happening
import React, { useEffect, useState } from 'react';
import { string, number, arrayOf } from 'prop-types';
import Container from './Container';
function Message({
text,
type,
timeout,
classes,
}) {
const [show, setShow] = useState(false);
useEffect(() => {
if (text && type) {
setShow(true);
setTimeout(() => setShow(false), timeout);
}
}, [text, type]);
const date = new Date();
return (
<Container
id={`message-${date}`}
key={`message-${date}`}
className={`${type}${classes?.map((className) => ` ${className}`)}`}
>
{
show
? (
<p>{text}</p>
) : ''
}
</Container>
);
}
// The source map points to this line when the error happens, but it still happens if I remove it and don't use prop-types, instead pointing to the closing bracket of the 'Message' function
Message.defaultProps = {
timeout: 3000,
classes: [],
};
Message.propTypes = {
text: string.isRequired,
type: string.isRequired,
timeout: number,
classes: arrayOf(string),
};
export default Message;
Test component where it's being used:
import React from 'react';
import { Message } from 'pure-ui';
import { getRandomArrayElement } from 'formatadores';
const types = [
'warning',
'error',
'success',
];
const texts = [
'This is a test',
'I will randomly display a message every so often, so stay sharp',
'Yet another test message',
];
const timeouts = [
5000,
3000,
1000,
];
function App() {
return (
<div>
<h1>Running...</h1>
<Message
type={getRandomArrayElement(types)}
text={getRandomArrayElement(texts)}
timeout={getRandomArrayElement(timeouts)}
/>
</div>
);
}
export default App;
rollup config file:
import babel from '#rollup/plugin-babel';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import external from 'rollup-plugin-peer-deps-external';
import React from 'react';
import propTypes from 'prop-types';
const extensions = ['.js', '.jsx', '.ts', '.tsx'];
export default [
{
input: 'src/index.js',
watch: true,
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: true,
globals: {
react: 'React',
'react-dom': 'ReactDOM',
'prop-types': 'PropTypes',
},
},
plugins: [
external(),
babel({
exclude: 'node_modules/**',
presets: [
'#babel/preset-env',
['#babel/preset-react', { runtime: 'automatic' }],
],
}),
resolve({ extensions }),
commonjs({
namedExports: {
react: Object.keys(React),
'react/jsx-runtime': ['jsx', 'jsxs', 'Fragment'],
'react/jsx-dev-runtime': ['jsx', 'jsxs', 'jsxDEV'],
'prop-types': Object.keys(propTypes),
},
}),
],
external: [
'react',
'react-dom',
'prop-types',
],
},
];
I tried changing the namedExports (and also removing them), linking React from the lib to use the same version from the CRA project (in the lib both React and React DOM are listed as peer dependencies), but I always end with the same result. Is there something wrong with my config? This is the first time I use Rollup for creating a React component lib, so maybe there's something I missed
If the above info is insufficient, here's the GitHub repo
Thanks in advance
Edit: I just saw that I forgot to import React in my test project, however after doing so the results were the same, editing my original question just to fix that.
Update 1: I changed several configurations (changed deprecated rollup-plugins to their currently maintained versions, added globals to the output part of rollup.config.js, added namedExports to commonjs plugin configuration, added an external section specifying react, react-dom and prop-types), but now what I'm getting is a React is not defined error, updating the question with the new config

SyntaxError: Cannot use import statement outside a module in JEST LWC

I am trying to test my first lightning web component using visual studio code as my IDE. As instructed I installed Node.js, npm and jest dependency. But I am getting this error
Error Image
when trying to run the below code
driver_Registration.html
<template>
<div class="slds-m-around_medium">
<p>Hello, {person}!</p>
</div>
</template>
driver_Registration.js
import { LightningElement, api } from 'lwc';
export default class Driver_Registration extends LightningElement {
#api person = 'World';
}
hello.test.js in tests folder
// hello.test.js
import { createElement } from 'lwc';
import Hello from 'c/driver_Registration';
describe('c-hello', () => {
afterEach(() => {
// The jsdom instance is shared across test cases in a single file so reset the DOM
while (document.body.firstChild) {
document.body.removeChild(document.body.firstChild);
}
});
it('displays greeting', () => {
// Create element
const element = createElement('c-hello', {
is: Hello
});
document.body.appendChild(element);
// Verify displayed greeting
const pTag = element.shadowRoot.querySelector('p');
expect(pTag.textContent).toEqual('Hello, World!');
});
});
Any input is appreciated
tsconfig.json
"compilerOptions": {
...
"allowJs": true
}
jest config
add
"transformIgnorePatterns": [
"node_modules/(?!lwc)"
]
remove
"testPathIgnorePatterns": [
"node_modules"
],
If that's not enough =>
jest --clearCache
Hope this helps

make sure to include the file in Jest's transformIgnorePatterns as wel

I'm trying to make jest/enzyme tests in react
I have this test:
import React from 'react';
import { shallow } from 'enzyme';
import { mount } from 'enzyme'
import WorkOutForm from './workOutForm';
describe('WorkOutForm', () => {
it('should start a new workoutForm with empty state', () => {
const component = mount(<WorkOutForm/>)
expect(component).toMatchSnapshot();
});
})
but when i do a npm run test i receive:
src/workout/workOut.test.js ● Test suite failed to run
babel-jest: Babel ignores src/workout/workOutForm.jsx - make sure to include the file in Jest's transformIgnorePatterns as well.
I try to add this file in the package.json:
"jest": {
"transformIgnorePatterns": [
"src/workout/workOutForm.jsx"
]
}
but i'm receiving the same error.
where i have to put this?
where i have to put this?
You should not ignore jsx source files. What you need to do is convert your jsx to js using babel.
You need to use babel-preset-react. This will automatically add #babel/plugin-transform-react-jsx for the transformation.
Then put this in your .babelrc
{
"presets": ["#babel/preset-react"]
}
I have already this error and i fixed changing the code from:
"ignore": [
"./test",
"./src/assets",
"./src/stories",
"./src/.storybook"
]
To this:
"ignore": [
"./src/assets",
"./src/stories",
"./src/.storybook"
]
I remove my test folder from the .babelrc ignore prop and its works for me!

Test suite failed to run Your test suite must contain at least one test.

Im getting this error
Test suite failed to run
Your test suite must contain at least one test.
at node_modules/jest-cli/build/test_scheduler.js:108:22
with jest configuration
"jest": {
"transform": {
".*": "./tests/preprocessor.js"
},
"modulePaths": [
"src"
],
"testPathIgnorePatterns": [
"/node_modules/",
"/vendor"
],
"testRegex": "\\.spec\\.js"
}
any help how can i solve this
im i missing something
thanks in advance
carlos vieira
This issue is happening because you have created the test file, but not included any of the tests.
example:- The below unit test consists of only describe part not covering any tests (commented as of now)
import { mount } from "enzyme";
import React from "react";
import Privileges from "./privileges";
describe("Privileges Component ", () => {
//const wrapper = mount(<Privileges />).find(".privileges-container");
// it("should render in DOM", () => {
// expect(wrapper.length).toEqual(1);
// });
});

Resources