testing-library / testing-library/user-event
Problem testing keyboard interaction with select element
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.3k
- Forks
- 258
- PR merge metrics
- No merged PRs in 30d
Description
- @testing-library/user-event version: 13.5.0
- Testing Framework and version: jest (version 26.6.0 )
- DOM Environment: jsdom (version 16.7.0)
Relevant code:
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
describe("When rendering dropdown", () => {
beforeEach(() => {
render(
<select>
<option value="A">First Option</option>
<option value="B">Second Option</option>
<option value="C">Third Option</option>
</select>);
});
describe("When second option has been selected", () => {
beforeEach(() => {
userEvent.selectOptions(screen.getByRole("combobox"), ["B"]);
});
it("Only second option has been selected", () => {
expect(screen.getByRole("option", { name: "First Option" }).selected).toBe(false);
expect(screen.getByRole("option", { name: "Second Option" }).selected).toBe(true);
expect(screen.getByRole("option", { name: "Third Option" }).selected).toBe(false);
});
});
describe("When pressing tab", () => {
beforeEach(() => {
userEvent.tab();
});
it("set focus on dropDown", () => {
expect(screen.getByRole("combobox")).toHaveFocus();
});
describe("When pressing space and 2x arrowDown", () => {
beforeEach(() => {
userEvent.keyboard("{space}");
userEvent.keyboard("{arrowdown}");
userEvent.keyboard("{arrowdown}");
userEvent.keyboard("{space}");
});
it("Only second option has been selected", () => {
expect(screen.getByRole("option", { name: "First Option" }).selected).toBe(false);
expect(screen.getByRole("option", { name: "Second Option" }).selected).toBe(true);
expect(screen.getByRole("option", { name: "Third Option" }).selected).toBe(false);
});
});
describe("When pressing space and 2x arrowDown", () => {
beforeEach(() => {
userEvent.type(screen.getByRole("combobox"), "{space}{arrowdown}{arrowdown}{space}");
});
it("Only second option has been selected", () => {
expect(screen.getByRole("option", { name: "First Option" }).selected).toBe(false);
expect(screen.getByRole("option", { name: "Second Option" }).selected).toBe(true);
expect(screen.getByRole("option", { name: "Third Option" }).selected).toBe(false);
});
});
});
});
What you did:
I ran the tests above.
What happened:
The tests failed with the following message.
● When rendering dropdown › When pressing tab › When pressing space and 2x arrowDown › Only second option has been selected
expect(received).toBe(expected) // Object.is equality
Expected: false
Received: true
43 |
44 | it("Only second option has been selected", () => {
> 45 | expect(screen.getByRole("option", { name: "First Option" }).selected).toBe(false);
| ^
46 | expect(screen.getByRole("option", { name: "Second Option" }).selected).toBe(true);
47 | expect(screen.getByRole("option", { name: "Third Option" }).selected).toBe(false);
48 | });
at Object.<anonymous> (src/components/Select.test.js:45:79)
● When rendering dropdown › When pressing tab › When pressing space and 2x arrowDown › Only second option has been selected
expect(received).toBe(expected) // Object.is equality
Expected: false
Received: true
55 |
56 | it("Only second option has been selected", () => {
> 57 | expect(screen.getByRole("option", { name: "First Option" }).selected).toBe(false);
| ^
58 | expect(screen.getByRole("option", { name: "Second Option" }).selected).toBe(true);
59 | expect(screen.getByRole("option", { name: "Third Option" }).selected).toBe(false);
60 | });
at Object.<anonymous> (src/components/Select.test.js:57:79)
Problem description:
I want to test the keyboard interaction with a select component to make sure that it also works for users who can only interact via the keyboard. However, only the first option is selected whether I add any keyboard interaction through userEvent.keyboard or userEvent.type and the tests fail. Nevertheless, interacting in the browser with the element works fine.
Through the sandbox I saw that the space bar is being kept pressed when interacting with the element. However, using "{space>}{arrowdown}{arrowdown}{/space}" does not work either.
Suggested solution:
Unfortunately, I have no idea for a solution. I am not sure if there is a problem in my code or if testing this kind of interaction is not supported by the user-event library and I would be happy if you could point me in the right direction.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the failing cases in src/components/Select.test.js and compare the userEvent.keyboard and userEvent.type paths with the passing selectOptions case. Then inspect the user-event entry points handling select keyboard interaction and the linked sandbox behavior. Done means keyboard navigation selects only the second option and the regression tests pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react, typescript
- Domain
- frontend, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100