getComputedStyle not returning correct pseudo-selector properties (React + Vitest + react-testing-library)

71 Views Asked by At

I'm trying to write a test for a custom switch component, which I've created starting from a MUI example (the 1st one of the four switches).

This is the component's code:

import styled from '@mui/system/styled'
import Switch from '@mui/material/Switch'

const IncomeOrExpenseSwitch = styled(Switch)(({ theme }) => ({
  width: 62,
  height: 34,
  padding: 7,
  '& .MuiSwitch-switchBase': {
    margin: 1,
    padding: 0,
    transform: 'translateX(6px)',
    '&.Mui-checked': {
      color: '#fff',
      transform: 'translateX(22px)',
      '& .MuiSwitch-thumb:before': {
        backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 311 311"><path fill="${encodeURIComponent(
          '#28a745'
        )}" d="M184 266c-33 0-61-22-76-55h102v-45H96a141 141 0 0 1 0-22h114V99H108c15-32 43-54 76-54 31 0 60 21 76 54l41-19C277 31 232 0 184 0c-37 0-71 17-96 47-13 15-23 33-29 52H10v45h40a184 184 0 0 0 0 22H10v45h49c6 20 16 38 29 53 25 30 59 47 96 47 48 0 93-31 117-80l-41-19c-16 33-45 54-76 54z"/></svg>')`,
      },
      '& + .MuiSwitch-track': {
        opacity: 1,
        backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
      },
    },
  },
  '& .MuiSwitch-thumb': {
    backgroundColor: theme.palette.mode === 'dark' ? '#003892' : '#001e3c',
    width: 32,
    height: 32,
    '&:before': {
      content: "''",
      position: 'absolute',
      width: '100%',
      height: '100%',
      left: 0,
      top: 0,
      backgroundRepeat: 'no-repeat',
      backgroundPosition: 'center',
      backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 311 311"><path fill="${encodeURIComponent(
        '#dc3545'
      )}" d="M184 266c-33 0-61-22-76-55h102v-45H96a141 141 0 0 1 0-22h114V99H108c15-32 43-54 76-54 31 0 60 21 76 54l41-19C277 31 232 0 184 0c-37 0-71 17-96 47-13 15-23 33-29 52H10v45h40a184 184 0 0 0 0 22H10v45h49c6 20 16 38 29 53 25 30 59 47 96 47 48 0 93-31 117-80l-41-19c-16 33-45 54-76 54z"/></svg>')`,
    },
  },
  '& .MuiSwitch-track': {
    opacity: 1,
    backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
    borderRadius: 20 / 2,
  },
}))

export default IncomeOrExpenseSwitch

Here's the test code:

import { assert, describe, it, expect, afterEach } from 'vitest'
import { render, cleanup, fireEvent } from '@testing-library/react'
import IncomeOrExpenseSwitch from './IncomeOrExpenseSwitch'

describe('IncomeOrExpenseSwitch', () => {
  afterEach(() => {
    cleanup()
  })

  it('renders IncomeOrExpenseSwitch component', () => {
    const { getByRole } = render(<IncomeOrExpenseSwitch />)
    const switchElement = getByRole('checkbox')
    expect(switchElement).not.toBeNull()
  })

  // TODO: getComputedStyle doesn't seem to get the right properties
  it('has a background-image', () => {
    const { getByRole } = render(<IncomeOrExpenseSwitch />)
    const switchElement = getByRole('checkbox')

    expect(switchElement.parentElement?.className).not.toContain('Mui-checked')

    const thumbElement = getByRole('checkbox').parentElement?.querySelector(
      '.MuiSwitch-thumb'
    )
    console.log(
      getComputedStyle(thumbElement!).getPropertyValue('background-color')
    )
    console.log(
      getComputedStyle(thumbElement!, ':before').getPropertyValue(
        'background-image'
      )
    )
  })
})

This is the test result:

 RERUN  src/components/Buttons/IncomeOrExpenseSwitch/IncomeOrExpenseSwitch.test.tsx x48

stdout | src/components/Buttons/IncomeOrExpenseSwitch/IncomeOrExpenseSwitch.test.tsx > IncomeOrExpenseSwitch > has a background-image
#001e3c


 ✓ src/components/Buttons/IncomeOrExpenseSwitch/IncomeOrExpenseSwitch.test.tsx (2)
   ✓ IncomeOrExpenseSwitch (2)
     ✓ renders IncomeOrExpenseSwitch component
     ✓ has a background-image

 Test Files  1 passed (1)
      Tests  2 passed (2)
   Start at  11:03:38
   Duration  308ms


 PASS  Waiting for file changes...

As you can see, whilst the background-color of thumbElement is correctly logged (#001e3c), the background-image of the pseudo-element (:before) is not. In fact, if I try to log the pseudo-element background-color, I still get #001e3c, as if it was still dealing with the base element selector. What am I doing wrong?

vite.config.ts:

import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react-swc'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    environment: 'happy-dom',
    css: true,
  },
})

vitests.config.ts:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    environmentMatchGlobs: [
      ['**', 'happy-dom'],
    ],
    coverage: {
      reporter: ['text', 'json', 'html'],
    },
  },
})
0

There are 0 best solutions below