user-event
user-event copied to clipboard
Arrow keys on radio buttons are backwards
Reproduction example
https://codesandbox.io/p/devbox/github/joshferrell/user-event-radio-demo/tree/main/
Prerequisites
Create a series of radio inputs
<label><input type="radio" name="group" value="a" />A</label>
<label><input type="radio" name="group" value="d" />D</label>
<label><input type="radio" name="group" value="e" />E</label>
Create a test that confirms radio behavior using the userEvent keyboard function
describe('Radio implementation', () => {
test.each([
{
name: "per [ArrowDown]",
focus: 'A',
key: "[ArrowDown]",
expectedTarget: 'D',
},
{
name: "per [ArrowLeft]",
focus: 'D',
key: "[ArrowLeft]",
expectedTarget: 'A',
},
{
name: "per [ArrowRight]",
focus: 'A',
key: "[ArrowRight]",
expectedTarget: 'D',
},
{
name: "per [ArrowUp]",
focus: 'D',
key: "[ArrowUp]",
expectedTarget: 'A',
},
{
name: "forward around the corner",
focus: 'E',
key: "[ArrowRight]",
expectedTarget: 'A',
},
{
name: "backward around the corner",
focus: 'A',
key: "[ArrowUp]",
expectedTarget: 'E',
},
])('$name', async ({ focus, key, expectedTarget }) => {
const user = userEvent.setup()
render(<App />)
screen.getByLabelText(focus).focus()
await user.keyboard(key)
expect(screen.getByLabelText(expectedTarget)).toHaveFocus()
})
})
Expected behavior
Behavior
Arrow Right
If A is selected and ArrowRight is pressed, D should be selected If E is selected and ArrowRight is pressed, A should be selected
Arrow Down
If A is selected and ArrowDown is pressed, D should be selected If E is selected and ArrowDown is pressed, A should be selected
Arrow Left
If D is selected and ArrowLeft is pressed, A should be selected If A is selected and ArrowLeft is pressed, E should be selected
Arrow Up
If D is selected and ArrowUp is pressed, A should be selected If A is selected and ArrowUp is pressed, E should be selected
Actual behavior
Behavior
Arrow Right
If A is selected and ArrowRight is pressed, E is selected If E is selected and ArrowRight is pressed, D is selected
Arrow Down
If A is selected and ArrowDown is pressed, D is selected If E is selected and ArrowDown is pressed, A is selected
Arrow Left
If D is selected and ArrowLeft is pressed, E is selected If A is selected and ArrowLeft is pressed, D is selected
Arrow Up
If D is selected and ArrowUp is pressed, A is selected If A is selected and ArrowUp is pressed, E is selected
User-event version
14.5.2
Environment
Testing Library framework: @testing-library/[email protected]
and @testing-library/user-event:14.5.2
JS framework: [email protected]
Test environment: [email protected]
Also ran in the user-event test suite and had the same issue
DOM implementation: [email protected]
Additional context
There are two issues with the current implementation of the keyboard event and handling radios.
- The walk radio function does not quit the for loop if it finds the next element
- Arrow Down and Arrow Up directions are inverted.