Tab keypress doesn't change focused element

I'm creating a component which handles focus based on user keyboard events (like pressing enter, arrows, etc).

It'd be preferable to test that the component ignores the tab key on keydown.

However, on firing the keydown tab event, the focus doesn't change like it would in a browser.


Given the react component in Component.js

import React from 'react'

export default () => (
  <>
    <button data-testid="one">
      one
    </button>
    <button data-testid="two">
      two
    </button>
  </>
)

and the following test Component.test.js

import React from 'react'
import 'jest-dom/extend-expect'
import { cleanup, fireEvent, render, wait } from 'react-testing-library'
import Component from './Component'

afterEach(cleanup)

it('changes focus on tab', async () => {
  const { getByTestId } = render(<Component />)
  const one = getByTestId('one')
  const two = getByTestId('two')

  one.focus()

  expect(one).toHaveFocus()

  fireEvent.keyDown(one, {
    key: 'Tab',
    code: 9,
    charCode: 9
  })

  await wait(() => {
    expect(two).toHaveFocus()
  })
})

the test fails, as the element data-testid="one" still has focus.

See CodeSandbox for an editable version of this code

Answers:

Answer

A working solution nowadays would be to use userEvent.tab() instead of fireEvent.keyDown().

import '@testing-library/jest-dom'
import userEvent from '@testing-library/user-event'

import { render, screen } from '@testing-library/react'
import Component from './buttons'

it('changes focus on tab', async () => {
  render(<Component />)
  const one = screen.getByTestId('one')
  const two = screen.getByTestId('two')

  one.focus()
  expect(one).toHaveFocus()

  userEvent.tab()
  expect(two).toHaveFocus()
})

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.