Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

userEvent.keyboard throws TypeError when using arrow keys #901

Closed
mattcarlotta opened this issue Apr 3, 2022 · 5 comments · Fixed by #953
Closed

userEvent.keyboard throws TypeError when using arrow keys #901

mattcarlotta opened this issue Apr 3, 2022 · 5 comments · Fixed by #953
Labels
bug Something isn't working released

Comments

@mattcarlotta
Copy link

  • @testing-library/dom version: 8.12.0
  • @testing-library/user-event version: 14.04
  • @testing-library/react version: 13.0.0
  • Testing Framework and version: jest@27.5.1
  • DOM Environment: @testing-library/jest-dom@5.16.3
  • Framework: react/react-dom@18.0.0
  • Node version: 16.14.2

Relevant code or config:

jest.config.js
setupTest.ts

What you did:

Attempting to test user arrow key navigation within a modal: ArrowRight and ArrowLeft

What happened:

TypeErrors:
ArrowRight
ArrowLeft

Reproduction:

testing branch (failing)

Problem description:

Appears that arrow keys aren't mapped properly. Downgrading to React 17.0.2, Testing Library User Event 13.0.5 and Testing Library React 12.1.4 works as expected on my development branch.

@timdeschryver timdeschryver transferred this issue from testing-library/dom-testing-library Apr 4, 2022
@ph-fritsche
Copy link
Member

ph-fritsche commented Apr 4, 2022

The error is caused by a Selection with rangeCount === 0.
Any interaction that moves focus on elements without own selection context (anything except <input>, <textarea>) sets the Selection to one Range. So per user interaction there is no focus on such an element without a Range on the Selection.
We probably should still guard against this here.

If you replace your fireEvent.click with await user.click the error will be gone.

@pascalduez
Copy link
Contributor

Hi,

the issue can be reproduced simply by:

const user = userEvent.setup();

render(
  <>
    <label htmlFor="one">One</label>
    <input type="radio" name="test" id="one" />
    <label htmlFor="two">Two</label>
    <input type="radio" name="test" id="two" />{' '}
  </>
);

// TypeError: Cannot read property 'nodeType' of null
await user.keyboard('[ArrowRight]');
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^12.1.4",
    "@testing-library/user-event": "^14.1.1",
    "jest": "^28.1.0",
    "jest-environment-jsdom": "^28.1.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"

Real world test

const user = userEvent.setup();

render(
  <>
    <label htmlFor="one">One</label>
    <input type="radio" name="test" id="one" />
    <label htmlFor="two">Two</label>
    <input type="radio" name="test" id="two" />{' '}
  </>
);

await user.tab();

expect(screen.getByRole('radio', { name: 'One' })).toHaveFocus();
expect(screen.getByRole('radio', { name: 'One' })).not.toBeChecked();

await user.keyboard('[Space]');

expect(screen.getByRole('radio', { name: 'One' })).toBeChecked();

// ¯\_(ツ)_/¯
// TypeError: Cannot read property 'nodeType' of null
await user.keyboard('[ArrowRight]');

expect(screen.getByRole('radio', { name: 'Two' })).toHaveFocus();
expect(screen.getByRole('radio', { name: 'Two' })).toBeChecked();

@ph-fritsche ph-fritsche added the bug Something isn't working label May 9, 2022
@github-actions
Copy link

🎉 This issue has been resolved in version 14.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@ph-fritsche
Copy link
Member

@all-contributors add @mattcarlotta bug

@allcontributors
Copy link
Contributor

@ph-fritsche

I've put up a pull request to add @mattcarlotta! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants