From b9bd1dc886ad20814f7af4d6e5f3e22b89906cf5 Mon Sep 17 00:00:00 2001
From: Ammon Sarver <3289501+a0js@users.noreply.github.com>
Date: Thu, 11 May 2023 15:43:24 -0600
Subject: [PATCH] fix: prevent click event on non-focusable control
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 #1057
Also, updating the how to contribute tutorial link in CONTRIBUTING.md.
---
CONTRIBUTING.md | 2 +-
src/event/behavior/click.ts | 2 +-
tests/pointer/click.ts | 31 +++++++++++++++++++++++++++++++
3 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 43bc1c16..653a2785 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -48,7 +48,7 @@ Also, please watch the repo and respond to questions/bug reports/feature
requests! Thanks!
-[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
diff --git a/src/event/behavior/click.ts b/src/event/behavior/click.ts
index c9d6a4b6..c3e0d481 100644
--- a/src/event/behavior/click.ts
+++ b/src/event/behavior/click.ts
@@ -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 () => {
diff --git a/tests/pointer/click.ts b/tests/pointer/click.ts
index da3dab61..3dfb6d69 100644
--- a/tests/pointer/click.ts
+++ b/tests/pointer/click.ts
@@ -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(
+ ``,
+ )
+
+ 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(``)
+
+ await user.pointer({keys: '[MouseLeft]', target: element})
+
+ expect(getEvents('click')).toHaveLength(1)
+ })
})
describe('check/uncheck control per click', () => {
@@ -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(``)
+
+ expect(input).not.toBeChecked()
+
+ await user.pointer({keys: '[MouseLeft]', target: label})
+
+ expect(input).not.toBeChecked()
+ })
})
describe('submit form per click', () => {