Open espipj opened 3 years ago
I sometimes think we should not have added the .toHaveStyle
custom matcher to this library. It is by far the one that gives more headaches.
In this case I cannot say for sure, but I bet that in the context of running the tests in jest, the stylesheet is not attached to the document that's being used in this context to run the test.
See for instance the code for when we run the very tests of this matcher, to see how we have to explicitly create a style
element with the css we want to be in place, and we have to explicitly attach it to the document
before these styles are enforced. This bit of the puzzle does not work in the context of the test in the same way as it works when you run a full-fledged page.
So to be clear, what I suspect is that the test is running in a document that looks like this more or less:
<html>
<head>
<!-- no style elements or link rel elements here -->
</head>
<body>
<!-- no style elements or link rel elements here -->
<div>
<!-- this is react's root element and where the <Demo /> component is mounted -->
</div>
<body>
</html>
If what I suspect is correct, there's little we can do. It depends on how css is built into your pages during the build steps of your bundler, or something along those lines.
Suggestions are welcome.
Hey thanks @gnapse Yes I guess is somehow related with how MUI theming/styling is applied... I'll try to do some research in the next days about it :)
I'm Having exact same problem with .toHaveStyle
. I'm using material components as well. @espipj let me know if you've found some solution/workaround for this problem.
Hey @ganeshr43 I'm afraid I didn't get anywhere sadly 😔
I ran into this same issue today. Did anyone figure this out yet or maybe a workaround?
We encountered a similar issue, however, the actual styles were there in the expectation and received values. The issue is that the received value was wrong. We have a component that generates HSLA colors using the d3-scale-chromatic and color libraries. These colors were being incorrectly transformed to the RGBA model (mapping to a gray while preserving the alpha channel). We were able to resolve our issue by switching to @emotion/jest's toHaveStyleRule for making color assertions. For other kinds of style assertions (which we tend to avoid except for special cases like this), things should have been working fine.
Possible janky solution for this, if you check document.head.innerHTML
does actually contain the style definitions MUI should be injecting, then try just replacing it on the document after rendering:
it('should hide menu button when menu bar is open', async () => {
const { findByLabelText, debug } = render((
<SomeMenuBar />
));
document.head.innerHTML = document.head.innerHTML; // ⚠️ Add this line.
const button = await findByLabelText('menu');
fireEvent.click(button);
expect(button).not.toBeVisible(); // And now my style is applied.
});
Why this works... no clue 🤷
I have run into this as well, with MaterialUI. In my case, reassigning document.head.innerHTML doesn't work.
const StyledTable = styled(Table)({
'& .MuiTableCell': {
'&-head': {
color: '#5C5C5C',
},
},
})
const table = <StyledTable>
<TableHead>
<TableRow>
<TableCell>Head cell</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Body cell</TableCell>
</TableRow>
</TableBody>
</StyledTable>
act(() => {
render(table, container)
})
const tableHead = container.querySelector('.MuiTableCell-head')
document.head.innerHTML = document.head.innerHTML // doesn't seem to matter whether I include this here
expect(tableHead).toHaveStyle({
color: '#353535', // receives the base MuiTable th color instead
})
If I change the way I send styles into the Mui component to using a Theme Provider and some overrides around the MuiTable rules, the test will pass. But that approach introduces friction when dealing with an outer theme provider, so the styled component/withStyles approach is preferable.
Hoping these additional details help.
after struggling a lot with the toHaveStyle method, I resolved my tests converting the HEX to RGB with this function below:
export const convertHexToRGBA = (hexCode: string) => {
let hex = hexCode.replace('#', '');
if (hex.length === 3) {
hex = `${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;
}
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return { r, g, b };
};
your tests will look like this:
expect(screen.getByText("Calories")).toHaveStyle({ color: convertHexToRGBA('#FFF') });
What fixed this to me was changing the jest-environment-jsdom-fourteen to "jest-environment-jsdom": "^26.6.2",
@cassiourugit I tried that and a get a error
ReferenceError: global is not defined
at Object.<anonymous> (node_modules/graceful-fs/graceful-fs.js:92:1)
at Object.<anonymous> (node_modules/expect/build/toThrowMatchers.js:10:24)
at Object.<anonymous> (node_modules/expect/build/index.js:35:48)
@jadir-junior
If you're using webpack, I believe you can enable node.global polyfill in your webpack config:
module.exports = {
//...
node: {
global: true
}
};
I'm having issues getting the correct value for background-color
for a React MUI SnackbarContent
component. I'm using testing-library. I've confirmed that my element is the correct element and that the background color of the element is rgb(230, 243, 250)
in the inspector.
Here is my test code:
test('Renders correct color', async () => {
render(<Info {...story.args} />);
const content = screen.getByRole('alert');
expect(content).toHaveStyle(`background-color: #E6F3FA`);
});
Here is the error message:
SnackbarContent > Renders info
-----
Error: expect(element).toHaveStyle()
- Expected
- background-color: rgb(230, 243, 250);
+ background-color: rgb(50, 50, 50);
I've also attempted using the color converter mentioned above but this results in the test passing no matter what color I pass to the function.
expect(content).toHaveStyle({
backgroundColor: convertHexToRGBA('#E6F3FA'),
});
I had the same problem, and for me it works to put it inside an object
expect(screen.getByText("Calories")).toHaveStyle({ color: '#FFF' });
I'm having issues getting the correct value for
background-color
for a React MUISnackbarContent
component. I'm using testing-library. I've confirmed that my element is the correct element and that the background color of the element isrgb(230, 243, 250)
in the inspector.Here is my test code:
test('Renders correct color', async () => { render(<Info {...story.args} />); const content = screen.getByRole('alert'); expect(content).toHaveStyle(`background-color: #E6F3FA`); });
Here is the error message:
SnackbarContent > Renders info ----- Error: expect(element).toHaveStyle() - Expected - background-color: rgb(230, 243, 250); + background-color: rgb(50, 50, 50);
I've also attempted using the color converter mentioned above but this results in the test passing no matter what color I pass to the function.
expect(content).toHaveStyle({ backgroundColor: convertHexToRGBA('#E6F3FA'), });
@strtw were you able to resolve this?
I had the same problem, and for me it works to put it inside an object
expect(screen.getByText("Calories")).toHaveStyle({ color: '#FFF' });
This worked for me too. We didn't upgrade any package. We just upgraded node version
For me the following does NOT work:
it("should work", () => {
render(<button style={{ color: "white" }}>123</button>);
expect(screen.getByText("123")).toHaveStyle({ color: "white" });
});
error:
- Expected
- color: white;
+ color: rgb(255, 255, 255);
But this works:
it("should work", () => {
render(<button style={{ color: "white" }}>123</button>);
expect(screen.getByText("123")).toHaveStyle({ color: "#FFF" });
});
This makes me wonder if it is helpful/feasible to add a color translation step for the .toHaveStyle
matcher into testing library?
Or at least raise an error, that named color strings are not supported ("no #
at the string start -> error) 🤷🏻
dom-testing-library
version: 5.11.9react-testing-library
version: 11.2.5Relevant code or config:
Problem Statement:
I was trying to test the styling of some components (applied via Material UI styling solution) and it seems that
toHaveStyle
doesn't work properly. The component style is computed/rendered properly in the web dom, the TabeHead cells styles show up as:But when using Testing library...
It throws the following error:
Expected - color: rgb(255, 255, 255); + color: rgba(0, 0, 0, 0.87);
rgba(0, 0, 0, 0.87)
is doesn't match with hex#FFF
At the same time this weirdly works with background-color. Please check the code sandbox for more context, if you need further explanation let me know and Im happy to help 😃