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'],
},
},
})