emotion-js / emotion

👩‍🎤 CSS-in-JS library designed for high performance style composition
https://emotion.sh/
MIT License
17.5k stars 1.11k forks source link

css property does not get passed `theme` in Vitest tests #3237

Open cdan-youdo opened 3 months ago

cdan-youdo commented 3 months ago

Current behavior:

When rendering a component from inside a test, the theme is not passed to the css property if using ThemeProvider from @mui/material/styles. However, the test passes if ThemeProvider is imported from @emotion/react.

The component that is being tested

const StyledDiv = () => {
  return (
    <div css={
      theme => ({
        border: `6px solid ${theme.palette.secondary.main}`
      })
    } data-testid="styled-div">
    </div>
  )
}

The test

import React from 'react'
import {render, screen} from '@testing-library/react'
import { describe, expect, it } from 'vitest'

// It fails with ThemeProvider from @mui/material/styles
import { ThemeProvider } from '@mui/material/styles'
// It passes with ThemeProvider from @emotion/react
// import { ThemeProvider } from '@emotion/react'

import { default as StyledDiv } from './StyledDiv'
import { theme } from '../styles/theme'

describe('StyledDiv', () => {
  it('resolves the provided Theme', () => {
    render(
      <ThemeProvider theme={theme}>
        <StyledDiv/>
      </ThemeProvider>
    )
    const myComponent = screen.queryByTestId('styled-div');
    expect(myComponent).not.toBeNull();
    expect(myComponent).toHaveStyle({border: `6px solid ${theme.palette.secondary.main}`})
  })
})

My application root component uses the ThemeProvider from mui and works as expected when it renders in development.

import { ThemeProvider } from '@mui/material/styles';
import { theme } from 'styles/theme'
import { StyledDiv } from 'components';

export const AppContainer = () =>
  <ThemeProvider theme={theme}>
    <StyledDiv/>
  </ThemeProvider>

To reproduce:

I have put up a minimal git repo that you can use to reproduce the issue. https://github.com/cdan-youdo/react_vitest_emotion Once checked out, just run

yarn install
yarn vitest StyledDiv.test.tsx

Expected behavior:

I am expecting the test to pass when the component is rendered inside the ThemeProvider from @mui/material/styles.

Environment information:

Andarist commented 3 months ago

However, the test passes if ThemeProvider is imported from @emotion/react.

Why is this an issue created in the Emotion's repo then?

cdan-youdo commented 3 months ago

Why is this an issue created in the Emotion's repo then?

Because I didn't know what is the best place to post this. I have no idea if this is a Vite, emotion or mui/material issue.

I forgot to mention that my application root component uses the ThemeProvider from mui and works as expected when it renders in development.

import { ThemeProvider } from '@mui/material/styles';
import { theme } from 'styles/theme'
import { StyledDiv } from 'components';

export const AppContainer = () =>
  <ThemeProvider theme={theme}>
    <StyledDiv/>
  </ThemeProvider>

I was hoping for someone to shed some light on how the mui ThemeProvider and emotion integrate their context. This way maybe I get a better understanding and can figure out where to look for the culprit myself.

ScienceOfficer commented 3 months ago

We have this problem too and this happened after the dependency @emotion/react was updated from 11.12.0 to 11.13.0. Therefore we assumed that this might could be related with the emotion package