Convenience APIs
The following APIs are shortcuts for equivalent calls to the underlying
pointer() and keyboard() APIs.
Clicks
click()
click(element: Element): Promise<void>
pointer([{target: element}, {keys: '[MouseLeft]', target: element}])
test('click', async () => {
  const onChange = jest.fn()
  const user = userEvent.setup()
  render(<input type="checkbox" onChange={onChange} />)
  const checkbox = screen.getByRole('checkbox')
  await user.click(checkbox)
  expect(onChange).toHaveBeenCalledTimes(1)
  expect(checkbox).toBeChecked()
})
The first action might be skipped per skipHover.
dblClick()
dblClick(element: Element): Promise<void>
pointer([{target: element}, {keys: '[MouseLeft][MouseLeft]', target: element}])
test('double click', async () => {
  const onChange = jest.fn()
  const user = userEvent.setup()
  render(<input type="checkbox" onChange={onChange} />)
  const checkbox = screen.getByRole('checkbox')
  await user.dblClick(checkbox)
  expect(onChange).toHaveBeenCalledTimes(2)
  expect(checkbox).not.toBeChecked()
})
tripleClick()
tripleClick(element: Element): Promise<void>
pointer([
  {target: element},
  {keys: '[MouseLeft][MouseLeft][MouseLeft]', target: element},
])
test('triple click', async () => {
  const onChange = jest.fn()
  const user = userEvent.setup()
  render(<input type="checkbox" onChange={onChange} />)
  const checkbox = screen.getByRole('checkbox')
  await user.tripleClick(checkbox)
  expect(onChange).toHaveBeenCalledTimes(3)
  expect(checkbox).toBeChecked()
})
Mouse movement
hover()
hover(element: Element): Promise<void>
pointer({target: element})
test('hover/unhover', async () => {
  const user = userEvent.setup()
  render(<div>Hover</div>)
  const hoverBox = screen.getByText('Hover')
  let isHover = false
  hoverBox.addEventListener('mouseover', () => {
    isHover = true
  })
  hoverBox.addEventListener('mouseout', () => {
    isHover = false
  })
  expect(isHover).toBeFalsy()
  await user.hover(hoverBox)
  expect(isHover).toBeTruthy()
  await user.unhover(hoverBox)
  expect(isHover).toBeFalsy()
})
unhover()
unhover(element: Element): Promise<void>
pointer({target: element.ownerDocument.body})
Keyboard
tab()
tab(options: {shift?: boolean}): Promise<void>
// without shift
keyboard('{Tab}')
// with shift=true
keyboard('{Shift>}{Tab}{/Shift}')
// with shift=false
keyboard('[/ShiftLeft][/ShiftRight]{Tab}')
test('tab', async () => {
  const user = userEvent.setup()
  render(
    <div>
      <input type="checkbox" />
      <input type="radio" />
      <input type="number" />
    </div>,
  )
  const checkbox = screen.getByRole('checkbox')
  const radio = screen.getByRole('radio')
  const number = screen.getByRole('spinbutton')
  expect(document.body).toHaveFocus()
  await user.tab()
  expect(checkbox).toHaveFocus()
  await user.tab()
  expect(radio).toHaveFocus()
  await user.tab()
  expect(number).toHaveFocus()
  await user.tab()
  // cycle goes back to the body element
  expect(document.body).toHaveFocus()
  // simulate Shift-Tab
  await user.tab({shift: true})
  expect(number).toHaveFocus()
})