Test if nth-child is receiving styles
I don't know if this is a bug, or if I just can't find the answer on google.
I'm trying to see if a style rule is applied to the nth-child() of an element. I'm always getting the base style rather than the modified style which is based on the element's location in the tree.
This is my test:
it('should render correctly', () => {
const wrapper = render(<Rating rating={3} />);
expect(toJson(wrapper.find('button:nth-child(1) svg'))).toHaveStyleRule('fill', '#91c11e');
expect(toJson(wrapper.find('button:nth-child(1) svg'))).toMatchSnapshot();
});
The test fails with:
"Value mismatch for property 'fill'"
Expected
"fill: #91c11e"
Received:
"fill: #eceae6"
The snapshot is:
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Rating should render correctly 1`] = `
.c0 {
width: 16px;
height: 16px;
fill: #eceae6;
pointer-events: none;
}
.c1:nth-child(-n + 3) .c0 {
fill: #91c11e;
}
<svg
class="c0"
xmlns="http://www.w3.org/2000/svg"
>
<use
href="#star"
/>
</svg>
`;
Any help would be appreciated
Hey @jdwillemse!
You need to assert the style rule on the styled component that has these styles instead of finding the element that should be styled(In your case it should be just wrapper). You can achieve this by passing a modifier into the .toHaveStyleRule call.
I haven't tested the code below, but something like this should work:
expect(toJson(wrapper)).toHaveStyleRule('fill', '#91c11e', {
modifier: 'button:nth-child(1) svg',
});
Just be sure that your selector in styled-component code is exactly the same as in the modifier option.
For anyone else looking for an equivalent without Enzyme, I've used, @emotion/styled with jest, react-test-renderer (instead of Enzyme, as used here):
Here's how you'd do it there.
import renderer from 'react-test-renderer';
import Rating from './path/to/rating';
import { matchers } from '@emotion/jest'; // I've used @emotion/styled (https://emotion.sh/docs/@emotion/jest)
expect.extend(matchers); // This is necessary
it('should render correctly', () => {
const wrapper = renderer.create(<Rating rating={3} />).toJSON();
expect(wrapper).toHaveStyleRule('fill', '#91c11e', {
target: 'button:nth-child(1) svg'
});
});
Very similar to the enzyme one, slightly different syntax.