styled-components icon indicating copy to clipboard operation
styled-components copied to clipboard

v6 not injecting any style tag in test environment

Open domarmstrong opened this issue 2 years ago • 4 comments

Environment

## System:
 - OS: macOS 13.4
 - CPU: (10) arm64 Apple M1 Max
 - Memory: 487.28 MB / 64.00 GB
 - Shell: 5.9 - /bin/zsh
## Binaries:
 - Node: 18.16.0 - /private/var/folders/.../node
 - Yarn: 3.6.0 - /private/var/folders/.../yarn
 - npm: 9.5.1 - ~/n/bin/npm
 - pnpm: 8.6.5 - ~/n/bin/pnpm

Reproduction

Repo https://github.com/domarmstrong/styled-components-v6-repro Sandbox https://codesandbox.io/p/sandbox/styled-components-6-cloud-forked-q2m4pm

Steps to reproduce

See reproduction.

It works fine in a non-cloud version of the same sandbox https://codesandbox.io/s/styled-components-6-kqszxg. But fails when run in the cloud version linked above.

Note: the reproduction env is abstracted by react-scripts. However our application uses jest/jsdom env directly with the same behavior, so this issue should not be related to that setup.

Expected Behavior

When running in jest with jsdom a <style> tag is added to the document head.

Actual Behavior

When running in jest with jsdom no style tag is inserted.

domarmstrong avatar Jul 07 '23 14:07 domarmstrong

I've had a further dig in to this and it appears to be because when running in Jest the dist/styled-components.cjs.js is used, and when built with webpack the ./dist/styled-components.browser.esm.js (or cjs) files are used. The styled-components.cjs.js is compiled to have a hardcoded value that isServer is true. Presumably, this should still be a runtime check, not a static value.

https://github.com/styled-components/styled-components/blob/8e4b064a9001dc32495f9c77f0334a9b527a0bf7/packages/styled-components/src/sheet/Sheet.ts#L23

styled-components.cjs.js

  ve = { isServer: !0, useCSSOMInjection: !f },

styled-components.browser.esm.js

  f = 'undefined' != typeof window && 'HTMLElement' in window,
  Ee = { isServer: !f, useCSSOMInjection: !y },

I've managed to get this working by adding a manual mapping in our jest config file. This wasn't previously required and I'm not sure it's very intuitive.

jest.config.js

  ...
  moduleNameMapper: {
    'styled-components': 'styled-components/dist/styled-components.browser.cjs.js',
  },
  ...

domarmstrong avatar Jul 17 '23 13:07 domarmstrong

Thanks @domarmstrong

Replicated the issue in a fairly clean repository using the testing library which is using jsdom: https://github.com/dejanvasic85/jest-styled-components

Your jest config fixes the problem for the moment. Great find 👍 🔥

dejanvasic85 avatar Aug 07 '23 09:08 dejanvasic85

apparently this issue also happened on v5.2.0 https://github.com/styled-components/styled-components/issues/3262

leonluna avatar Aug 08 '23 19:08 leonluna

The solution of jest config override negates the use of Jest Styled Components which helps with snapshot testing. Class names are always changing in the snapshots, but we're expecting the styles to be rendered at the top which is the responsibility of this tool. 😢

dejanvasic85 avatar Aug 17 '23 11:08 dejanvasic85