Tab 按键不会改变焦点元素

evo*_*box 8 javascript jsdom reactjs jestjs react-testing-library

我正在创建一个基于用户键盘事件(如按 Enter、箭头等)处理焦点的组件。

最好测试该组件是否忽略了 keydown 上的 tab 键。

但是,在触发 keydown tab 事件时,焦点不会像在浏览器中那样改变。


鉴于反应组件 Component.js

import React from 'react'

export default () => (
  <>
    <button data-testid="one">
      one
    </button>
    <button data-testid="two">
      two
    </button>
  </>
)
Run Code Online (Sandbox Code Playgroud)

和下面的测试 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()
  })
})
Run Code Online (Sandbox Code Playgroud)

测试失败,因为元素data-testid="one"仍然具有焦点。

有关此代码的可编辑版本,请参阅 CodeSandbox

小智 6

现在一个可行的解决方案是使用userEvent.tab()而不是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()
})
Run Code Online (Sandbox Code Playgroud)