From dd20171ed441ff4a263aa664252be6d7ae3b1361 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Wed, 31 Jan 2024 19:56:10 -0800 Subject: [PATCH 01/22] Create common/keyboard-accessibility-utils.js --- common/keyboard-accessibility-utils.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 common/keyboard-accessibility-utils.js diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js new file mode 100644 index 00000000000000..8cbdc240ccd83d --- /dev/null +++ b/common/keyboard-accessibility-utils.js @@ -0,0 +1,5 @@ +/* Utilities for testing keyboard-focused accessibility */ + +const keyboardAccessibilityUtils { + +}; From 18545d82299717beb0aad24c843f11a087860db8 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Wed, 31 Jan 2024 20:23:11 -0800 Subject: [PATCH 02/22] Add verifyElementsAreFocusable() --- common/keyboard-accessibility-utils.js | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index 8cbdc240ccd83d..5f47ee4011864a 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -1,5 +1,29 @@ -/* Utilities for testing keyboard-focused accessibility */ +/* Utilities for keyboard-focused accessibility */ -const keyboardAccessibilityUtils { +const keyboardAccessibilityUtils = { + /* + Tests that all elements matching selector can + receive focus (and related) events. + + Ex:
+ + keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") + */ + verifyElementsAreFocusable: function(selector) { + const els = document.querySelectorAll(selector); + if (!els.length) { + throw `Selector passed in verifyElementsAreFocusable("${selector}") should match at least one element.`; + } + for (const el of els) { + let testName = el.getAttribute("data-testname"); + test(() => { + el.focus(); + assert_equals(document.activeElement, el, "Element is focusable with element.focus()"); + }, `${testName}`); + } + } }; From 0cef09bb2c4da7ea92686ee865cfceaaf9b04602 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Wed, 31 Jan 2024 21:19:32 -0800 Subject: [PATCH 03/22] Add verifyElementsAreTabbable() --- common/keyboard-accessibility-utils.js | 51 +++++++++++++++++++++----- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index 5f47ee4011864a..5459c07a7b69c4 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -14,16 +14,47 @@ const keyboardAccessibilityUtils = { keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") */ verifyElementsAreFocusable: function(selector) { + const els = document.querySelectorAll(selector); + if (!els.length) { + throw `Selector passed in verifyElementsAreFocusable("${selector}") should match at least one element.`; + } + for (const el of els) { + let testName = el.getAttribute("data-testname"); + test(() => { + el.focus(); + assert_equals(document.activeElement, el, "Element is focusable with element.focus()"); + }, `${testName}`); + } + }, + + + /* + Tests that all elements matching selector are + tabbable, i.e., present in the keyboard tab order. + + Ex: KeyboardAccessibilityUtils.verifyElementIsFocused(".ex-focused") */ @@ -59,6 +60,7 @@ const KeyboardAccessibilityUtils = { Ex: KeyboardAccessibilityUtils.verifyElementsAreTabbable(".ex-tabbable") */ From 1adf26aa63354ead0607f01428b41c48798e6800 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Wed, 31 Jan 2024 22:57:48 -0800 Subject: [PATCH 09/22] Add verifyElementsDoNotCauseKeyboardTrap() --- common/keyboard-accessibility-utils.js | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index 9f565ac4bd087a..d2f5619a8706c6 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -85,4 +85,40 @@ const KeyboardAccessibilityUtils = { }, `${testName}`); } }, + + /* + Tests that all elements matching selector are + tabbable and do not create a focus trap. + + Ex: + + KeyboardAccessibilityUtils.verifyElementsDoNotCauseKeyboardTrap(".ex-no-keyboard-trap") + */ + verifyElementsDoNotCauseKeyboardTrap: function(selector) { + const els = document.querySelectorAll(selector); + const focusablePreviousElement = document.createElement("a"); + focusablePreviousElement.setAttribute("href", "#"); + focusablePreviousElement.appendChild(document.createTextNode("a focusable link")); + if (!els.length) { + throw `Selector passed in verifyElementsDoNotCauseKeyboardTrap("${selector}") should match at least one element.`; + } + for (const el of els) { + let testName = el.getAttribute("data-testname"); + promise_test(async t => { + el.focus(); + assert_equals(document.activeElement, el, "precondition: el is currently focused"); + el.parentNode.insertBefore(focusablePreviousElement, el); + await test_driver.send_keys(el, "\uE004" + "\uE008"); + assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); + assert_not_equals(document.activeElement, el, "precondition: el is not focused"); + await test_driver.send_keys(focusablePreviousElement, "\uE004"); // \uE004 is the Tab key (see WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions) + assert_equals(document.activeElement, el, "el has successfully lost and received focus, and is now focused"); + document.body.removeChild(focusablePreviousElement); + }, `${testName}`); + } + }, }; + From 3fca138550b5441a532508e7b2b215c6c9701f74 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Wed, 31 Jan 2024 23:27:56 -0800 Subject: [PATCH 10/22] Updates to keyboard trap method, add keys{} object for keystrokes --- common/keyboard-accessibility-utils.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index d2f5619a8706c6..9cfee45b048fbb 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -1,6 +1,12 @@ /* Utilities for keyboard-focused accessibility */ -const KeyboardAccessibilityUtils = { +const keys = { + // See WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions + "Tab": "\uE004", + "ShiftAndTab": "\uE008" + "\uE004", +}; + +const keyboardAccessibilityUtils = { /* Tests that all elements matching selector can @@ -12,7 +18,7 @@ const KeyboardAccessibilityUtils = { class="ex">
- KeyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") + keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") */ verifyElementsAreFocusable: function(selector) { const els = document.querySelectorAll(selector); @@ -37,7 +43,7 @@ const KeyboardAccessibilityUtils = { class="ex-focused"> - KeyboardAccessibilityUtils.verifyElementIsFocused(".ex-focused") + keyboardAccessibilityUtils.verifyElementIsFocused(".ex-focused") */ verifyElementIsFocused: function(selector) { const els = document.querySelectorAll(selector); @@ -62,7 +68,7 @@ const KeyboardAccessibilityUtils = { class="ex-tabbable"> - KeyboardAccessibilityUtils.verifyElementsAreTabbable(".ex-tabbable") + keyboardAccessibilityUtils.verifyElementsAreTabbable(".ex-tabbable") */ verifyElementsAreTabbable: function(selector) { const els = document.querySelectorAll(selector); @@ -79,7 +85,7 @@ const KeyboardAccessibilityUtils = { focusablePreviousElement.focus(); assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, "\uE004"); // \uE004 is the Tab key (see WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions) + await test_driver.send_keys(focusablePreviousElement, keys.Tab); // assert_equals(document.activeElement, el, "Element is tabbable"); document.body.removeChild(focusablePreviousElement); }, `${testName}`); @@ -95,7 +101,7 @@ const KeyboardAccessibilityUtils = { class="ex-no-keyboard-trap"> - KeyboardAccessibilityUtils.verifyElementsDoNotCauseKeyboardTrap(".ex-no-keyboard-trap") + keyboardAccessibilityUtils.verifyElementsDoNotCauseKeyboardTrap(".ex-no-keyboard-trap") */ verifyElementsDoNotCauseKeyboardTrap: function(selector) { const els = document.querySelectorAll(selector); @@ -111,14 +117,13 @@ const KeyboardAccessibilityUtils = { el.focus(); assert_equals(document.activeElement, el, "precondition: el is currently focused"); el.parentNode.insertBefore(focusablePreviousElement, el); - await test_driver.send_keys(el, "\uE004" + "\uE008"); + await test_driver.send_keys(el, keys.ShiftAndTab); assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, "\uE004"); // \uE004 is the Tab key (see WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions) + await test_driver.send_keys(focusablePreviousElement, keys.Tab); assert_equals(document.activeElement, el, "el has successfully lost and received focus, and is now focused"); document.body.removeChild(focusablePreviousElement); }, `${testName}`); } }, -}; - +}; \ No newline at end of file From 2ece4ca340b7dcee43dbb71f1d420fc6402e7905 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Wed, 31 Jan 2024 23:49:38 -0800 Subject: [PATCH 11/22] More key related changes --- common/keyboard-accessibility-utils.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index 9cfee45b048fbb..a41c8c6b3ecd41 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -2,8 +2,8 @@ const keys = { // See WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions + "LeftShiftAndTab": "\uE008" + "\uE004", // Left Shift = \uE008 and Right Shift = \uE050 however, they should be indistinguishable "Tab": "\uE004", - "ShiftAndTab": "\uE008" + "\uE004", }; const keyboardAccessibilityUtils = { @@ -13,15 +13,15 @@ const keyboardAccessibilityUtils = { receive focus (and related) events. Ex:
+ tabindex="0" + data-testname="div with role button and tabindex is focusable" + class="ex">
keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") */ verifyElementsAreFocusable: function(selector) { - const els = document.querySelectorAll(selector); + const els = document.querySelectorAll(selector); if (!els.length) { throw `Selector passed in verifyElementsAreFocusable("${selector}") should match at least one element.`; } @@ -39,8 +39,8 @@ const keyboardAccessibilityUtils = { are currently focused at the point of test execution. Ex: keyboardAccessibilityUtils.verifyElementIsFocused(".ex-focused") @@ -117,10 +117,10 @@ const keyboardAccessibilityUtils = { el.focus(); assert_equals(document.activeElement, el, "precondition: el is currently focused"); el.parentNode.insertBefore(focusablePreviousElement, el); - await test_driver.send_keys(el, keys.ShiftAndTab); + await test_driver.send_keys(el, keys.LeftShiftAndTab); assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, keys.Tab); + await test_driver.send_keys(focusablePreviousElement, keys.LeftShiftAndTab); assert_equals(document.activeElement, el, "el has successfully lost and received focus, and is now focused"); document.body.removeChild(focusablePreviousElement); }, `${testName}`); From 1f8c36a62de95cbdc6481b0161a3d862be9542b9 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Wed, 31 Jan 2024 23:51:29 -0800 Subject: [PATCH 12/22] Minor key reference update --- common/keyboard-accessibility-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index a41c8c6b3ecd41..af6f5fa44d3dc1 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -120,7 +120,7 @@ const keyboardAccessibilityUtils = { await test_driver.send_keys(el, keys.LeftShiftAndTab); assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, keys.LeftShiftAndTab); + await test_driver.send_keys(focusablePreviousElement, keys.Tab); assert_equals(document.activeElement, el, "el has successfully lost and received focus, and is now focused"); document.body.removeChild(focusablePreviousElement); }, `${testName}`); From d69c461ebcc0ded755fa1e7f6be18ab17a235cd0 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Thu, 1 Feb 2024 00:29:14 -0800 Subject: [PATCH 13/22] Fix documentation references --- common/keyboard-accessibility-utils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index af6f5fa44d3dc1..0f587148361720 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -15,7 +15,7 @@ const keyboardAccessibilityUtils = { Ex:
+ class="ex-focusable">
keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") @@ -38,8 +38,8 @@ const keyboardAccessibilityUtils = { Tests that all elements matching selector are currently focused at the point of test execution. - Ex: From 95ad8a4816a40e5818148106a94456b2ac5e0590 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Thu, 1 Feb 2024 09:17:03 -0800 Subject: [PATCH 14/22] Remove extraneous comment --- common/keyboard-accessibility-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js index 0f587148361720..336c9613b196d3 100644 --- a/common/keyboard-accessibility-utils.js +++ b/common/keyboard-accessibility-utils.js @@ -85,7 +85,7 @@ const keyboardAccessibilityUtils = { focusablePreviousElement.focus(); assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, keys.Tab); // + await test_driver.send_keys(focusablePreviousElement, keys.Tab); assert_equals(document.activeElement, el, "Element is tabbable"); document.body.removeChild(focusablePreviousElement); }, `${testName}`); From 8e9dc0e78534f80c460a5ca664fbeb0db623b730 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Thu, 1 Feb 2024 09:44:40 -0800 Subject: [PATCH 15/22] Change filename, keyboard-accessibility-utils.js -> keyboard-utils.js --- common/keyboard-utils.js | 129 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 common/keyboard-utils.js diff --git a/common/keyboard-utils.js b/common/keyboard-utils.js new file mode 100644 index 00000000000000..7024239b98a2f0 --- /dev/null +++ b/common/keyboard-utils.js @@ -0,0 +1,129 @@ +/* Utilities for keyboard-focused accessibility */ + +const keys = { + // See WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions + "LeftShiftAndTab": "\uE008" + "\uE004", // Left Shift = \uE008 and Right Shift = \uE050 however, they should be indistinguishable + "Tab": "\uE004", +}; + +const keyboardAccessibilityUtils = { + + /* + Tests that all elements matching selector can + receive focus (and related) events. + + Ex:
+
+ + keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") + */ + verifyElementsAreFocusable: function(selector) { + const els = document.querySelectorAll(selector); + if (!els.length) { + throw `Selector passed in verifyElementsAreFocusable("${selector}") should match at least one element.`; + } + for (const el of els) { + let testName = el.getAttribute("data-testname"); + test(() => { + el.focus(); + assert_equals(document.activeElement, el, "Element is focusable with element.focus()"); + }, `${testName}`); + } + }, + + /* + Tests that all elements matching selector + are currently focused at the point of test execution. + + Ex: + + keyboardAccessibilityUtils.verifyElementIsFocused(".ex-focused") + */ + verifyElementIsFocused: function(selector) { + const els = document.querySelectorAll(selector); + if (!els.length) { + throw `Selector passed in verifyElementIsFocused("${selector}") should match at least one element.`; + } + for (const el of els) { + let testName = el.getAttribute("data-testname"); + test(() => { + assert_equals(document.activeElement, el, "Element is currently focused"); + }, `${testName}`); + } + }, + + + /* + Tests that all elements matching selector are + tabbable, i.e., present in the keyboard tab order. + + Ex: + + keyboardAccessibilityUtils.verifyElementsAreTabbable(".ex-tabbable") + */ + verifyElementsAreTabbable: function(selector) { + const els = document.querySelectorAll(selector); + const focusablePreviousElement = document.createElement("a"); + focusablePreviousElement.setAttribute("href", "#"); + focusablePreviousElement.appendChild(document.createTextNode("a focusable link")); + if (!els.length) { + throw `Selector passed in verifyElementsAreTabbable("${selector}") should match at least one element.`; + } + for (const el of els) { + let testName = el.getAttribute("data-testname"); + promise_test(async t => { + el.parentNode.insertBefore(focusablePreviousElement, el); + focusablePreviousElement.focus(); + assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); + assert_not_equals(document.activeElement, el, "precondition: el is not focused"); + await test_driver.send_keys(focusablePreviousElement, keys.Tab); + assert_equals(document.activeElement, el, "Element is tabbable"); + document.body.removeChild(focusablePreviousElement); + }, `${testName}`); + } + }, + + /* + Tests that all elements matching selector are + tabbable and do not create a focus trap. + + Ex: + + keyboardAccessibilityUtils.verifyElementsDoNotCauseKeyboardTrap(".ex-no-keyboard-trap") + */ + verifyElementsDoNotCauseKeyboardTrap: function(selector) { + const els = document.querySelectorAll(selector); + const focusablePreviousElement = document.createElement("a"); + focusablePreviousElement.setAttribute("href", "#"); + focusablePreviousElement.appendChild(document.createTextNode("a focusable link")); + if (!els.length) { + throw `Selector passed in verifyElementsDoNotCauseKeyboardTrap("${selector}") should match at least one element.`; + } + for (const el of els) { + let testName = el.getAttribute("data-testname"); + promise_test(async t => { + el.focus(); + assert_equals(document.activeElement, el, "precondition: el is currently focused"); + el.parentNode.insertBefore(focusablePreviousElement, el); + await test_driver.send_keys(el, keys.LeftShiftAndTab); + assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); + assert_not_equals(document.activeElement, el, "precondition: el is not focused"); + await test_driver.send_keys(focusablePreviousElement, keys.Tab); + assert_equals(document.activeElement, el, "el has successfully lost and received focus, and is now focused"); + document.body.removeChild(focusablePreviousElement); + }, `${testName}`); + } + }, +}; \ No newline at end of file From dfa528a4b999f3041b3036693e5e013541a02d2e Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Thu, 1 Feb 2024 09:56:23 -0800 Subject: [PATCH 16/22] Remove accessibility references --- common/keyboard-utils.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/common/keyboard-utils.js b/common/keyboard-utils.js index 7024239b98a2f0..8ac656de1ccc4d 100644 --- a/common/keyboard-utils.js +++ b/common/keyboard-utils.js @@ -1,4 +1,4 @@ -/* Utilities for keyboard-focused accessibility */ +/* Utilities for keyboard testing */ const keys = { // See WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions @@ -6,7 +6,7 @@ const keys = { "Tab": "\uE004", }; -const keyboardAccessibilityUtils = { +const keyboardUtils = { /* Tests that all elements matching selector can @@ -18,7 +18,7 @@ const keyboardAccessibilityUtils = { class="ex-focusable"> - keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") + keyboardUtils.verifyElementsAreFocusable(".ex-focusable") */ verifyElementsAreFocusable: function(selector) { const els = document.querySelectorAll(selector); @@ -43,7 +43,7 @@ const keyboardAccessibilityUtils = { class="ex-focused"> - keyboardAccessibilityUtils.verifyElementIsFocused(".ex-focused") + keyboardUtils.verifyElementIsFocused(".ex-focused") */ verifyElementIsFocused: function(selector) { const els = document.querySelectorAll(selector); @@ -68,7 +68,7 @@ const keyboardAccessibilityUtils = { class="ex-tabbable"> - keyboardAccessibilityUtils.verifyElementsAreTabbable(".ex-tabbable") + keyboardUtils.verifyElementsAreTabbable(".ex-tabbable") */ verifyElementsAreTabbable: function(selector) { const els = document.querySelectorAll(selector); @@ -101,7 +101,7 @@ const keyboardAccessibilityUtils = { class="ex-no-keyboard-trap"> - keyboardAccessibilityUtils.verifyElementsDoNotCauseKeyboardTrap(".ex-no-keyboard-trap") + keyboardUtils.verifyElementsDoNotCauseKeyboardTrap(".ex-no-keyboard-trap") */ verifyElementsDoNotCauseKeyboardTrap: function(selector) { const els = document.querySelectorAll(selector); From 54de2703793caa87d7285d5353ed94e8a3d88415 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Thu, 1 Feb 2024 09:57:06 -0800 Subject: [PATCH 17/22] Remove keyboard-accessibility-utils.js --- common/keyboard-accessibility-utils.js | 129 ------------------------- 1 file changed, 129 deletions(-) delete mode 100644 common/keyboard-accessibility-utils.js diff --git a/common/keyboard-accessibility-utils.js b/common/keyboard-accessibility-utils.js deleted file mode 100644 index 336c9613b196d3..00000000000000 --- a/common/keyboard-accessibility-utils.js +++ /dev/null @@ -1,129 +0,0 @@ -/* Utilities for keyboard-focused accessibility */ - -const keys = { - // See WebDriver key codepoints: https://w3c.github.io/webdriver/#keyboard-actions - "LeftShiftAndTab": "\uE008" + "\uE004", // Left Shift = \uE008 and Right Shift = \uE050 however, they should be indistinguishable - "Tab": "\uE004", -}; - -const keyboardAccessibilityUtils = { - - /* - Tests that all elements matching selector can - receive focus (and related) events. - - Ex:
-
- - keyboardAccessibilityUtils.verifyElementsAreFocusable(".ex-focusable") - */ - verifyElementsAreFocusable: function(selector) { - const els = document.querySelectorAll(selector); - if (!els.length) { - throw `Selector passed in verifyElementsAreFocusable("${selector}") should match at least one element.`; - } - for (const el of els) { - let testName = el.getAttribute("data-testname"); - test(() => { - el.focus(); - assert_equals(document.activeElement, el, "Element is focusable with element.focus()"); - }, `${testName}`); - } - }, - - /* - Tests that all elements matching selector - are currently focused at the point of test execution. - - Ex: - - keyboardAccessibilityUtils.verifyElementIsFocused(".ex-focused") - */ - verifyElementIsFocused: function(selector) { - const els = document.querySelectorAll(selector); - if (!els.length) { - throw `Selector passed in verifyElementIsFocused("${selector}") should match at least one element.`; - } - for (const el of els) { - let testName = el.getAttribute("data-testname"); - test(() => { - assert_equals(document.activeElement, el, "Element is currently focused"); - }, `${testName}`); - } - }, - - - /* - Tests that all elements matching selector are - tabbable, i.e., present in the keyboard tab order. - - Ex: - - keyboardAccessibilityUtils.verifyElementsAreTabbable(".ex-tabbable") - */ - verifyElementsAreTabbable: function(selector) { - const els = document.querySelectorAll(selector); - const focusablePreviousElement = document.createElement("a"); - focusablePreviousElement.setAttribute("href", "#"); - focusablePreviousElement.appendChild(document.createTextNode("a focusable link")); - if (!els.length) { - throw `Selector passed in verifyElementsAreTabbable("${selector}") should match at least one element.`; - } - for (const el of els) { - let testName = el.getAttribute("data-testname"); - promise_test(async t => { - el.parentNode.insertBefore(focusablePreviousElement, el); - focusablePreviousElement.focus(); - assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); - assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, keys.Tab); - assert_equals(document.activeElement, el, "Element is tabbable"); - document.body.removeChild(focusablePreviousElement); - }, `${testName}`); - } - }, - - /* - Tests that all elements matching selector are - tabbable and do not create a focus trap. - - Ex: - - keyboardAccessibilityUtils.verifyElementsDoNotCauseKeyboardTrap(".ex-no-keyboard-trap") - */ - verifyElementsDoNotCauseKeyboardTrap: function(selector) { - const els = document.querySelectorAll(selector); - const focusablePreviousElement = document.createElement("a"); - focusablePreviousElement.setAttribute("href", "#"); - focusablePreviousElement.appendChild(document.createTextNode("a focusable link")); - if (!els.length) { - throw `Selector passed in verifyElementsDoNotCauseKeyboardTrap("${selector}") should match at least one element.`; - } - for (const el of els) { - let testName = el.getAttribute("data-testname"); - promise_test(async t => { - el.focus(); - assert_equals(document.activeElement, el, "precondition: el is currently focused"); - el.parentNode.insertBefore(focusablePreviousElement, el); - await test_driver.send_keys(el, keys.LeftShiftAndTab); - assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); - assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, keys.Tab); - assert_equals(document.activeElement, el, "el has successfully lost and received focus, and is now focused"); - document.body.removeChild(focusablePreviousElement); - }, `${testName}`); - } - }, -}; \ No newline at end of file From 2f1f4bb0a5df24add2cecab9ce03abfdced708f3 Mon Sep 17 00:00:00 2001 From: Rahim Abdi Date: Thu, 1 Feb 2024 10:06:34 -0800 Subject: [PATCH 18/22] Change tabbable/focusable to tab focusable/script focusable --- common/keyboard-utils.js | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/common/keyboard-utils.js b/common/keyboard-utils.js index 8ac656de1ccc4d..bf4262a2ea9ba2 100644 --- a/common/keyboard-utils.js +++ b/common/keyboard-utils.js @@ -15,15 +15,15 @@ const keyboardUtils = { Ex:
+ class="ex-script-focusable">
- keyboardUtils.verifyElementsAreFocusable(".ex-focusable") + keyboardUtils.verifyElementsAreScriptFocusable(".ex-script-focusable") */ - verifyElementsAreFocusable: function(selector) { + verifyElementsAreScriptFocusable: function(selector) { const els = document.querySelectorAll(selector); if (!els.length) { - throw `Selector passed in verifyElementsAreFocusable("${selector}") should match at least one element.`; + throw `Selector passed in verifyElementsAreScriptFocusable("${selector}") should match at least one element.`; } for (const el of els) { let testName = el.getAttribute("data-testname"); @@ -61,40 +61,40 @@ const keyboardUtils = { /* Tests that all elements matching selector are - tabbable, i.e., present in the keyboard tab order. + tab focusable, i.e., present in the keyboard tab order. Ex: - keyboardUtils.verifyElementsAreTabbable(".ex-tabbable") + keyboardUtils.verifyElementsAreTabFocusable(".ex-tab-focusable") */ - verifyElementsAreTabbable: function(selector) { + verifyElementsAreTabFocusable: function(selector) { const els = document.querySelectorAll(selector); - const focusablePreviousElement = document.createElement("a"); - focusablePreviousElement.setAttribute("href", "#"); - focusablePreviousElement.appendChild(document.createTextNode("a focusable link")); + const focusablePreviousLinkElement = document.createElement("a"); + focusablePreviousLinkElement.setAttribute("href", "#"); + focusablePreviousLinkElement.appendChild(document.createTextNode("a focusable link")); if (!els.length) { - throw `Selector passed in verifyElementsAreTabbable("${selector}") should match at least one element.`; + throw `Selector passed in verifyElementsAreTabFocusable("${selector}") should match at least one element.`; } for (const el of els) { let testName = el.getAttribute("data-testname"); promise_test(async t => { - el.parentNode.insertBefore(focusablePreviousElement, el); - focusablePreviousElement.focus(); - assert_equals(document.activeElement, focusablePreviousElement, "precondition: el's previous focusable element is currently focused"); + el.parentNode.insertBefore(focusablePreviousLinkElement, el); + focusablePreviousLinkElement.focus(); + assert_equals(document.activeElement, focusablePreviousLinkElement, "precondition: el's previous focusable element is currently focused"); assert_not_equals(document.activeElement, el, "precondition: el is not focused"); - await test_driver.send_keys(focusablePreviousElement, keys.Tab); - assert_equals(document.activeElement, el, "Element is tabbable"); - document.body.removeChild(focusablePreviousElement); + await test_driver.send_keys(focusablePreviousLinkElement, keys.Tab); + assert_equals(document.activeElement, el, "Element is tab focusable"); + document.body.removeChild(focusablePreviousLinkElement); }, `${testName}`); } }, /* Tests that all elements matching selector are - tabbable and do not create a focus trap. + tab focusable and do not create a focus trap. Ex: + x + + + + x + x + x + + + + + \ No newline at end of file