Reputation: 251
I have a simple React component that will initially have a Tailwind CSS class of hidden
which apply CSS display: none
and will change the class to visible
on button click.
When I test with expect().not.toBeVisible()
it tells me the element is already visible while it has a hidden
class.
If I don't use Tailwind CSS and use a normal style={{display: 'none'}}
it'll correctly identify that the element isn't visible. That means clearly the issue is with Tailwind CSS.
Here's my test:
test("Notification bar should be initially hidden but visible on click", async () => {
render(<Notifications />);
expect(await screen.findByTestId("list")).not.toBeVisible();
// this test fails while the element already has a Tailwind CSS class of "hidden"
});
While this's my component:
<ul className="hidden" data-testid="list">
<li>item 1</li>
</ul>
Upvotes: 15
Views: 6884
Reputation: 537
I also encountered the same situation and tried to follow this upvoted answer many times but nothing happened.
For me what it worked I tried to solve this by mocking the tailwind CSS
from node modules, like this:
module.exports = {
moduleNameMapper: {
//.. all mocks names
'\\.(css|less)$': '<rootDir>/node_modules/tailwindcss',
},
}
I hope this someone helps!
Upvotes: 0
Reputation: 71
Use css:true
in vitest.config.ts
:
import { defineConfig } from 'vite';
import { configDefaults } from 'vitest/config';
export default defineConfig({
...
resolve: {
alias: {
'@': path.resolve(__dirname, './'),
},
},
test: {
// this option
css: true,
setupFiles: ['./tests/setupTests.ts'],
...
}
});
See more here: https://vitest.dev/config/#css
and then import your main CSS file in setupTests.ts
import '@/src/styles/globals.css';
where global.css
starts with:
@tailwind base;
@tailwind components;
@tailwind utilities;
Upvotes: 7
Reputation: 1
If your are using Vite as your bundler and Vitest as the testing framework, you can use the css: true
option in the Vitest options to enable processing CSS in test files. See more here: https://vitest.dev/config/#css
Additionally, you will have to import your index.css
(or whatever path name it is) in your component test or, even better, in your Vitest setupTests
file.
Upvotes: 0
Reputation: 394
The solution explained in this Stack Overflow: cannot check expectelm not tobevisible for semantic ui react component. Based on that thread, I extend the solution to make it works with TailwindCSS as the steps explained below,
root/
src/
test/
index.css
test-utils.tsx
component.test.tsx
index.css
By issuing the command below, the CSS file called index.css
will be generated in src/test
directory
npx tailwindcss -i ./src/index.css -o ./src/test/index.css
Further reading: TailwindCSS installation
Next we need to inject the generated CSS file into the JSDOM. Custom render function will be useful so we won't be needed to repeat this task for each test
import { render, RenderOptions } from '@testing-library/react';
import React, { FC, ReactElement } from 'react';
import fs from 'fs';
const wrapper: FC<{ children: React.ReactNode }> = ({ children }) => {
return <>{children}<>;
};
const customRender = (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) => {
const view = render(ui, { wrapper, ...options });
const style = document.createElement('style');
style.innerHTML = fs.readFileSync('src/test/index.css', 'utf8');
document.head.appendChild(style);
return view;
};
export * from '@testing-library/react';
export { customRender as render };
Further reading: Testing Library Setup
import React from 'react';
import { render, screen } from './test-utils';
test('Renders hidden hello world', () => {
render(<span className="hidden">Hello World</span>);
expect(screen.getByText('Hello World')).not.toBeVisible();
});
toHaveClass
matchers instead?it wouldn't align with the Testing Library guiding principle of “emphasize a focus on tests that closely resemble how your web pages are interacted by the users“ because by doing so, you are interacting with the component unnaturally
Upvotes: 6