Introduction
user-event
is a companionlibrary for Testing Library that simulates user interactions by dispatching theevents that would happen if the interaction took place in a browser.
While most examples withuser-event
are forReact
, the library can be usedwith any framework as long as there is a DOM.
Differences fromfireEvent
fireEvent
dispatchesDOM events, whereasuser-event
simulates fullinteractions, which may fire multiple events and do additional checks alongthe way.
Testing Library's built-infireEvent
is a lightweightwrapper around the browser's low-leveldispatchEvent
API, which allowsdevelopers to trigger any event on any element. The problem is that the browserusually does more than just trigger one event for one interaction. For example,when a user types into a text box, the element has to be focused, and thenkeyboard and input events are fired and the selection and value on the elementare manipulated as they type.
user-event
allows you to describe a user interaction instead of a concreteevent. It adds visibility and interactability checks along the way andmanipulates the DOM just like a user interaction in the browser would. Itfactors in that the browser e.g. wouldn't let a user click a hidden element ortype in a disabled text box.
This iswhy you should useuser-event
to test interaction with your components.
There are, however, some user interactions or aspects of thesethat aren't yet implemented and thus can't yet be described withuser-event
.In these cases you can usefireEvent
to dispatch the concrete events that yoursoftware relies on.
Note that this makes your component and/or test reliant upon your assumptionsabout the concrete aspects of the interaction being correct. Therefore if youalready put in the work to specify the correct aspects of such interaction,please consider contributing to this project so thatuser-event
might coverthese cases too.
Writing tests withuserEvent
We recommend invokinguserEvent.setup()
before the component isrendered. This can be done in the test itself, or by using a setup function. Wediscourage rendering or using anyuserEvent
functions outside of the testitself - e.g. in abefore
/after
hook - for reasons described in"Avoid Nesting When You're Testing".
importuserEventfrom'@testing-library/user-event'
// inlining
test('trigger some awesome feature when clicking the button',async()=>{
const user= userEvent.setup()
// Import `render` and `screen` from the framework library of your choice.
// See https://testing-library.com/docs/dom-testing-library/install#wrappers
render(<MyComponent/>)
await user.click(screen.getByRole('button',{name:/click me!/i}))
// ...assertions...
})
importuserEventfrom'@testing-library/user-event'
// setup function
functionsetup(jsx){
return{
user: userEvent.setup(),
// Import `render` from the framework library of your choice.
// See https://testing-library.com/docs/dom-testing-library/install#wrappers
...render(jsx),
}
}
test('render with a setup function',async()=>{
const{user}=setup(<MyComponent/>)
// ...
})
Note that, while directly invoking APIs such asuserEvent.click()
(which willtriggersetup
internally) isstill supported in v14,this option exists to ease the migration from v13 to v14, and for simple tests.We recommend using the methods on the instances returned byuserEvent.setup()
.