Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility Issue with jest-styled-components and Storybook's test-runner #443

Open
naporin0624 opened this issue Jan 11, 2024 · 2 comments

Comments

@naporin0624
Copy link

Issue Overview.

I am experiencing a problem with jest-styled-components not working as expected when using test-runner in Storybook. The problem seems to be caused by the way test-runner handles rendering.

  1. test-runner --eject to generate test-runner-jest.config.js
    Add the serializer from jest-styled-components/serializer to test-runner-jest.config.js
    Execute snapshot by test-runner.

I get the following snapshot, but it does not show the css associated with the class.

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[\`Button Default smoke-test 1\`] = \`
<button class="sc-beySPh fvFDzo">
default button
</button>
\`;

Detailed Description.

  • Non-Operational jest-styled-components: If you try to use jest-styled-components with storybook test-runner, it will not work correctly. It seems that test-runner is incompatible with jest-styled-components.

  • Rendering with headless browser:** Storybook's test-runner uses a headless browser to render React components. This process results in output that is different from what the jest-styled-components serializer expects. jest-styled-components` standard input is usually a ReactNode or HTMLElement, but output from a headless browser does not match this format.

Seeking a Solution

Are there any known solutions or workarounds for this problem?

Sample Repository

https://github.com/naporin0624/test-runner-jest-styled-components

@barmatz
Copy link

barmatz commented Sep 17, 2024

I am having the same issue

@kerlos-alfy
Copy link

The issue with jest-styled-components not working as expected with Storybook's test-runner likely stems from differences in rendering environments and how jest-styled-components serializer interacts with the rendered output. Here's a breakdown and possible solutions:


Problem Analysis

  1. Mismatch in Rendered Output
    Storybook's test-runner uses a headless browser (like Puppeteer) to render components. This output differs from what jest-styled-components expects (ReactNode or HTMLElement).

  2. Serializer Issue
    The jest-styled-components serializer relies on specific DOM structures and metadata to extract CSS styles. Headless browser rendering might strip some of this context.


Potential Solutions

  1. Use the jest-styled-components serializer correctly
    Ensure that the serializer from jest-styled-components is added to the Jest configuration properly in test-runner-jest.config.js. Example:

    module.exports = {
        ...require('@storybook/test-runner/jest-config'),
        snapshotSerializers: ['jest-styled-components/serializer'],
    };
  2. Switch Rendering Strategy
    Instead of relying on the headless browser rendering from Storybook, you can:

    • Mock the components to render using Jest's native rendering.
    • Test styles in isolation in a Jest-controlled environment rather than using test-runner.
  3. Custom Serializer
    Write a custom serializer to adapt the output from the headless browser to the format expected by jest-styled-components. Example setup:

    const { createSerializer } = require('jest-styled-components');
    const customSerializer = createSerializer({
        // Configuration or transformation logic if needed
    });
    
    module.exports = {
        snapshotSerializers: [customSerializer],
    };
  4. Force React Testing Library Rendering
    If you use React Testing Library with Jest, ensure your components are rendered via render from the library instead of relying on the headless browser:

    import { render } from '@testing-library/react';
    import 'jest-styled-components';
    
    test('Button Default smoke-test', () => {
        const { container } = render(<Button />);
        expect(container.firstChild).toMatchSnapshot();
    });
  5. Alternative Testing Strategies
    Consider avoiding snapshot testing altogether for styled-components in Storybook and instead:

    • Use visual regression testing (e.g., Chromatic or Percy).
    • Write specific tests for CSS properties using libraries like @testing-library/jest-dom:
      import { render } from '@testing-library/react';
      
      test('Button has correct styles', () => {
          const { getByText } = render(<Button />);
          const button = getByText('default button');
          expect(button).toHaveStyleRule('color', 'black'); // Example
      });
  6. Use of Decorators
    Ensure that Storybook decorators don't interfere with jest-styled-components behavior. You might need to adjust your configuration to apply styles globally or conditionally.


Suggested Workaround

In your specific repository setup, try the following:

  1. Update your test-runner-jest.config.js:

    const baseConfig = require('@storybook/test-runner/jest-config');
    
    module.exports = {
        ...baseConfig,
        snapshotSerializers: ['jest-styled-components/serializer'],
    };
  2. Replace headless browser rendering with @testing-library/react wherever possible.

  3. If the problem persists, consider isolating your tests for styled-components outside the Storybook test-runner and running them in a pure Jest environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants