Skip to content

Commit

Permalink
fix: prevent click event on non-focusable control
Browse files Browse the repository at this point in the history
When a label with a control is clicked, the click is forwarded even if
the control is not focusable (i.e. disabled or hidden). This change
addresses that issue.

Resolves testing-library#1057

Also, updating the how to contribute tutorial link in CONTRIBUTING.md.
  • Loading branch information
ammons-qualtrics committed May 11, 2023
1 parent 7a305de commit f0fec8a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Expand Up @@ -48,7 +48,7 @@ Also, please watch the repo and respond to questions/bug reports/feature
requests! Thanks!

<!-- prettier-ignore-start -->
[egghead]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github
[egghead]: https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github
[all-contributors]: https://github.com/all-contributors/all-contributors
[issues]: https://github.com/testing-library/user-event/issues
<!-- prettier-ignore-end -->
2 changes: 1 addition & 1 deletion src/event/behavior/click.ts
Expand Up @@ -9,8 +9,8 @@ behavior.click = (event, target, instance) => {
return () => {
if (isFocusable(control)) {
focusElement(control)
instance.dispatchEvent(control, cloneEvent(event))
}
instance.dispatchEvent(control, cloneEvent(event))
}
} else if (isElementType(target, 'input', {type: 'file'})) {
return () => {
Expand Down
31 changes: 31 additions & 0 deletions tests/pointer/click.ts
Expand Up @@ -216,6 +216,24 @@ describe('label', () => {

expect(getEvents('click')).toHaveLength(2)
})

test('do not click associated non-focusable control per label', async () => {
const {element, getEvents, user} = setup(
`<label for="in">foo</label><input disabled id="in"/>`,
)

await user.pointer({keys: '[MouseLeft]', target: element})

expect(getEvents('click')).toHaveLength(1)
})

test('do not click nested non-focusable control per label', async () => {
const {element, getEvents, user} = setup(`<label><input disabled/></label>`)

await user.pointer({keys: '[MouseLeft]', target: element})

expect(getEvents('click')).toHaveLength(1)
})
})

describe('check/uncheck control per click', () => {
Expand Down Expand Up @@ -263,6 +281,19 @@ describe('check/uncheck control per click', () => {

expect(input).not.toBeChecked()
})

test('clicking label does not change non-focusable checkable input', async () => {
const {
elements: [input, label],
user,
} = setup(`<input type="checkbox" disabled id="a"/><label for="a"></label>`)

expect(input).not.toBeChecked()

await user.pointer({keys: '[MouseLeft]', target: label})

expect(input).not.toBeChecked()
})
})

describe('submit form per click', () => {
Expand Down

0 comments on commit f0fec8a

Please sign in to comment.