Remix
This example demonstrates how to use jest-preview
with Remix
, bootstrapped using create-remix
(without using any built-in templates/stacks).
🚧 This example only demonstrates the simplest use of CSS in a Remix app (global stylesheet). Remix supports many different ways of styling. Example of more complex ways to style is coming.
You can see the full example at https://github.com/nvh95/jest-preview/tree/main/examples/remix
Install Jest
You have to manually install Jest in your Remix app.
First, install jest
itself. If you are using jest
version 28 or later, you must install jest-environment-jsdom
too (reference).
npm install --save-dev jest jest-environment-jsdom
Install SWC
npm install --save-dev @swc/core @swc/jest
Config SWC inside .swcrc
{
"jsc": {
"target": "es2017",
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": false,
"dynamicImport": false
},
"transform": {
"react": {
"pragma": "React.createElement",
"pragmaFrag": "React.Fragment",
"throwIfNamespace": true,
"development": false,
"useBuiltins": false,
"runtime": "automatic"
},
"hidden": {
"jest": true
}
}
},
"module": {
"type": "commonjs",
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
}
}
Next, install your favorite testing libraries. This example uses react-testing-library
, at version 12 specifically (version 13 wouldn't work). Optionally, you can install its companion jest-dom
package to add some useful matchers to Jest.
npm install --save-dev @testing-library/react@12 @testing-library/jest-dom
Install & configure Jest Preview
Install Jest Preview
npm install --save-dev jest-preview
Enable Jest Preview inside jest.config.js
. The config options are largely up to you, but remember to remove/add the highlighted options as followed so Jest Preview could work properly.
module.exports = {
collectCoverageFrom: [
'**/*.{js,jsx,ts,tsx}',
'!**/*.d.ts',
'!**/node_modules/**',
],
moduleNameMapper: {
// Handle absolute imports in Remix
'~/(.*)': '<rootDir>/app/$1',
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testPathIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>/.cache/',
'<rootDir>/build/',
],
testEnvironment: 'jsdom',
transform: {
// Use @swc/jest to transpile tests
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
'^.+\\.(js|jsx|ts|tsx)$': '@swc/jest',
'^.+\\.(css|scss|sass|less)$': 'jest-preview/transforms/css',
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)':
'jest-preview/transforms/file',
},
transformIgnorePatterns: ['/node_modules/'],
};
Configure Jest Preview inside jest.setup.js
(or any setup files specified in your setupFilesAfterEnv
config), so Jest Preview knows which global CSS file to load. You can even set autoPreview
to true
so your failed test gets a preview automatically! 🤯
import { jestPreviewConfigure } from 'jest-preview';
import './app/styles/global.css';
jestPreviewConfigure({
// Enable autoPreview so Jest Preview runs automatically
// whenever your test fails, without you having to do anything!
autoPreview: true,
});
Done
That's it! Now you can use Jest Preview in your test. Say we have app/__tests__/index.test.tsx
as follow...
import { render, screen } from '@testing-library/react';
import { debug } from 'jest-preview';
import Index from '../routes/index';
import '@testing-library/jest-dom'; // So we can use toBeInTheDocument assertion
it('should show welcome message', () => {
render(<Index />);
debug(); // Remove this line if you have enabled autoPreview in jest.setup.js
expect(
screen.getByRole('heading', { name: /welcome to remix/i }),
).toBeInTheDocument();
});
...and an app/styles/global.css
like this:
html {
max-width: 38rem;
padding: 2rem;
margin: auto;
line-height: 1.5rem;
font-size: 24px;
}
To run this test with Jest Preview, you must keep the jest-preview
server running in parallel. See the result at http://locahost:3336
.
./node_modules/.bin/jest-preview
./node_modules/.bin/jest --watch
You might as well add some NPM scripts for convenience:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
+ "test": "jest --watch",
+ "jest-preview": "jest-preview"
},
npm run jest-preview
npm run test
You may even install npm-run-all
to simplify this further:
npm install --save-dev npm-run-all
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "jest --watch",
"jest-preview": "jest-preview",
+ "test:preview": "npm-run-all -p test jest-preview"
},
npm run test:preview