最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Tab keypress doesn't change focused element - Stack Overflow

programmeradmin4浏览0评论

Note: this isn't about simulating the keypress itself

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

It'd be preferable to test that the ponent 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 ponent 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

Note: this isn't about simulating the keypress itself

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

It'd be preferable to test that the ponent 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 ponent 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

Share Improve this question edited Sep 20, 2022 at 14:24 evolutionxbox asked Apr 30, 2019 at 11:29 evolutionxboxevolutionxbox 4,1226 gold badges38 silver badges57 bronze badges 2
  • 1 Possible duplicate of Simulate keydown on document for JEST unit testing – Pants Commented Apr 30, 2019 at 13:56
  • @Pants I guess it could be. Couple of questions... Are they the same library? This question doesn’t ask about simulating key press on the document. – evolutionxbox Commented Apr 30, 2019 at 13:58
Add a ment  | 

2 Answers 2

Reset to default 12

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()

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

You can simply do this with react-testing-library itself. All you have to do is this:

Use the 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()
})
发布评论

评论列表(0)

  1. 暂无评论