styled-components / jest-styled-components

🔧 💅 Jest utilities for Styled Components
MIT License
1.59k stars 145 forks source link

Support snapshots of `GlobalStyle` components #324

Open lunelson opened 4 years ago

lunelson commented 4 years ago

The style extraction methods in src/styleSheetSerializer.js should extract the styles created by "global styled components" such as created by the createGlobalStyle API. Currently, this does not happen.

Adapting an example from the styled-components docs...

import React from 'react'
import styled, { createGlobalStyle } from 'styled-components'
import renderer from 'react-test-renderer'
import 'jest-styled-components'

const GlobalStyle = createGlobalStyle`
  body {
    color: ${props => (props.whiteColor ? 'white' : 'black')};
  }
`

test('it works', () => {
  const tree = renderer.create(<GlobalStyle whiteColor />).toJSON()
  expect(tree).toMatchSnapshot()
})

...the above code should result in the following snapshot:

exports[`it works 1`] = `
  body {
    color: white;
  }
`;

This has already been cited and left unresolved in the following threads:

https://github.com/styled-components/jest-styled-components/issues/292 https://github.com/styled-components/jest-styled-components/issues/262 https://github.com/styled-components/jest-styled-components/issues/232

sauldeleon commented 2 years ago

Is this a request of jest-styled-components? Maybe we have to push this in other place!

hugonasciutti commented 2 years ago

I made a workaround until we have support to toMatchSnapshot or toHaveStyle.

Basically, I just mocked the lib and made the CSS interpolation myself and returned as string from the component.

Maybe this could benefit you @marnixhoh https://github.com/styled-components/jest-styled-components/issues/397 and @masakudamatsu https://github.com/masakudamatsu/nextjs-template/issues/17

It is not ideal, but we can guarantee the theme values.

interleave function used link.

import { render } from '@testing-library/react'
import { GlobalStyle } from '../GlobalStyle'

// GlobalStyle is the: const GlobalStyle = createGlobalStyle`

jest.mock('styled-components', () => {
  const originalModule = jest.requireActual('styled-components')

  function interleave(strings, interpolations) {
    const result = [strings[0]]

    for (let i = 0, len = interpolations.length; i < len; i += 1) {
      result.push(interpolations[i], strings[i + 1])
    }

    return result
  }

  const injectTheme = (css, { theme, fns }) =>
    interleave(
      css,
      fns.map((fn) => fn({ theme })),
    )

  const createGlobalStyle = (css, ...fns) => {
    return ({ theme }) => injectTheme(css, { theme, fns })
  }

  return {
    __esModule: true,
    ...originalModule,
    createGlobalStyle: jest.fn(createGlobalStyle),
  }
})

const theme = {
  palette: {
    common: {
      black: '#000',
      white: '#fff',
    },
  },
}

describe('GlobalStyle', () => {
  it('should match snapshot', () => {
    const { baseElement } = render(<GlobalStyle theme={theme} />)

    expect(baseElement).toMatchSnapshot()
  })
})
Katreque commented 1 year ago

Any updates? It's a big problem for those who use Global Style and basically can't test it.