-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[docs][Rating] Testing the component with @testing-library/user-event results in NaN #38828
Comments
Hey @IgnusG, thanks for the report!
This seems like a testing limitation. In Material UI's Rating tests, there's |
Since the issue is missing key information and has been inactive for 7 days, it has been automatically closed. If you wish to see the issue reopened, please provide the missing information. |
Hey @DiegoAndai 👋 Yeah I also resorted to stubbing to resolve this issue. Maybe MUI will handle this edge case more gracefully in the future but until then I think it's a good enough solution 👍 I would only suggest to add this gotcha to the Rating component's documentation. I couldn't find anything in there about this behavior and it took me a few hours of digging in the source code to find out this was the cause. |
In the meantime, for anyone else intimidated by the stubbing workaround, another way to avoid this issue when testing the component is to set the const user = userEvent.setup({ skipHover: true })
user.click(screen.getByLabelText('2 Stars')) |
I agree that documenting this would be useful. I will add the If anyone is interested on working on it, let us know 😊 |
@DiegoAndai can you please assign it to me? I'd like to work on it. |
@rajabhi21 sure! Go ahead. Let me know if you need any help. Thanks in advance. |
Hi @DiegoAndai as i've not seen any progress on this for last two weeks. I decided to try my luck. Please find attached PR. I probably forgot about the label :( . #44129 |
This is how the component is tested: material-ui/packages/mui-material/src/Rating/Rating.test.js Lines 114 to 122 in 064fa67
So far we avoided // @vitest-environment jsdom
import { Rating } from "@mui/material"
import { render, fireEvent, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { describe, test } from 'vitest';
describe('Rating', () => {
test('Rating', async () => {
const user = userEvent.setup();
render(<Rating onChange={(_, newRating) => console.log('newRating', newRating)} />);
- await user.click(screen.getByLabelText('2 Stars'));
+ fireEvent.click(screen.getByLabelText('2 Stars'));
})
}) https://codesandbox.io/p/devbox/wispy-fire-7lsnzs?file=%2Fsrc%2FApp.test.tsx%3A22%2C1 Now, yeah, I see We have 1. docs as a lever, I think that we also have:
On updating the docs 1., my instinct as a developer would be to go straight to check the source to see how it's tested, I wouldn't trust the docs so much because it doesn't run in the CI, it could get outdated. If we do 3. We don't need 1. +1 on my end to do 3. then 2, and skip 1 because 3 might be a minimal overhead compared to the DX pain (not a strong preference, only #suggestion). |
Can I ask whether are we gonna go with 3. -> 2.? I'd love to work on this approach |
@NooBat, sorry for the delay. I agree with going with 3. and 2. If you (or anyone) wish to implement it, go ahead. Feel free to let me know if you need any help. Thanks in advance. |
Steps to reproduce 🕹
Link to live example: https://codesandbox.io/p/sandbox/eloquent-breeze-7dtljr (run test task and scroll up for console log)
Steps:
onChange
handleronChange
handler is fired withnewRating
set toNaN
Current behavior 😯
Due to the way user events simulates user interaction the
handleMouseMove
method in MUI's Rating is fired (since user event simulates the mouse movement before issuing the click event). This method however relies on.getBoundingClientRect
which is not available in jest - or rather it is but all the values are set to 0 which means thepercent
calculation tries to divide by 0 ((event.clientX - left) / (width * max)
) which results in a NaN being set as thehover
state.In
onChange
sincehover
is set even though theparseFloat(event.target.value)
parses correctly it is overridden by theNaN
from hover.Expected behavior 🤔
Either this edge case is documented - I didn't find anything about this
handleMouseMove
behavior and how it takes precedence over the click when running theonChange
callback in the Rating docs or the calculation is adjusted to take into account thatwidth
could potentially be 0 and the hover should not be set (or be set to -1) in this case - such thatonChange
still reports theevent.target.value
instead.Context 🔦
No response
Your environment 🌎
npx @mui/envinfo
The text was updated successfully, but these errors were encountered: