docs/user-event/api-utility.mdx
The following APIs don't have one-to-one equivalents in a real user
interaction.
Their behavior is therefore an interpretation how the "perceived" user
interaction might be translated to actual events on the DOM.
clear(element: Element): Promise<void>
This API can be used to easily clear an editable element.
test('clear', async () => {
const user = userEvent.setup()
render(<textarea defaultValue="Hello, World!" />)
await user.clear(screen.getByRole('textbox'))
expect(screen.getByRole('textbox')).toHaveValue('')
})
The Promise is rejected if the element can not be focused or contents can not
be selected.
selectOptions(
element: Element,
values: HTMLElement | HTMLElement[] | string[] | string,
): Promise<void>
deselectOptions(
element: Element,
values: HTMLElement | HTMLElement[] | string[] | string,
): Promise<void>
Select/deselect the given options in an HTMLSelectElement or listbox.
The values parameter can refer to an option per its value, HTML content or
just provide the element. It also accepts an array of these.
Selecting multiple options and/or deselecting options of
HTMLSelectElementis only possible if multiple is specified.
test('selectOptions', async () => {
const user = userEvent.setup()
render(
<select multiple>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>,
)
await user.selectOptions(screen.getByRole('listbox'), ['1', 'C'])
expect(screen.getByRole('option', {name: 'A'}).selected).toBe(true)
expect(screen.getByRole('option', {name: 'B'}).selected).toBe(false)
expect(screen.getByRole('option', {name: 'C'}).selected).toBe(true)
})
test('deselectOptions', async () => {
const user = userEvent.setup()
render(
<select multiple>
<option value="1">A</option>
<option value="2" selected>
B
</option>
<option value="3">C</option>
</select>,
)
await user.deselectOptions(screen.getByRole('listbox'), '2')
expect(screen.getByText('B').selected).toBe(false)
})
Note that this API triggers pointer events and is therefore subject to pointerEventsCheck.
type(
element: Element,
text: KeyboardInput,
options?: {
skipClick?: boolean
skipAutoClose?: boolean
initialSelectionStart?: number
initialSelectionEnd?: number
}
): Promise<void>
Type into an input element.
You should use
keyboard()if you want to just simulate pressing buttons on the keyboard.
You can usetype()if you just want to conveniently insert some text into an input field or textarea.
skipClick is true, click the element.initialSelectionStart is set, set the selection on the element. If
initialSelectionEnd is not set, this results in a collapsed selection.text per keyboard().skipAutoClose is true, release all
pressed keys.test('type into an input field', async () => {
const user = userEvent.setup()
render(<input defaultValue="Hello," />)
const input = screen.getByRole('textbox')
await user.type(input, ' World!')
expect(input).toHaveValue('Hello, World!')
})
upload(
element: HTMLElement,
fileOrFiles: File | File[],
): Promise<void>
Change a file input as if a user clicked it and selected files in the resulting file upload dialog.
Files that don't match an
acceptproperty will be automatically discarded, unlessapplyAcceptis set tofalse.
test('upload file', async () => {
const user = userEvent.setup()
render(
<div>
<label htmlFor="file-uploader">Upload file:</label>
<input id="file-uploader" type="file" />
</div>,
)
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
const input = screen.getByLabelText(/upload file/i)
await user.upload(input, file)
expect(input.files[0]).toBe(file)
expect(input.files.item(0)).toBe(file)
expect(input.files).toHaveLength(1)
})
test('upload multiple files', async () => {
const user = userEvent.setup()
render(
<div>
<label htmlFor="file-uploader">Upload file:</label>
<input id="file-uploader" type="file" multiple />
</div>,
)
const files = [
new File(['hello'], 'hello.png', {type: 'image/png'}),
new File(['there'], 'there.png', {type: 'image/png'}),
]
const input = screen.getByLabelText(/upload file/i)
await user.upload(input, files)
expect(input.files).toHaveLength(2)
expect(input.files[0]).toBe(files[0])
expect(input.files[1]).toBe(files[1])
})