Hello there I have two question with Next.js, testing-library/react and emotion.
before ask, I'll show you code below
// component
import { css, Theme } from '@emotion/react';
function Foo() {
return <h1 css={fooCss}>title</h1
}
const fooCss = (theme: Theme) => css`position: absoulte;`;
// test code
it('position absoulte', () => {
render(<Foo />);
expect(screen.getByRole('heading')).toHaveStyle('position: absoulte');
});
First Question. warning at jest : Invalid value for prop 'css' on tag... warning
Second Question. test failed with doesn't have style with css prop
How can I dealing with this warning and error ?
I'll post with babelrc, jest.config and setup
// jest.config.js
const nextJest = require('next/jest');
const createJestConfig = nextJest({
dir: './',
});
const customJestConfig = {
resetMocks: true,
moduleDirectories: ['node_modules'],
testEnvironment: 'jsdom',
testRegex: '(/__tests__/.*|(\\.|/)(test))\\.[jt]sx?$',
collectCoverageFrom: ['**/src/**/*.{js,ts,jsx,tsx}'],
moduleNameMapper: {
'~/(.*)': '<rootDir>/src/$1',
'.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2|ico)$': 'identity-obj-proxy',
},
moduleFileExtensions: ['js', 'jsx', 'json', 'ts', 'tsx'],
transform: {
'^.+\\.tsx?$': 'esbuild-jest',
},
coverageThreshold: null,
setupFilesAfterEnv: ['./jest.setup.js'],
};
module.exports = createJestConfig(customJestConfig);
// jest.setup.js
import '@testing-library/jest-dom';
window.matchMedia = query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
});
// .babelrc.js
module.exports = {
presets: [
[
'next/babel',
{
'preset-react': {
runtime: 'automatic',
importSource: '@emotion/react',
},
},
],
],
plugins: ['@emotion/babel-plugin'],
};
This is a problem related to passing a function (theme) => css``
or (theme) => css({})
into css prop.
You could solve this with useTheme
hook.
import {css, Theme, useTheme} from '@emotion/react';
function Foo() {
const theme: Theme = useTheme()
return (
<h1 css={css`color: ${theme.colors.primary}`}>
title
</h1>
)
}
You need to use custom matchers from @emotion/jest
.
import {matchers} from '@emotion/jest'
expect.extend(matchers)
it('position absolute', () => {
render(<Foo />);
expect(screen.getByRole('heading')).toHaveStyleRule('position', 'absolute');
});
Note: In order to make this work, don't forget to add the pragma /** @jsxImportSource @emotion/react */
in components using css prop.