summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-toggle/toggle-aria-roles.tentative.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/css/css-toggle/toggle-aria-roles.tentative.html
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-toggle/toggle-aria-roles.tentative.html')
-rw-r--r--testing/web-platform/tests/css/css-toggle/toggle-aria-roles.tentative.html453
1 files changed, 453 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-toggle/toggle-aria-roles.tentative.html b/testing/web-platform/tests/css/css-toggle/toggle-aria-roles.tentative.html
new file mode 100644
index 0000000000..9ba545f21a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-toggle/toggle-aria-roles.tentative.html
@@ -0,0 +1,453 @@
+<!DOCTYPE HTML>
+<meta charset="UTF-8">
+<title>CSS Toggles: ARIA roles and inferred keyboard handling</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://tabatkins.github.io/css-toggle/">
+<link rel="help" href="https://github.com/tabatkins/css-toggle/issues/41">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="support/toggle-helpers.js"></script>
+<style>
+
+/* for send_keys */
+div { min-height: 10px }
+
+</style>
+
+<body>
+
+<div id="container"></div>
+<script>
+
+let aria_role_tests = [
+ // Markup to create the test assertions:
+ // data-expected-role: The expected aria role for this element.
+ // data-expected-trigger-keys: When present, indicates that keyboard events
+ // should be tested on this element, and indicates the keys
+ // (space-separated) that are expected to toggle the toggle.
+ // data-expected-arrows-between-children: When present, indicates
+ // that arrow keys should navigate between the children of this
+ // element that have the given role.
+ //
+ // Helper markup to create more markup:
+ // class=group: group the group with the toggle-group property
+ // class=group-self: same, but with the self keyword (narrow scope)
+ // class=root: create a test-role toggle with the toggle-root property
+ // class=root-group: same, but with the 'group' keyword
+ // class=root-self: same, but with the 'self' keyword
+ // class=trigger: toggle-trigger to activate test-role toggle
+ // class=visibility: toggle-visibility connected to test-role toggle
+ `
+ <div></div>
+ `,
+ `
+ <div class="root">
+ <div></div>
+ </div>
+ `,
+ `
+ <div class="root trigger" data-expected-role="checkbox"></div>
+ `,
+ // Test that ARIA attributes override the toggle inference:
+ `
+ <div class="root trigger" role="link" data-expected-role="link"></div>
+ `,
+ `
+ <div class="root">
+ <div class="trigger" data-expected-role="button"></div>
+ </div>
+ `,
+
+ // Radios and radio groups:
+ `
+ <div class="group" data-expected-role="radiogroup">
+ <div class="root-group trigger" data-expected-role="radio" data-expected-trigger-keys="Space"></div>
+ </div>
+ `,
+ `
+ <div class="group" data-expected-role="radiogroup" data-expected-arrows-between-children="radio">
+ <div class="root-group trigger" data-expected-role="radio" data-expected-trigger-keys="Space"></div>
+ <div class="root-group trigger" data-expected-role="radio" data-expected-trigger-keys="Space"></div>
+ </div>
+ `,
+ `
+ <div>
+ <div class="root-group trigger" data-expected-role="radio"></div>
+ </div>
+ `,
+ `
+ <div style="toggle-group: another-group">
+ <div class="root-group trigger" data-expected-role="radio"></div>
+ </div>
+ `,
+ `
+ <div style="toggle-group: another-group, test-role, third-group" data-expected-role="radiogroup">
+ <div class="root-group trigger" data-expected-role="radio"></div>
+ </div>
+ `,
+
+
+ // Checkboxes and checkbox groups:
+ `
+ <div>
+ <div class="root trigger" data-expected-role="checkbox" data-expected-trigger-keys="Space"></div>
+ </div>
+ `,
+ // TODO(https://crbug.com/1250716): This is a checkbox group... but we
+ // can't distinguish that with current ARIA roles.
+ `
+ <div data-expected-arrows-between-children="checkbox">
+ <div class="root trigger" data-expected-role="checkbox" data-expected-trigger-keys="Space"></div>
+ <div class="root trigger" data-expected-role="checkbox" data-expected-trigger-keys="Space"></div>
+ </div>
+ `,
+
+ // Disclosure:
+ // TODO(https://crbug.com/1250716): This is a disclosure... but how is
+ // it possible to distinguish with ARIA roles (compare to next test!)?
+ `
+ <div class="root">
+ <div class="trigger" data-expected-role="button" data-expected-trigger-keys="Space Enter"></div>
+ <div class="visibility"></div>
+ </div>
+ `,
+ // This is not a disclosure because it has a toggle-group.
+ `
+ <div class="root-group">
+ <div class="trigger" data-expected-role="button" data-expected-trigger-keys="Space Enter"></div>
+ <div class="visibility"></div>
+ </div>
+ `,
+ // This is button with popup (absolute positioning)
+ // TODO(https://crbug.com/1250716): This test doesn't actually
+ // distinguish this from disclosure because the internal kPopUpButton
+ // role maps to "button" in kReverseRoles in ax_object.cc.
+ `
+ <div class="root">
+ <div class="trigger" data-expected-role="button"></div>
+ <div class="visibility" style="position: absolute"></div>
+ </div>
+ `,
+ // This is button with popup (fixed positioning)
+ // TODO(https://crbug.com/1250716): This test doesn't actually
+ // distinguish this from disclosure because the internal kPopUpButton
+ // role maps to "button" in kReverseRoles in ax_object.cc.
+ `
+ <div class="root">
+ <div class="trigger" data-expected-role="button" data-expected-trigger-keys="Space Enter"></div>
+ <div class="visibility" style="position: fixed"></div>
+ </div>
+ `,
+ // This is button with popup (popover)
+ // TODO(https://crbug.com/1250716): This test doesn't actually
+ // distinguish this from disclosure because the internal kPopUpButton
+ // role maps to "button" in kReverseRoles in ax_object.cc.
+ `
+ <div class="root">
+ <div class="trigger" data-expected-role="button" data-expected-trigger-keys="Space Enter"></div>
+ <div class="visibility" popover="auto"></div>
+ </div>
+ `,
+ // This is disclosure (NOT button with popup) (sticky positioning)
+ `
+ <div class="root">
+ <div class="trigger" data-expected-role="button" data-expected-trigger-keys="Space Enter"></div>
+ <div class="visibility" style="position: sticky"></div>
+ </div>
+ `,
+
+ // Accordion:
+ `
+ <div class="group">
+ <div class="root-group" data-expected-role="region">
+ <div class="trigger" data-expected-role="button"></div>
+ <div class="visibility"></div>
+ </div>
+ <div class="root-group" data-expected-role="region">
+ <div class="trigger" data-expected-role="button"></div>
+ <div class="visibility"></div>
+ </div>
+ </div>
+ `,
+ // Not accordion because of other siblings:
+ `
+ <div class="group">
+ <div class="root-group">
+ <div class="trigger" data-expected-role="button"></div>
+ <div class="visibility"></div>
+ </div>
+ <div class="root-group">
+ <div class="trigger" data-expected-role="button"></div>
+ <div class="visibility"></div>
+ </div>
+ <div></div>
+ <div></div>
+ <div></div>
+ </div>
+ `,
+
+ // Tree:
+ // TODO(https://crbug.com/1250716): This should probably also work
+ // with the toggles on the <button>!
+ // TODO(https://crbug.com/1250716): This should probably mark the
+ // non-interactive items as treeitem as well!
+ // TODO(https://crbug.com/1250716): Do the elements getting the roles
+ // here make sense?
+ // TODO(https://crbug.com/1250716): The requirement for having
+ // multiple disclosure-ish children to qualify as accordion-ish
+ // probably doesn't make sense here. The test below is basically the
+ // minimal example that gets detected as a tree, but simpler things
+ // definitely should be!
+ // TODO(https://crbug.com/1250716): The inner parts of the tree should
+ // also be getting tree roles!
+ `
+ <ul data-expected-role="tree">
+ <li class="root-self" data-expected-role="group">
+ <button class="trigger" data-expected-role="treeitem"></button>
+ <ul class="visibility" data-expected-role="list">
+ <li>item</li>
+ <li class="root-self">
+ <button class="trigger" data-expected-role="button"></button>
+ <ul class="visibility" data-expected-role="list">
+ <li>item</li>
+ <li>item</li>
+ </ul>
+ </li>
+ <li class="root-self">
+ <button class="trigger" data-expected-role="button"></button>
+ <ul class="visibility" data-expected-role="list">
+ <li>item</li>
+ <li>item</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li class="root-self" data-expected-role="group">
+ <button class="trigger" data-expected-role="treeitem"></button>
+ <ul class="visibility" data-expected-role="list">
+ <li class="root-self">
+ <button class="trigger" data-expected-role="button"></button>
+ <ul class="visibility" data-expected-role="list">
+ <li>item</li>
+ <li>item</li>
+ </ul>
+ </li>
+ <li class="root-self">
+ <button class="trigger" data-expected-role="button"></button>
+ <ul class="visibility" data-expected-role="list">
+ <li>item</li>
+ <li>item</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ `,
+
+ // Tabs:
+ `
+ <section class="group" data-expected-role="tablist" data-expected-arrows-between-children="tab">
+ <h1 class="root-group trigger" data-expected-role="tab" data-expected-trigger-keys="Space Enter"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <h1 class="root-group trigger" data-expected-role="tab" data-expected-trigger-keys="Space Enter"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <h1 class="root-group trigger" data-expected-role="tab" data-expected-trigger-keys="Space Enter"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ </section>
+ `,
+ `
+ <section class="group" data-expected-role="tablist">
+ <h1 class="root-group trigger" data-expected-role="tab"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <h1 class="root-group trigger" data-expected-role="tab"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <div></div>
+ </section>
+ `,
+ `
+ <section class="group" data-expected-role="tablist">
+ <h1 class="root-group trigger" data-expected-role="tab"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <h1 class="root-group trigger" data-expected-role="tab"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <h1 style="toggle-root: other-toggle; toggle-trigger: other-toggle" data-expected-role="checkbox"></h1>
+ </section>
+ `,
+ `
+ <section class="group" data-expected-role="tablist">
+ <h1 class="root-group trigger" data-expected-role="tab"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <h1 class="root-group trigger" data-expected-role="tab"></h1>
+ <div class="visibility" data-expected-role="tabpanel"></div>
+ <h1 style="toggle-root: other-toggle; toggle-trigger: other-toggle" data-expected-role="button"></h1>
+ <div style="toggle-visibility: toggle other-toggle"></div>
+ </section>
+ `,
+ // TODO(https://crbug.com/758089): The expected role for the <section>
+ // should be generic rather than null!
+ `
+ <section class="group" data-expected-role="null">
+ <h1 class="root-group trigger" data-expected-role="button"></h1>
+ <div class="visibility"></div>
+ <h1 class="root-group trigger" data-expected-role="button"></h1>
+ <div class="visibility"></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ </section>
+ `,
+ `
+ <section class="group" data-expected-role="radiogroup">
+ <h1 class="root-group trigger" data-expected-role="radio"></h1>
+ <h1 class="root-group trigger" data-expected-role="radio"></h1>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ </section>
+ `,
+];
+
+function find_toggle_in_scope(e) {
+ let allow_self = true;
+ while (e) {
+ let toggle = e.toggles.get("test-role");
+ if (toggle && (allow_self || toggle.scope == "wide"))
+ return toggle;
+ let sibling = e.previousElementSibling;
+ if (sibling) {
+ e = sibling;
+ allow_self = false;
+ }
+ e = e.parentNode;
+ allow_self = true;
+ }
+ return null;
+}
+
+for (let t of aria_role_tests) {
+ promise_test(async function() {
+ container.innerHTML = t;
+
+ for (let e of container.querySelectorAll('.group')) {
+ e.style.toggleGroup = "test-role";
+ }
+ for (let e of container.querySelectorAll('.group-self')) {
+ e.style.toggleGroup = "test-role self";
+ }
+ for (let e of container.querySelectorAll('.root')) {
+ e.style.toggleRoot = "test-role";
+ }
+ for (let e of container.querySelectorAll('.root-group')) {
+ e.style.toggleRoot = "test-role group";
+ }
+ for (let e of container.querySelectorAll('.root-self')) {
+ e.style.toggleRoot = "test-role self";
+ }
+ for (let e of container.querySelectorAll('.trigger')) {
+ e.style.toggleTrigger = "test-role";
+ }
+ for (let e of container.querySelectorAll('.visibility')) {
+ e.style.toggleVisibility = "toggle test-role";
+ }
+
+ for (let e of container.querySelectorAll('.root, .root-nogroup')) {
+ await wait_for_toggle_creation(e);
+ }
+
+ let count = 0;
+ for (let e of container.querySelectorAll("*")) {
+ if (e == container)
+ continue;
+
+ let expected_role = "generic";
+ if (e.hasAttribute("data-expected-role")) {
+ expected_role = e.getAttribute("data-expected-role");
+ // TODO(https://crbug.com/758089): See above regarding <section>;
+ // this null handling should eventually be removed.
+ if (expected_role === "null") {
+ expected_role = null;
+ }
+ }
+ ++count;
+ // NOTE: This relies on Element.computedRole, which is an
+ // experimental feature behind the ComputedAccessibilityInfo flag
+ // in blink.
+ assert_equals(e.computedRole, expected_role, `role on ${e.tagName} element (#${count})`);
+ }
+
+ if (container.querySelector("[data-expected-arrows-between-children], [data-expected-trigger-keys]")) {
+ // We should do keyboard tests for this test.
+ for (let e of container.querySelectorAll("*")) {
+ if (e == container)
+ continue;
+
+ let arrows = e.parentNode.hasAttribute("data-expected-arrows-between-children") && e.getAttribute("data-expected-role") == e.parentNode.getAttribute("data-expected-arrows-between-children");
+ let trigger_keys = [];
+ if (e.hasAttribute("data-expected-trigger-keys")) {
+ trigger_keys = e.getAttribute("data-expected-trigger-keys").split(" ");
+ }
+
+ if (!e.classList.contains("trigger")) {
+ // It is a bug in the test to have expected key handling for elements
+ // that are not toggle triggers.
+ assert_false(arrows);
+ assert_equals(trigger_keys.length, 0);
+ continue;
+ }
+
+ // Test handling of space, enter, and all arrows, and check that
+ // it matches expectations.
+ let keys_to_test = {
+ "Enter": "\uE007",
+ // better known as " ", but "Space" in this test.
+ // https://w3c.github.io/webdriver/#keyboard-actions says
+ // "\uE00D" but that doesn't work.
+ "Space": " ",
+ "ArrowLeft": "\uE012",
+ "ArrowUp": "\uE013",
+ "ArrowRight": "\uE014",
+ "ArrowDown": "\uE015",
+ };
+ for (let key in keys_to_test) {
+ let toggle = find_toggle_in_scope(e);
+ let expected_state = toggle.valueAsNumber;
+ e.focus();
+ let expected_focus = e;
+ assert_equals(document.activeElement, expected_focus, `focus before ${key} key`);
+ await test_driver.send_keys(document.body, keys_to_test[key]);
+ if (trigger_keys.includes(key)) {
+ expected_state = expected_state ? 0 : 1;
+ }
+ if (key.startsWith("Arrow")) {
+ if (arrows) {
+ let role = e.parentNode.getAttribute("data-expected-arrows-between-children");
+ let direction;
+ if (key == "ArrowLeft" || key == "ArrowUp") {
+ direction = "previousElementSibling";
+ } else {
+ direction = "nextElementSibling";
+ }
+ let new_element = e;
+ while ((new_element = new_element[direction])) {
+ if (new_element.getAttribute("data-expected-role") == role)
+ break;
+ }
+ if (new_element)
+ expected_focus = new_element;
+ }
+ }
+ assert_equals(toggle.valueAsNumber, expected_state, `state after ${key} key`);
+ assert_equals(document.activeElement, expected_focus, `focus after ${key} key`);
+ }
+ }
+ }
+
+ }, `aria role and key handling test: ${t}`);
+}
+
+</script>