Jest.js 按Tab键不会更改焦点元素

brvekthn  于 2022-12-08  发布在  Jest
关注(0)|答案(2)|浏览(215)
  • Note: this isn't about simulating the keypress itself*

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

yyhrrdl8

yyhrrdl81#

现在的工作解决方案是使用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()

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

iqxoj9l92#

你可以简单地用react-testing-library本身来做这件事。你所要做的就是:
使用fireEvent.blur(<your-input-element-here>)

import { fireEvent } from '@testing-library/react';

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

  // fires the onBlur event
  fireEvent.blur(one)

  expect(one).not.toHaveFocus()
})

相关问题