WebKit Bugzilla
Attachment 360553 Details for
Bug 194005
: AX: Audit tab should have built-in accessibility tests.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194005-20190129222111.patch (text/plain), 38.73 KB, created by
Aaron Chu
on 2019-01-29 22:21:12 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Aaron Chu
Created:
2019-01-29 22:21:12 PST
Size:
38.73 KB
patch
obsolete
>Subversion Revision: 240558 >diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index ffddf7c4c6be26091f8a4312fd3ddd2ad0174d4f..f437044d74371e3f6d08d5e4715ce3754f001640 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,19 @@ >+2019-01-29 Aaron Chu <aaron_chu@apple.com> >+ >+ AX: Audit tab should have built-in accessibility tests. >+ https://bugs.webkit.org/show_bug.cgi?id=194005 >+ <rdar://problem/47657503> >+ >+ Updated built-in accessibility audits test suite. >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * Localizations/en.lproj/localizedStrings.js: >+ * UserInterface/Controllers/AuditManager.js: >+ (WI.AuditManager.prototype.addDefaultTestsIfNeeded.): >+ (WI.AuditManager.prototype.addDefaultTestsIfNeeded): >+ (WI.AuditManager): >+ > 2019-01-26 Devin Rousso <drousso@apple.com> > > Web Inspector: handle CSS Color 4 color syntaxes >diff --git a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >index bf92bafb669cd61242f3c629d9fde46533667564..ea9cb26ced9957a8dd572f13a5e7335fcdb83974 100644 >--- a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >+++ b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >@@ -104,6 +104,7 @@ localizedStrings["All Storage"] = "All Storage"; > localizedStrings["All items in \u0022%s\u0022 must be error objects"] = "All items in \u0022%s\u0022 must be error objects"; > localizedStrings["All items in \u0022%s\u0022 must be non-empty strings"] = "All items in \u0022%s\u0022 must be non-empty strings"; > localizedStrings["All items in \u0022%s\u0022 must be valid DOM nodes"] = "All items in \u0022%s\u0022 must be valid DOM nodes"; >+localizedStrings["An accessibility test suite that uses WebCore for testing."] = "An accessibility test suite that uses WebCore for testing."; > localizedStrings["An error occurred trying to load the resource."] = "An error occurred trying to load the resource."; > localizedStrings["An error occurred trying to read the \u201C%s\u201D table."] = "An error occurred trying to read the \u201C%s\u201D table."; > localizedStrings["An unexpected error %s occurred."] = "An unexpected error %s occurred."; >@@ -378,18 +379,22 @@ localizedStrings["Enable source maps"] = "Enable source maps"; > localizedStrings["Enabled"] = "Enabled"; > localizedStrings["Encoded"] = "Encoded"; > localizedStrings["Encoding"] = "Encoding"; >-localizedStrings["Ensure <area> elements have alternate text."] = "Ensure <area> elements have alternate text."; >-localizedStrings["Ensure <blink> is not used."] = "Ensure <blink> is not used."; >-localizedStrings["Ensure <dt> and <dd> elements are contained by a <dl>."] = "Ensure <dt> and <dd> elements are contained by a <dl>."; >-localizedStrings["Ensure <form>s have at least one input."] = "Ensure <form>s have at least one input."; >-localizedStrings["Ensure <frame> elements have a title."] = "Ensure <frame> elements have a title."; >-localizedStrings["Ensure <img> elements have alternate text."] = "Ensure <img> elements have alternate text."; >-localizedStrings["Ensure <marquee> is not used."] = "Ensure <marquee> is not used."; >-localizedStrings["Ensure <meta http-equiv=refresh> is not used."] = "Ensure <meta http-equiv=refresh> is not used."; >-localizedStrings["Ensure exactly one <legend> exists per <form>."] = "Ensure exactly one <legend> exists per <form>."; >-localizedStrings["Ensure hidden=true is not present on the <body>."] = "Ensure hidden=true is not present on the <body>."; >-localizedStrings["Ensure tabindex is a number."] = "Ensure tabindex is a number."; >-localizedStrings["Ensure that the <legend> is the first child in the <form>."] = "Ensure that the <legend> is the first child in the <form>."; >+localizedStrings["Ensure `aria-labelledby` is spelled correctly."] = "Ensure `aria-labelledby` is spelled correctly."; >+localizedStrings["Ensure `cell` to have required children."] = "Ensure `cell` to have required children."; >+localizedStrings["Ensure `grid` to have required children."] = "Ensure `grid` to have required children."; >+localizedStrings["Ensure `menu` and `menubar` child roles are inside a `menu` or a `menubar`."] = "Ensure `menu` and `menubar` child roles are inside a `menu` or a `menubar`."; >+localizedStrings["Ensure `menu` and `menubar` to have required children."] = "Ensure `menu` and `menubar` to have required children."; >+localizedStrings["Ensure `radiogroup` to have required children."] = "Ensure `radiogroup` to have required children."; >+localizedStrings["Ensure `rowgroup` to have required children."] = "Ensure `rowgroup` to have required children."; >+localizedStrings["Ensure `tablist` to have required children."] = "Ensure `tablist` to have required children."; >+localizedStrings["Ensure `tree` to have required children."] = "Ensure `tree` to have required children."; >+localizedStrings["Ensure aria-hidden=\"false\" is not used"] = "Ensure aria-hidden=\"false\" is not used"; >+localizedStrings["Ensure elements of accessibility role `combobox` to have required children."] = "Ensure elements of accessibility role `combobox` to have required children."; >+localizedStrings["Ensure elements of accessibility role `feed` to have required children."] = "Ensure elements of accessibility role `feed` to have required children."; >+localizedStrings["Ensure elements of accessibility role `list` to have required children."] = "Ensure elements of accessibility role `list` to have required children."; >+localizedStrings["Ensure elements of accessibility role `listbox` to have required children."] = "Ensure elements of accessibility role `listbox` to have required children."; >+localizedStrings["Ensure elements of accessibility role `table` to have required children."] = "Ensure elements of accessibility role `table` to have required children."; >+localizedStrings["Ensure elements of role `img` to have labels."] = "Ensure elements of role `img` to have labels."; > localizedStrings["Entered Full-Screen Mode"] = "Entered Full-Screen Mode"; > localizedStrings["Entered Low-Power Mode"] = "Entered Low-Power Mode"; > localizedStrings["Entire Recording"] = "Entire Recording"; >@@ -940,10 +945,13 @@ localizedStrings["Tabs"] = "Tabs"; > localizedStrings["Tag"] = "Tag"; > localizedStrings["Take snapshot"] = "Take snapshot"; > localizedStrings["Template Content"] = "Template Content"; >-localizedStrings["Tests for element accessibility issues."] = "Tests for element accessibility issues."; >-localizedStrings["Tests for element attribute accessibility issues."] = "Tests for element attribute accessibility issues."; >-localizedStrings["Tests for ways to improve accessibility."] = "Tests for ways to improve accessibility."; >-localizedStrings["Tests the accessibility of form elements."] = "Tests the accessibility of form elements."; >+localizedStrings["Test for Buttons with labels."] = "Test for Buttons with labels."; >+localizedStrings["Test for invalid \"aria-hidden\" values."] = "Test for invalid \"aria-hidden\" values."; >+localizedStrings["Test for links to have labels."] = "Test for links to have labels."; >+localizedStrings["Test for multiple banners on the page."] = "Test for multiple banners on the page."; >+localizedStrings["Test for multiple live regions."] = "Test for multiple live regions."; >+localizedStrings["Test that all Dialogs have aria-modal set to true."] = "Test that all Dialogs have aria-modal set to true."; >+localizedStrings["Test that all Dialogs have labels."] = "Test that all Dialogs have labels."; > localizedStrings["Text"] = "Text"; > localizedStrings["Text Frame"] = "Text Frame"; > localizedStrings["Text Node"] = "Text Node"; >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >index 815212d83dd4da48e18b5fa7592be4be3ffd187a..6ea51c97ea9faf0e88f2c85bb1711ebc892b371a 100644 >--- a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >+++ b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >@@ -321,25 +321,30 @@ WI.AuditManager = class AuditManager extends WI.Object > ], {description: WI.UIString("These are all of the different types of data that can be returned with the test result.")}), > ], {description: WI.UIString("These tests serve as a demonstration of the functionality and structure of audits.")}), > new WI.AuditTestGroup(WI.UIString("Accessibility"), [ >- new WI.AuditTestGroup(WI.UIString("Attributes"), [ >- new WI.AuditTestCase(`img-alt`, `function() { let domNodes = Array.from(document.getElementsByTagName("img")).filter((img) => !img.alt || !img.alt.length); return { level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["alt"] }; }`, {description: WI.UIString("Ensure <img> elements have alternate text.")}), >- new WI.AuditTestCase(`area-alt`, `function() { let domNodes = Array.from(document.getElementsByTagName("area")).filter((area) => !area.alt || !area.alt.length); return { level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["alt"] }; }`, {description: WI.UIString("Ensure <area> elements have alternate text.")}), >- new WI.AuditTestCase(`valid-tabindex`, `function() { let domNodes = Array.from(document.querySelectorAll("*[tabindex]")) .filter((node) => { let tabindex = node.getAttribute("tabindex"); if (!tabindex) return false; tabindex = parseInt(tabindex); return isNaN(tabindex) || (tabindex !== 0 && tabindex !== -1); }); return { level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["tabindex"] }; }`, {description: WI.UIString("Ensure tabindex is a number.")}), >- new WI.AuditTestCase(`frame-title`, `function() { let domNodes = Array.from(document.querySelectorAll("iframe, frame")) .filter((node) => { let title = node.getAttribute("title"); return !title || !title.trim().length; }); return { level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["title"] }; }`, {description: WI.UIString("Ensure <frame> elements have a title.")}), >- new WI.AuditTestCase(`hidden-body`, `function() { let domNodes = Array.from(document.querySelectorAll("body[hidden]")).filter((body) => body.hidden); return { level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["hidden"] }; }`, {description: WI.UIString("Ensure hidden=true is not present on the <body>.")}), >- new WI.AuditTestCase(`meta-refresh`, `function() { let domNodes = Array.from(document.querySelectorAll("meta[http-equiv=refresh]")); return { level: domNodes.length ? "warn" : "pass", domNodes, domAttributes: ["http-equiv"] }; }`, {description: WI.UIString("Ensure <meta http-equiv=refresh> is not used.")}), >- ], {description: WI.UIString("Tests for element attribute accessibility issues.")}), >- new WI.AuditTestGroup(WI.UIString("Elements"), [ >- new WI.AuditTestCase(`blink`, `function() { let domNodes = Array.from(document.getElementsByTagName("blink")); return { level: domNodes.length ? "warn" : "pass", domNodes }; }`, {description: WI.UIString("Ensure <blink> is not used.")}), >- new WI.AuditTestCase(`marquee`, `function() { let domNodes = Array.from(document.getElementsByTagName("marquee")); return { level: domNodes.length ? "warn" : "pass", domNodes }; }`, {description: WI.UIString("Ensure <marquee> is not used.")}), >- new WI.AuditTestCase(`dlitem`, `function() { function check(node) { if (!node) { return false; } if (node.nodeName === "DD") { return true; } return check(node.parentNode); } let domNodes = Array.from(document.querySelectorAll("dt, dd")).filter(check); return { level: domNodes.length ? "warn" : "pass", domNodes }; }`, {description: WI.UIString("Ensure <dt> and <dd> elements are contained by a <dl>.")}), >- ], {description: WI.UIString("Tests for element accessibility issues.")}), >- new WI.AuditTestGroup(WI.UIString("Forms"), [ >- new WI.AuditTestCase(`one-legend`, `function() { let formLegendsMap = Array.from(document.querySelectorAll("form legend")).reduce((accumulator, node) => { let existing = accumulator.get(node.form); if (!existing) { existing = []; accumulator.set(node.form, existing); } existing.push(node); return accumulator; }, new Map); let domNodes = Array.from(formLegendsMap.values()).reduce((accumulator, legends) => accumulator.concat(legends), []); return { level: domNodes.length ? "warn" : "pass", domNodes }; }`, {description: WI.UIString("Ensure exactly one <legend> exists per <form>.")}), >- new WI.AuditTestCase(`legend-first-child`, `function() { let domNodes = Array.from(document.querySelectorAll("form > legend:not(:first-child)")); return { level: domNodes.length ? "warn" : "pass", domNodes }; }`, {description: WI.UIString("Ensure that the <legend> is the first child in the <form>.")}), >- new WI.AuditTestCase(`form-input`, `function() { let domNodes = Array.from(document.getElementsByTagName("form")) .filter(node => !node.elements.length); return { level: domNodes.length ? "warn" : "pass", domNodes }; }`, {description: WI.UIString("Ensure <form>s have at least one input.")}), >- ], {description: WI.UIString("Tests the accessibility of form elements.")}), >- ], {description: WI.UIString("Tests for ways to improve accessibility.")}), >+ new WI.AuditTestCase(`testMenuRoleForRequiredChidren`, `async function() {let domNodes = [];const Relationships = {"menu": ["menuitem", "menuitemcheckbox", "menuitemradio"],"menubar": ["menuitem", "menuitemcheckbox", "menuitemradio"]};let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})();t.init(Relationships, domNodes);return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"]}}`, {description: WI.UIString("Ensure `menu` and `menubar` to have required children.")}), >+ new WI.AuditTestCase(`testGridRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"grid": ["row", "rowgroup"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure `grid` to have required children.")}), >+ new WI.AuditTestCase(`testForMultipleBanners`, `async function () { let banners = Array.from(WebInspectorAudit.Accessibility.getElementsByComputedRole("banner")); let domNodes = banners.slice(1); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Test for multiple banners on the page.")}), >+ new WI.AuditTestCase(`testDialogToHaveAriaModal`, `async function () { let audit = WebInspectorAudit.Accessibility; let dialogs = Array.from(audit.getElementsByComputedRole("dialog")); let domNodes = dialogs.filter(dialog => {return !dialog.getAttribute("aria-modal") === "true"; }); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Test that all Dialogs have aria-modal set to true.")}), >+ new WI.AuditTestCase(`testForLinksLabels`, `async function () { let audit = WebInspectorAudit.Accessibility; let links = Array.from(audit.getElementsByComputedRole("link")); let domNodes = links.filter(link => {return !audit.getComputedProperties(link).label; }); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Test for links to have labels.")}), >+ new WI.AuditTestCase(`testRowGroupRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"rowgroup": ["row"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure `rowgroup` to have required children.")}), >+ new WI.AuditTestCase(`testTableRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"table": ["row", "rowgroup"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure elements of accessibility role `table` to have required children.")}), >+ new WI.AuditTestCase(`testForAriaLabelledbySpelling`, `async function () { let domNodes = Array.from(document.querySelectorAll("[aria-labeledby]")); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["aria-labeledby"] }}`, {description: WI.UIString("Ensure `aria-labelledby` is spelled correctly.")}), >+ new WI.AuditTestCase(`testForInvalidAriaHiddenValue`, `async function () { let domNodes = Array.from(document.querySelectorAll("[aria-hidden]:not([aria-hidden=true]):not([aria-hidden=false])")); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Test for invalid \"aria-hidden\" values.")}), >+ new WI.AuditTestCase(`testForAriaHiddenFalse`, `async function () { let domNodes = Array.from(document.querySelectorAll("[aria-hidden=false]")); return {level: domNodes.length ? "warn" : "pass", domNodes, domAttributes: ["aria-hidden"] }}`, {description: WI.UIString("Ensure aria-hidden=\"false\" is not used")}), >+ new WI.AuditTestCase(`testTreeRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"tree": ["treeitem", "group"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure `tree` to have required children.")}), >+ new WI.AuditTestCase(`testRadioGroupRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"radiogroup": ["radio"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure `radiogroup` to have required children.")}), >+ new WI.AuditTestCase(`testFeedRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"feed": ["article"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure elements of accessibility role `feed` to have required children.")}), >+ new WI.AuditTestCase(`testImagesLabels`, `async function () { let audit = WebInspectorAudit.Accessibility; let images = Array.from(audit.getElementsByComputedRole("img")); let domNodes = images.filter(image => {return !audit.getComputedProperties(image).label; }); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Ensure elements of role `img` to have labels.")}), >+ new WI.AuditTestCase(`testComboboxRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"combobox": ["textbox", "listbox", "tree", "grid", "dialog"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure elements of accessibility role `combobox` to have required children.")}), >+ new WI.AuditTestCase(`testForMultupleLiveRegions`, `async function () { let audit = WebInspectorAudit.Accessibility; let alerts = Array.from(audit.getElementsByComputedRole("alert")); let logs = Array.from(audit.getElementsByComputedRole("log")); let statuses = Array.from(audit.getElementsByComputedRole("status")); let marquees = Array.from(audit.getElementsByComputedRole("marquee")); let timers = Array.from(audit.getElementsByComputedRole("timer")); let liveRegions = Array.from(document.querySelectorAll("[aria-live=polite], [aria-live=assertive]")); let allLiveRegions = alerts.concat(logs, statuses, marquees, liveRegions, timers); let domNodes = allLiveRegions.slice(1); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Test for multiple live regions.")}), >+ new WI.AuditTestCase(`testButtonLabels`, `async function () { let audit = WebInspectorAudit.Accessibility; let buttons = Array.from(audit.getElementsByComputedRole("button")); let domNodes = buttons.filter(button => {return !audit.getComputedProperties(button).label; }); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Test for Buttons with labels.")}), >+ new WI.AuditTestCase(`testMenuChildRoleForRequiredParent`, `async function() {let domNodes = [];const Relationships = {"menu, menubar": ["menuitem", "menuitemcheckbox", "menuitemradio"]};let t = (function(){let e = function() { function test(relationships, domNodes) {let audit = WebInspectorAudit.Accessibility;for (let parentRole in relationships) { let targetParentRoles = parentRole.split(", "); relationships[parentRole].forEach(childRole => {let childNodes = Array.from(audit.getElementsByComputedRole(childRole));childNodes.forEach(node => { let pNodes = getAllParentNodes(node); if (!pNodes.length) {return; } let validParents = pNodes.filter(node => {return targetParentRoles.includes(audit.getComputedProperties(node).role); }); if (validParents.length) {return; } let omParentNode = pNodes.slice(-1)[0]; if (!domNodes.includes(omParentNode)) {domNodes.push(omParentNode); }}); });} }; function getAllParentNodes(childNode) {let parentNode = childNode.parentNode;let res = [];if (!parentNode || parentNode.nodeType !== 1 || parentNode.nodeName === "BODY" || parentNode.nodeName === "HTML") { return res;};res.push(parentNode);res = res.concat(getAllParentNodes(parentNode)); return res; }; return {test }};return new e;;})(); t.test(Relationships, domNodes);return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"]}}`, {description: WI.UIString("Ensure `menu` and `menubar` child roles are inside a `menu` or a `menubar`.")}), >+ new WI.AuditTestCase(`testCellRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"cell": ["row"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure `cell` to have required children.")}), >+ new WI.AuditTestCase(`testListRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"list": ["listitem", "group"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "warn" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure elements of accessibility role `list` to have required children.")}), >+ new WI.AuditTestCase(`testTablistRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"tablist": ["tab"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure `tablist` to have required children.")}), >+ new WI.AuditTestCase(`testDialogsForLabels`, `async function () { let audit = WebInspectorAudit.Accessibility; let dialogs = Array.from(audit.getElementsByComputedRole("dialog")); let domNodes = dialogs.filter(dialog => {return !WebInspectorWebInspectorAudit.Accessibility.getComputedProperties(dialog).label; }); return {level: domNodes.length ? "fail" : "pass", domNodes }}`, {description: WI.UIString("Test that all Dialogs have labels.")}), >+ new WI.AuditTestCase(`testListboxRoleForRequiredChidren`, `async function() { let domNodes = []; const Relationships = {"listbox": ["option"] };let t = (function(){let r = function() { let audit = WebInspectorAudit.Accessibility; function init(relationships, domNodes) {let visitedParents = [];if (!relationships) { return console.error("Missing Relationship Mapping.");};if (!Array.isArray(domNodes)) { return console.error("\`domNodes\` must be an instance of Array.");};for (let role in relationships) { let parentNodes = audit.getElementsByComputedRole(role); if (!parentNodes.length)continue; for (let parentNode of parentNodes) {if (visitedParents.includes(parentNode)) { continue;};let res = [];traverseForChildRole(parentNode.firstChild, relationships[role], visitedParents, res);if (!res.length) domNodes.push(parentNode); }} } function traverseForChildRole(node, expectedRoles, visitedParents = [], res = []){let childNode = node;if (childNode) { visitedParents.push(childNode.parentNode);};while(childNode) { if (childNode.nodeType === 1 && audit.getComputedProperties(childNode)) {let targetRole = audit.getComputedProperties(childNode).role;if (targetRole !== "" && expectedRoles.includes(targetRole)) { res.push(childNode);};if (childNode.hasChildNodes()) { traverseForChildRole(childNode.firstChild, expectedRoles, visitedParents, res)} } childNode = childNode.nextSibling;} } return {init: init }};return new r;})(); t.init(Relationships, domNodes); return {level: domNodes.length ? "fail" : "pass", domNodes, domAttributes: ["role"] }}`, {description: WI.UIString("Ensure elements of accessibility role `listbox` to have required children.")}) >+ ], {description: WI.UIString("An accessibility test suite that uses WebCore for testing.")}), > ]; > > let checkDisabledDefaultTest = (test) => {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194005
:
360553
|
360601
|
360681
|
360703
|
360713
|
360714
|
360750
|
361376
|
361381
|
361426
|
361442
|
362155