testing-library / user-event

🐕 Simulate user events
https://testing-library.com/user-event
MIT License
2.18k stars 247 forks source link

replacing `fireEvent.click` with `userEvent.click` fails test #696

Closed steabert closed 2 years ago

steabert commented 3 years ago

Relevant code or config

We wrote a minimal unit test reproducing the issue. Commenting out line 46 or 47 makes the test either pass or fail, the only difference being userEvent.click or fireEvent.click. It works with fireEvent but not userEvent, which seems odd. To run the test, see instructions below under the reproduction repository.

What you did:

replace fireEvent.click with userEvent.click

What happened:

test goes from passed to failed

Reproduction repository: https://github.com/boilund/practical-react-components.git

git clone https://github.com/boilund/practical-react-components.git
cd practical-react-components
git checkout nm/unit-test
yarn
yarn setup
yarn workspace practical-react-components-core jest packages/core/src/Select/Select_unit.test.tsx

Problem description:

When using fireEvent.click in our test, the menu item gets clicked and the test passes. When we try to replace this with userEvent.click, the test fails. We were not successful in finding the cause of the problem. It seems that the userEvent.click function eventually calls fireEvent.click, but we're at a loss to explain why nothing happens after that. We need help analyzing the cause of the problem.

Suggested solution: Help us diagnose the issue, maybe point out something we missed, or let us know what we can do more to help investigate.

ph-fritsche commented 3 years ago

I guess there is something wrong with your setup. When extracting packages/core and installing dependencies there, the test works with userEvent.click.

steabert commented 3 years ago

Interesting! Thank you, I hadn't thought of trying that.

steabert commented 3 years ago

How exactly did you extract the workspace? When we create a separate package and install dependencies there, the userEvent.click still fails compared to fireEvent.click.

ph-fritsche commented 3 years ago

Oh it was a really quick and dirty reproduction - after I figured that walking through breakpoints in your setup wasn't too easy I extracted the package directory installed dependencies and plugged in the relevant code from userEvent to walk through just to find it working. But I didn't have time to figure where exactly this fails so this might need more investigation.

TangoYankee commented 3 years ago

This comment is not a bug report. I was poking around GitHub, saw this issue, and thought my experience might lead to an insight on why fireEvent and userEvent are not direct swaps.

When testing a checkbox event in an application test, I found that fireEvent and userEvent behaved differently when the checkbox was disabled. When clicking the input, the userEvent correctly stopped the onChange function from firing. Meanwhile, fireEvent incorrectly allowed the onChange function to fire. After finding #96, I swapped fireEvent for userEvent and now my test is working correctly.

Apologies for not providing exact version numbers. I forgot to grab the information while I was at work and now I'm on my personal laptop.

ph-fritsche commented 2 years ago

This issue has been stale for a while. If someone is willing to investigate and break the reproduction down to a minimal example, I'll gladly reopen.

redouredou commented 2 years ago

Hello guys,

I had similar issues when I wanted to use userEvents instead of fireEvents.

here is the versions I'm using.

"@testing-library/react": "^13.1.1", "@testing-library/user-event": "^14.1.1",

User events seems use asynchronous functions ( This seems logical since we want to reproduce user interactions ), so you need use async and await when you invoke functions from this lib in your test. This is what I did for resolve my issue.

0xHecker commented 2 years ago

It is because now the userEvent is async. this will work await userEvent.click(/* some code */)

PetyaFerreiraDeveloper commented 1 year ago

I had the same problem - using userEvent in an async function solves it