From bdff141871e8ca67dd16ee79665dc3f969db2725 Mon Sep 17 00:00:00 2001 From: Jey Date: Tue, 13 Nov 2018 10:59:04 +0000 Subject: [PATCH] fix: flag hidden elms with disallowed role(s) for review (#1225) --- lib/checks/aria/aria-allowed-role.js | 5 +++ lib/checks/aria/aria-allowed-role.json | 5 +-- test/checks/aria/aria-allowed-role.js | 36 ++++++++++++++++--- .../aria-allowed-role/aria-allowed-role.html | 5 +++ .../aria-allowed-role/aria-allowed-role.json | 14 +++++--- 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/lib/checks/aria/aria-allowed-role.js b/lib/checks/aria/aria-allowed-role.js index e221ef34c1..21cae12ca5 100644 --- a/lib/checks/aria/aria-allowed-role.js +++ b/lib/checks/aria/aria-allowed-role.js @@ -3,6 +3,7 @@ * https://www.w3.org/TR/html-aria/#docconformance * https://www.w3.org/TR/SVG2/struct.html#implicit-aria-semantics */ +const { dom } = axe.commons; const { allowImplicit = true, ignoredTags = [] } = options || {}; const tagName = node.nodeName.toUpperCase(); @@ -18,6 +19,10 @@ const unallowedRoles = axe.commons.aria.getElementUnallowedRoles( if (unallowedRoles.length) { this.data(unallowedRoles); + if (!dom.isVisible(node, true)) { + // flag hidden elements for review + return undefined; + } return false; } return true; diff --git a/lib/checks/aria/aria-allowed-role.json b/lib/checks/aria/aria-allowed-role.json index f0a09782dd..15ac20dfd3 100644 --- a/lib/checks/aria/aria-allowed-role.json +++ b/lib/checks/aria/aria-allowed-role.json @@ -9,7 +9,8 @@ "impact": "minor", "messages": { "pass": "ARIA role is allowed for given element", - "fail": "role{{=it.data && it.data.length > 1 ? 's' : ''}} {{=it.data.join(', ')}} {{=it.data && it.data.length > 1 ? 'are' : ' is'}} not allowed for given element" + "fail": "ARIA role{{=it.data && it.data.length > 1 ? 's' : ''}} {{=it.data.join(', ')}} {{=it.data && it.data.length > 1 ? 'are' : ' is'}} not allowed for given element", + "incomplete": "ARIA role{{=it.data && it.data.length > 1 ? 's' : ''}} {{=it.data.join(', ')}} must be removed when the element is made visible, as {{=it.data && it.data.length > 1 ? 'they are' : 'it is'}} not allowed for the element" } } -} \ No newline at end of file +} diff --git a/test/checks/aria/aria-allowed-role.js b/test/checks/aria/aria-allowed-role.js index d3a56ef325..9f0736704a 100644 --- a/test/checks/aria/aria-allowed-role.js +++ b/test/checks/aria/aria-allowed-role.js @@ -12,6 +12,7 @@ describe('aria-allowed-role', function() { it('returns true if given element is an ignoredTag in options', function() { var node = document.createElement('article'); node.setAttribute('role', 'presentation'); + fixture.appendChild(node); var options = { ignoredTags: ['article'] }; @@ -26,16 +27,15 @@ describe('aria-allowed-role', function() { }); it('returns false with implicit role of row for TR when allowImplicit is set to false via options', function() { - var node = document.createElement('table'); - node.setAttribute('role', 'grid'); - var row = document.createElement('tr'); - row.setAttribute('role', 'row'); + fixture.innerHTML = + '
'; + var target = fixture.querySelector('#target'); var options = { allowImplicit: false }; var actual = checks['aria-allowed-role'].evaluate.call( checkContext, - row, + target, options ); var expected = false; @@ -51,6 +51,32 @@ describe('aria-allowed-role', function() { ); }); + it('returns undefined (needs review) when element is hidden and has unallowed role', function() { + fixture.innerHTML = + ''; + var target = fixture.querySelector('#target'); + var actual = checks['aria-allowed-role'].evaluate.call( + checkContext, + target + ); + assert.isUndefined(actual); + }); + + it('returns undefined (needs review) when element is with in hidden parent and has unallowed role', function() { + fixture.innerHTML = + '
' + + '' + + '
'; + var target = fixture.querySelector('#target'); + var actual = checks['aria-allowed-role'].evaluate.call( + checkContext, + target + ); + assert.isUndefined(actual); + }); + it('returns true when BUTTON has type menu and role as menuitem', function() { var node = document.createElement('button'); node.setAttribute('type', 'menu'); diff --git a/test/integration/rules/aria-allowed-role/aria-allowed-role.html b/test/integration/rules/aria-allowed-role/aria-allowed-role.html index b27daccdfb..e4acd11792 100644 --- a/test/integration/rules/aria-allowed-role/aria-allowed-role.html +++ b/test/integration/rules/aria-allowed-role/aria-allowed-role.html @@ -55,3 +55,8 @@

+
+ +
+ + diff --git a/test/integration/rules/aria-allowed-role/aria-allowed-role.json b/test/integration/rules/aria-allowed-role/aria-allowed-role.json index a92c112926..2a61d87bc8 100644 --- a/test/integration/rules/aria-allowed-role/aria-allowed-role.json +++ b/test/integration/rules/aria-allowed-role/aria-allowed-role.json @@ -12,7 +12,7 @@ ["#pass-li-role-doc-biblioentry"], ["#pass-aside-doc-example"], ["#pass-div-valid-role"], - ["#pass-ol-valid-role"], + ["#pass-ol-valid-role"], ["#pass-nav-role-doc-index"], ["#pass-h1-role-doc-subtitle"], ["#pass-video-valid-role"], @@ -26,7 +26,7 @@ ["#pass-section-valid-role-application"], ["#pass-section-valid-role-content-info"], ["#pass-section-valid-role-dialog"], - ["#pass-button-valid-role-checkbox"], + ["#pass-button-valid-role-checkbox"], ["#pass-header-valid-role"], ["#pass-footer-valid-role"], ["#pass-embed-valid-role"], @@ -51,7 +51,7 @@ ["#fail-dd-no-role"], ["#fail-dt-no-role"], ["#fail-label-no-role"], - ["#fail-ol-invalid-role"], + ["#fail-ol-invalid-role"], ["#fail-a-invalid-role"], ["#fail-section-invalid-role"], ["#fail-embed-invalid-role"], @@ -61,5 +61,9 @@ ["#fail-aside-role-tab"], ["#fail-button-role-gridcell"], ["#fail-input-role-gridcell-multiple-role"] - ] -} \ No newline at end of file + ], + "incomplete": [ + ["#incomplete1"], + ["#incomplete2"] + ] +}