| /* Utilities related to WAI-ARIA */ |
| |
| const AriaUtils = { |
| |
| /* |
| Tests simple role assignment: <div role="alert">x</div> |
| Not intended for nested, context-dependent, or other complex role tests. |
| |
| Ex: AriaUtils.assignAndVerifyRolesByRoleNames(["group", "main", "button"]) |
| |
| */ |
| assignAndVerifyRolesByRoleNames: function(roleNames) { |
| if (!Array.isArray(roleNames) || !roleNames.length) { |
| throw `Param roleNames of assignAndVerifyRolesByRoleNames("${roleNames}") should be an array containing at least one role string.`; |
| } |
| for (const role of roleNames) { |
| promise_test(async t => { |
| let el = document.createElement("div"); |
| el.appendChild(document.createTextNode("x")); |
| el.setAttribute("role", role); // el.role not yet supported by Gecko. |
| document.body.appendChild(el); |
| const computedRole = await test_driver.get_computed_role(el); |
| assert_equals(computedRole, role, el.outerHTML); |
| }, `role: ${role}`); |
| } |
| }, |
| |
| |
| /* |
| Tests computed ROLE of all elements matching selector |
| against the string value of their data-expectedrole attribute. |
| |
| Ex: <div role="list" |
| data-testname="optional unique test name" |
| data-expectedrole="list" |
| class="ex"> |
| |
| AriaUtils.verifyRolesBySelector(".ex") |
| |
| */ |
| verifyRolesBySelector: function(selector) { |
| const els = document.querySelectorAll(selector); |
| if (!els.length) { |
| throw `Selector passed in verifyRolesBySelector("${selector}") should match at least one element.`; |
| } |
| for (const el of els) { |
| let role = el.getAttribute("data-expectedrole"); |
| let testName = el.getAttribute("data-testname") || role; // data-testname optional if role is unique per test file |
| promise_test(async t => { |
| const expectedRole = el.getAttribute("data-expectedrole"); |
| const computedRole = await test_driver.get_computed_role(el); |
| assert_equals(computedRole, expectedRole, el.outerHTML); |
| }, `${testName}`); |
| } |
| }, |
| |
| |
| /* |
| Tests computed ROLE of selected elements matching selector |
| against the string value of provided roles array. |
| |
| Ex: <foo |
| data-testname="verify fooRole or barRole role on span" |
| class="ex-foo-or-bar"> |
| |
| AriaUtils.verifyRoleOrVariantRolesBySelector(".ex-foo-or-bar", ["fooRole", "barRole"]); |
| |
| See also helper function verifyGenericRolesBySelector shorthand of the above using ["generic", "", "none"]. |
| |
| Note: This function should not be used to circumvent unexpected interop differences in implementations. |
| It should only be used in specific cases (like "generic") determined by ARIA WG or other spec maintainers to be acceptable for the purposes of testing. |
| |
| */ |
| verifyRoleOrVariantRolesBySelector: function(selector, roles) { |
| const els = document.querySelectorAll(selector); |
| if (!els.length) { |
| throw `Selector "${selector}" should match at least one element.`; |
| } |
| if (!roles.length || roles.length < 2) { |
| throw `Roles array ["${roles.join('", "')}"] should include at least two strings, a primary role and at least one acceptable implementation-specific variant. E.g. ["generic", "", "none"]…`; |
| } |
| for (const el of els) { |
| let testName = el.getAttribute("data-testname"); |
| promise_test(async t => { |
| const expectedRoles = roles; |
| const computedRole = await test_driver.get_computed_role(el); |
| for (role of roles){ |
| if (computedRole === role) { |
| return assert_equals(computedRole, role, `Computed Role: "${computedRole}" matches one of the acceptable role strings in ["${roles.join('", "')}"]: ${el.outerHTML}`); |
| } |
| } |
| return assert_false(true, `Computed Role: "${computedRole}" does not match any of the acceptable role strings in ["${roles.join('", "')}"]: ${el.outerHTML}`); |
| }, `${testName}`); |
| } |
| }, |
| |
| |
| /* |
| Helper function for "generic" ROLE tests. |
| |
| Ex: <span |
| data-testname="verify generic, none, or empty computed role on span" |
| class="ex-generic"> |
| |
| AriaUtils.verifyGenericRolesBySelector(".ex-generic"); |
| |
| This helper function is equivalant to AriaUtils.verifyRoleOrVariantRolesBySelector(".ex-generic", ["generic", "", "none"]); |
| See various issues and discussions linked from https://github.com/web-platform-tests/interop-2023-accessibility-testing/issues/48 |
| |
| */ |
| verifyGenericRolesBySelector: function(selector) { |
| // ARIA WG determined implementation variants "none" (Chromium), and the empty string "" (WebKit), are sufficiently equivalent to "generic" for WPT test verification of HTML-AAM. |
| // See various discussions linked from https://github.com/web-platform-tests/interop-2023-accessibility-testing/issues/48 |
| this.verifyRoleOrVariantRolesBySelector(selector, ["generic", "", "none"]); |
| }, |
| |
| |
| /* |
| Tests computed LABEL of all elements matching selector |
| against the string value of their data-expectedlabel attribute. |
| |
| Ex: <div aria-label="foo" |
| data-testname="optional unique test name" |
| data-expectedlabel="foo" |
| class="ex"> |
| |
| AriaUtils.verifyLabelsBySelector(".ex") |
| |
| */ |
| verifyLabelsBySelector: function(selector) { |
| const els = document.querySelectorAll(selector); |
| if (!els.length) { |
| throw `Selector passed in verifyLabelsBySelector("${selector}") should match at least one element.`; |
| } |
| for (const el of els) { |
| let label = el.getAttribute("data-expectedlabel"); |
| let testName = el.getAttribute("data-testname") || label; // data-testname optional if label is unique per test file |
| promise_test(async t => { |
| const expectedLabel = el.getAttribute("data-expectedlabel"); |
| let computedLabel = await test_driver.get_computed_label(el); |
| // Todo: Remove whitespace normalization after https://github.com/w3c/accname/issues/192 is addressed. Change prior line back to `const`, too. |
| computedLabel = computedLabel.trim() |
| assert_equals(computedLabel, expectedLabel, el.outerHTML); |
| }, `${testName}`); |
| } |
| }, |
| |
| |
| }; |
| |