user-event
user-event
is a companion library for Testing Library that provides more
advanced simulation of browser interactions than the built-in
fireEvent
method.
Install
API
Note: All userEvent methods are synchronous with one exception: when delay
option used with userEvent.type
as described below. We also discourage using
userEvent
inside before/after
blocks at all, for important reasons described
in
"Avoid Nesting When You're Testing".
click(element, eventInit, options)
Clicks element
, depending on what element
is it can have different side
effects.
You can also ctrlClick / shiftClick etc with
See the
MouseEvent
constructor documentation for more options.
Note that click
will trigger hover events before clicking. To disable this,
set the skipHover
option to true
.
dblClick(element, eventInit, options)
Clicks element
twice, depending on what element
is it can have different
side effects.
type(element, text, [options])
Writes text
inside an <input>
or a <textarea>
.
options.delay
is the number of milliseconds that pass between two characters
are typed. By default it's 0. You can use this option if your component has a
different behavior for fast or slow users. If you do this, you need to make sure
to await
!
To be clear,
userEvent.type
always returns a promise, but you only need toawait
the promise it returns if you're using thedelay
option. Otherwise everything runs synchronously and you can ignore the promise.
type
will click the element before typing. To disable this, set the
skipClick
option to true
.
Special characters
The following special character strings are supported:
Text string | Key | Modifier | Notes |
---|---|---|---|
{enter} | Enter | N/A | Will insert a newline character (<textarea /> only). |
{space} | ' ' | N/A | |
{esc} | Escape | N/A | |
{backspace} | Backspace | N/A | Will delete the previous character (or the characters within the selectedRange , see example below). |
{del} | Delete | N/A | Will delete the next character (or the characters within the selectedRange , see example below) |
{selectall} | N/A | N/A | Selects all the text of the element. Note that this will only work for elements that support selection ranges (so, not email , password , number , among others) |
{arrowleft} | ArrowLeft | N/A | |
{arrowright} | ArrowRight | N/A | |
{arrowup} | ArrowUp | N/A | |
{arrowdown} | ArrowDown | N/A | |
{shift} | Shift | shiftKey | Does not capitalize following characters. |
{ctrl} | Control | ctrlKey | |
{alt} | Alt | altKey | |
{meta} | OS | metaKey | |
{capslock} | CapsLock | modifierCapsLock | Fires both keydown and keyup when used (simulates a user clicking their "Caps Lock" button to enable caps lock). |
A note about modifiers: Modifier keys (
{shift}
,{ctrl}
,{alt}
,{meta}
) will activate their corresponding event modifiers for the duration of type command or until they are closed (via{/shift}
,{/ctrl}
, etc.). If they are not closed explicitly, then events will be fired to close them automatically (to disable this, set theskipAutoClose
option totrue
).
We take the same stance as Cypress in that we do not simulate the behavior that happens with modifier key combinations as different operating systems function differently in this regard.
An example of an usage with a selection range:
<input type="time" />
support
The following is an example of usage of this library with
<input type="time" />
keyboard(text, options)
Simulates the keyboard events described by text
. This is similar to
userEvent.type()
but without any clicking or changing the selection range.
You should use
userEvent.keyboard
if you want to just simulate pressing buttons on the keyboard. You should useuserEvent.type
if you just want to conveniently insert some text into an input field or textarea.
Keystrokes can be described:
- Per printable characterThe bracketsuserEvent.keyboard('foo') // translates to: f, o, o
{
and[
are used as special character and can be referenced by doubling them.userEvent.keyboard('{{a[[') // translates to: {, a, [ - Per
KeyboardEvent.key
(only supports alphanumeric values of
key
)This does not keep any key pressed. SouserEvent.keyboard('{Shift}{f}{o}{o}') // translates to: Shift, f, o, oShift
will be lifted before pressingf
. - Per
KeyboardEvent.codeuserEvent.keyboard('[ShiftLeft][KeyF][KeyO][KeyO]') // translates to: Shift, f, o, o
- Per legacy
userEvent.type
modifier/specialChar The modifiers like{shift}
(note the lowercase) will automatically be kept pressed, just like before. You can cancel this behavior by adding a/
to the end of the descriptor.userEvent.keyboard('{shift}{ctrl/}a{/shift}') // translates to: Shift(down), Control(down+up), a, Shift(up)
Keys can be kept pressed by adding a >
to the end of the descriptor - and
lifted by adding a /
to the beginning of the descriptor:
userEvent.keyboard
returns a keyboard state that can be used to continue
keyboard operations.
The mapping of key
to code
is performed by a
default key map
portraying a "default" US-keyboard. You can provide your own local keyboard
mapping per option.
Future versions might try to interpolate the modifiers needed to reach a printable key on the keyboard. E.g. Automatically pressing
{Shift}
when CapsLock is not active andA
is referenced. If you don't wish this behavior, you can passautoModify: false
when usinguserEvent.keyboard
in your code.
upload(element, file, [{ clickInit, changeInit }])
Uploads file to an <input>
. For uploading multiple files use <input>
with
the multiple
attribute and the second upload
argument as an array. It's also
possible to initialize a click or change event using a third argument.
clear(element)
Selects the text inside an <input>
or <textarea>
and deletes it.
selectOptions(element, values)
Selects the specified option(s) of a <select>
or a <select multiple>
element.
The values
parameter can be either an array of values or a singular scalar
value.
It also accepts option nodes:
deselectOptions(element, values)
Remove the selection for the specified option(s) of a <select multiple>
element.
The values
parameter can be either an array of values or a singular scalar
value.
tab({shift, focusTrap})
Fires a tab event changing the document.activeElement in the same way the browser does.
Options:
shift
(defaultfalse
) can be true or false to invert tab direction.focusTrap
(defaultdocument
) a container element to restrict the tabbing within.
A note about tab: jsdom does not support tabbing, so this feature is a way to enable tests to verify tabbing from the end user's perspective. However, this limitation in jsdom will mean that components like focus-trap-react will not work with
userEvent.tab()
or jsdom. For that reason, thefocusTrap
option is available to let you ensure your user is restricted within a focus-trap.
hover(element)
Hovers over element
.
unhover(element)
Unhovers out of element
.
See above for an example
paste(element, text, eventInit, options)
Allows you to simulate the user pasting some text into an input.
You can use the eventInit
if what you're pasting should have clipboardData
(like files
).
specialChars
A handful set of special characters used in type method.
Key | Character |
---|---|
arrowLeft | {arrowLeft} |
arrowRight | {arrowRight} |
arrowDown | {arrowDown} |
arrowUp | {arrowUp} |
enter | {enter} |
escape | {esc} |
delete | {del} |
backspace | {backspace} |
selectAll | {selectAll} |
space | {space} |
whitespace | ' ' |
Usage example:
Known limitations
- No
<input type="color" />
support. #423