From 2467b3a59cb853689b88a15580acd6e9b210dd6b Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Thu, 19 Aug 2021 21:12:04 -0400 Subject: [PATCH 01/24] refactor(checks/navigation): improve `internal-link-present-evaluate` Make `internal-link-present-evaluate` work with virtualNode rather than actualNode. Closes issue #2466 --- .../internal-link-present-evaluate.js | 20 +-- .../navigation/internal-link-present.js | 155 +++++++++--------- 2 files changed, 88 insertions(+), 87 deletions(-) diff --git a/lib/checks/navigation/internal-link-present-evaluate.js b/lib/checks/navigation/internal-link-present-evaluate.js index acf086d43f..d235bfbe2b 100644 --- a/lib/checks/navigation/internal-link-present-evaluate.js +++ b/lib/checks/navigation/internal-link-present-evaluate.js @@ -1,10 +1,10 @@ -import { querySelectorAll } from '../../core/utils'; - -function internalLinkPresentEvaluate(node, options, virtualNode) { - const links = querySelectorAll(virtualNode, 'a[href]'); - return links.some(vLink => { - return /^#[^/!]/.test(vLink.actualNode.getAttribute('href')); - }); -} - -export default internalLinkPresentEvaluate; +import { querySelectorAll } from '../../core/utils'; + +function internalLinkPresentEvaluate(node, options, virtualNode) { + const links = querySelectorAll(virtualNode, 'a[href]'); + return links.some(vLink => { + return /^#[^/!]/.test(vLink.attr('href')); + }); +} + +export default internalLinkPresentEvaluate; diff --git a/test/checks/navigation/internal-link-present.js b/test/checks/navigation/internal-link-present.js index 5ea7efed12..2f3d34d561 100644 --- a/test/checks/navigation/internal-link-present.js +++ b/test/checks/navigation/internal-link-present.js @@ -1,77 +1,78 @@ -describe('internal-link-present', function() { - 'use strict'; - - var fixture = document.getElementById('fixture'); - var shadowSupported = axe.testUtils.shadowSupport.v1; - var checkContext = axe.testUtils.MockCheckContext(); - var checkSetup = axe.testUtils.checkSetup; - var shadowCheckSetup = axe.testUtils.shadowCheckSetup; - - afterEach(function() { - fixture.innerHTML = ''; - axe._tree = undefined; - checkContext.reset(); - }); - - it('should return true when an internal link is found', function() { - var params = checkSetup('
hi
'); - assert.isTrue( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should return false when a hashbang URL was used', function() { - var params = checkSetup('
hi
'); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should return false when a hash route URL was used', function() { - var params = checkSetup('
hi
'); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should return false when a hashbang + slash route URL was used', function() { - var params = checkSetup('
hi
'); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should otherwise return false', function() { - var params = checkSetup( - '
hi
' - ); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - (shadowSupported ? it : xit)( - 'should return true when internal link is found in shadow dom', - function() { - var params = shadowCheckSetup( - '
', - 'hi' - ); - assert.isTrue( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - } - ); -}); +describe('internal-link-present', function() { + 'use strict'; + + var fixture = document.getElementById('fixture'); + var shadowSupported = axe.testUtils.shadowSupport.v1; + var checkContext = axe.testUtils.MockCheckContext(); + var shadowCheckSetup = axe.testUtils.shadowCheckSetup; + var queryFixture = axe.testUtils.queryFixture; + + afterEach(function() { + fixture.innerHTML = ''; + axe._tree = undefined; + checkContext.reset(); + }); + + it('should return true when an internal link is found', function() { + var vNode = queryFixture('
hi
'); + assert.isTrue( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should return false when a hashbang URL was used', function() { + var vNode = queryFixture('
hi
'); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should return false when a hash route URL was used', function() { + var vNode = queryFixture('
hi
'); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should return false when a hashbang + slash route URL was used', function() { + var vNode = queryFixture('
hi
'); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should otherwise return false', function() { + var vNode = queryFixture( + '
hi
' + ); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + (shadowSupported ? it : xit)( + 'should return true when internal link is found in shadow dom', + function() { + var params = shadowCheckSetup( + '
', + 'hi' + ); + var vNode = params[2]; + assert.isTrue( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + } + ); +}); From 9f996bc6f54092541db77b9c3e62e2a5d9d9643e Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Fri, 3 Sep 2021 08:48:36 -0400 Subject: [PATCH 02/24] test commit 1 --- test/testutils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/testutils.js b/test/testutils.js index 8c60d13a93..5b37f8b83d 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -501,3 +501,6 @@ testUtils.shadowQuerySelector = function shadowQuerySelector(axeSelector, doc) { }); return elm; }; + +// test commit 1 + From c011d2c2887c2caecb53e40411b4526d0f0690e9 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Fri, 3 Sep 2021 08:54:37 -0400 Subject: [PATCH 03/24] test commit 2 --- test/testutils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/testutils.js b/test/testutils.js index 8c60d13a93..a31429c124 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -501,3 +501,6 @@ testUtils.shadowQuerySelector = function shadowQuerySelector(axeSelector, doc) { }); return elm; }; + +// test commit 2 + From a3861666d61988443343356a8b26760cc3818a6e Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Fri, 3 Sep 2021 08:55:07 -0400 Subject: [PATCH 04/24] test commit 3 --- test/testutils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testutils.js b/test/testutils.js index a31429c124..f5b385e6d5 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -502,5 +502,5 @@ testUtils.shadowQuerySelector = function shadowQuerySelector(axeSelector, doc) { return elm; }; -// test commit 2 +// test commit 3 From 31b19a3829bd8d52eacc006af973261e2d4d1f93 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Fri, 3 Sep 2021 09:28:17 -0400 Subject: [PATCH 05/24] Revert "Merge branch 'dan-test-branch-1' into develop" This reverts commit 428e01533eb561a5a2ee0a603014057337ba0177, reversing changes made to 9f996bc6f54092541db77b9c3e62e2a5d9d9643e. --- test/testutils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testutils.js b/test/testutils.js index 73d902ed24..5b37f8b83d 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -502,5 +502,5 @@ testUtils.shadowQuerySelector = function shadowQuerySelector(axeSelector, doc) { return elm; }; -// test commit 1 & 3 +// test commit 1 From ac32146f5561fcdafac1c5876e57f3fd8342d8a0 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Fri, 3 Sep 2021 09:28:29 -0400 Subject: [PATCH 06/24] Revert "test commit 1" This reverts commit 9f996bc6f54092541db77b9c3e62e2a5d9d9643e. --- test/testutils.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/testutils.js b/test/testutils.js index 5b37f8b83d..8c60d13a93 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -501,6 +501,3 @@ testUtils.shadowQuerySelector = function shadowQuerySelector(axeSelector, doc) { }); return elm; }; - -// test commit 1 - From 30f0e01506979bb92600289bd242ab01d25cb8ec Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Thu, 23 Sep 2021 21:12:17 -0400 Subject: [PATCH 07/24] fix(rule): allow "tabindex=-1" for rules "aria-text" and "nested-interactive" Closes issue #2934 --- .../keyboard/no-focusable-content-evaluate.js | 6 ++++- test/checks/keyboard/no-focusable-content.js | 22 +++++++++++++++++++ .../rules/aria-text/aria-text.html | 6 ++--- .../rules/aria-text/aria-text.json | 4 ++-- .../nested-interactive.html | 12 +++++----- .../nested-interactive.json | 4 +++- .../virtual-rules/nested-interactive.js | 20 +++++++++++++++++ 7 files changed, 62 insertions(+), 12 deletions(-) diff --git a/lib/checks/keyboard/no-focusable-content-evaluate.js b/lib/checks/keyboard/no-focusable-content-evaluate.js index e45bdfde9f..0f6842405f 100644 --- a/lib/checks/keyboard/no-focusable-content-evaluate.js +++ b/lib/checks/keyboard/no-focusable-content-evaluate.js @@ -1,7 +1,11 @@ import isFocusable from '../../commons/dom/is-focusable'; function focusableDescendants(vNode) { - if (isFocusable(vNode)) { + const isNodeFocusable = isFocusable(vNode); + let tabIndex = parseInt(vNode.attr('tabindex'), 10); + tabIndex = !isNaN(tabIndex) ? tabIndex : null; + + if(tabIndex ? isNodeFocusable && tabIndex >= 0 : isNodeFocusable) { return true; } diff --git a/test/checks/keyboard/no-focusable-content.js b/test/checks/keyboard/no-focusable-content.js index 1e1a3a8474..9959fda468 100644 --- a/test/checks/keyboard/no-focusable-content.js +++ b/test/checks/keyboard/no-focusable-content.js @@ -37,4 +37,26 @@ describe('no-focusable-content tests', function() { ); assert.isFalse(noFocusableContent(null, null, vNode)); }); + + it('should return true on span with tabindex=-1', function() { + var vNode = queryFixture(' some text ' + +'JavaScript is able to focus this ' + +''); + assert.isTrue(noFocusableContent(null, null, vNode)); + }); + + it('should return true on aria-hidden span with tabindex=-1', function() { + var vNode = queryFixture(' some text ' + +' ' + +''); + assert.isTrue(noFocusableContent(null, null, vNode)); + }); + + it('should return false on span with tabindex=0', function() { + var vNode = queryFixture(' some text ' + +'anyone is able to focus this ' + +''); + assert.isFalse(noFocusableContent(null, null, vNode)); + }); + }); diff --git a/test/integration/rules/aria-text/aria-text.html b/test/integration/rules/aria-text/aria-text.html index 28252c0bce..4059f1e53b 100644 --- a/test/integration/rules/aria-text/aria-text.html +++ b/test/integration/rules/aria-text/aria-text.html @@ -15,8 +15,8 @@

Flattened text because of the explicit role.
-
+
Flattened text because of the - explicit role. + explicit role. Considered non-focusable because of tabindex=-1...
-

+

diff --git a/test/integration/rules/aria-text/aria-text.json b/test/integration/rules/aria-text/aria-text.json index f6c3f1d2d9..3aa00ff23b 100644 --- a/test/integration/rules/aria-text/aria-text.json +++ b/test/integration/rules/aria-text/aria-text.json @@ -1,6 +1,6 @@ { "description": "aria-text tests", "rule": "aria-text", - "violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"]], - "passes": [["#pass1"], ["#pass2"], ["#pass3"]] + "violations": [["#fail1"], ["#fail2"], ["#fail3"]], + "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"]] } diff --git a/test/integration/rules/nested-interactive/nested-interactive.html b/test/integration/rules/nested-interactive/nested-interactive.html index beb7fbdf37..0baf57f5bb 100644 --- a/test/integration/rules/nested-interactive/nested-interactive.html +++ b/test/integration/rules/nested-interactive/nested-interactive.html @@ -1,12 +1,14 @@ -
pass
- - - + +
pass
+ + + +
- + diff --git a/test/integration/rules/nested-interactive/nested-interactive.json b/test/integration/rules/nested-interactive/nested-interactive.json index 78d3b43176..9195a46ad1 100644 --- a/test/integration/rules/nested-interactive/nested-interactive.json +++ b/test/integration/rules/nested-interactive/nested-interactive.json @@ -8,6 +8,8 @@ ["#pass3"], ["#pass4"], ["#pass5"], - ["#pass6"] + ["#pass6"], + ["#pass7"], + ["#pass8"] ] } diff --git a/test/integration/virtual-rules/nested-interactive.js b/test/integration/virtual-rules/nested-interactive.js index ba963b99b5..cd364e2b22 100644 --- a/test/integration/virtual-rules/nested-interactive.js +++ b/test/integration/virtual-rules/nested-interactive.js @@ -38,6 +38,26 @@ describe('nested-interactive virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); + it('should pass for element with content with tabindex=-1', function() { + var node = new axe.SerialVirtualNode({ + nodeName: 'button' + }); + var child = new axe.SerialVirtualNode({ + nodeName: 'span', + attributes: { + tabindex: -1 + } + }); + child.children = []; + node.children = [child]; + + var results = axe.runVirtualRule('nested-interactive', node); + + assert.lengthOf(results.passes, 1); + assert.lengthOf(results.violations, 0); + assert.lengthOf(results.incomplete, 0); + }); + it('should pass for empty element without', function() { var node = new axe.SerialVirtualNode({ nodeName: 'div', From 40025ad09bac49ee56a0d2cd1d45668dc90b54db Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 27 Nov 2021 20:19:49 -0500 Subject: [PATCH 08/24] work in progress --- .../keyboard/no-focusable-content-evaluate.js | 4 ++- test/checks/keyboard/no-focusable-content.js | 34 +++++++++++++------ .../rules/aria-text/aria-text.html | 14 ++++++-- .../rules/aria-text/aria-text.json | 4 +-- .../nested-interactive.html | 14 ++++---- .../nested-interactive.json | 9 ++--- .../virtual-rules/nested-interactive.js | 8 ++--- 7 files changed, 55 insertions(+), 32 deletions(-) diff --git a/lib/checks/keyboard/no-focusable-content-evaluate.js b/lib/checks/keyboard/no-focusable-content-evaluate.js index 27824fc4f4..8fc8aa3b34 100644 --- a/lib/checks/keyboard/no-focusable-content-evaluate.js +++ b/lib/checks/keyboard/no-focusable-content-evaluate.js @@ -1,4 +1,5 @@ import isFocusable from '../../commons/dom/is-focusable'; +import { getRole, getRoleType } from '../../commons/aria'; export default function noFocusableContentEvaluate(node, options, virtualNode) { if (!virtualNode.children) { @@ -40,7 +41,8 @@ function getFocusableDescendants(vNode) { const retVal = []; vNode.children.forEach(child => { - if (isFocusable(child)) { + const role = getRole(child); + if(getRoleType(role) === 'widget' && isFocusable(child)) { retVal.push(child); } else { retVal.push(...getFocusableDescendants(child)); diff --git a/test/checks/keyboard/no-focusable-content.js b/test/checks/keyboard/no-focusable-content.js index fdea6a0b05..871169f202 100644 --- a/test/checks/keyboard/no-focusable-content.js +++ b/test/checks/keyboard/no-focusable-content.js @@ -28,17 +28,22 @@ describe('no-focusable-content tests', function() { assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return false if element has focusable content', function() { + it('should return true if element has content which is focusable (tabindex=0) and does not have a widget role', function() { var params = checkSetup( '' ); - assert.isFalse(noFocusableContent.apply(checkContext, params)); - assert.deepEqual(checkContext._data, null); - assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]); + assert.isTrue(noFocusableContent.apply(checkContext, params)); + }); + + it('should return true if element has content which has negative tabindex and non-widget role', function() { + var vNode = queryFixture( + '' + ); + assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return false if element has natively focusable content', function() { + it('should return false if element has content which is natively focusable and has a widget role', function() { var params = checkSetup( '' ); @@ -50,7 +55,7 @@ describe('no-focusable-content tests', function() { it('should add each focusable child as related nodes', function() { var params = checkSetup( - '' + '' ); assert.isFalse(noFocusableContent.apply(checkContext, params)); @@ -61,7 +66,7 @@ describe('no-focusable-content tests', function() { ]); }); - it('should return false if element has natively focusable content with negative tabindex', function() { + it('should return false if element has natively focusable widget role content with negative tabindex', function() { var params = checkSetup( '' ); @@ -71,25 +76,32 @@ describe('no-focusable-content tests', function() { assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]); }); - it('should return true on span with tabindex=-1', function() { + it('should return true if element has content which is natively focusable and has a widget role but is disabled', function() { + var vNode = queryFixture( + '' + ); + assert.isTrue(noFocusableContent(null, null, vNode)); + }); + + it('should return true on span with negative tabindex (focusable, does not have a widget role)', function() { var vNode = queryFixture(' some text ' +'JavaScript is able to focus this ' +''); assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return true on aria-hidden span with tabindex=-1', function() { + it('should return true on aria-hidden span with negative tabindex (focusable, does not have a widget role)', function() { var vNode = queryFixture(' some text ' +' ' +''); assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return false on span with tabindex=0', function() { + it('should return true on nested span with tabindex=0 (focusable, does not have a widget role)', function() { var vNode = queryFixture(' some text ' +'anyone is able to focus this ' +''); - assert.isFalse(noFocusableContent(null, null, vNode)); + assert.isTrue(noFocusableContent(null, null, vNode)); }); }); diff --git a/test/integration/rules/aria-text/aria-text.html b/test/integration/rules/aria-text/aria-text.html index 4059f1e53b..54809b6bd5 100644 --- a/test/integration/rules/aria-text/aria-text.html +++ b/test/integration/rules/aria-text/aria-text.html @@ -15,8 +15,16 @@

Flattened text because of the explicit role.
-
+
Flattened text because of the - explicit role. Considered non-focusable because of tabindex=-1... + explicit role. +
+

+

+

Hello

+ + -

diff --git a/test/integration/rules/aria-text/aria-text.json b/test/integration/rules/aria-text/aria-text.json index 3aa00ff23b..9443502a16 100644 --- a/test/integration/rules/aria-text/aria-text.json +++ b/test/integration/rules/aria-text/aria-text.json @@ -1,6 +1,6 @@ { "description": "aria-text tests", "rule": "aria-text", - "violations": [["#fail1"], ["#fail2"], ["#fail3"]], - "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"]] + "violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"]], + "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"], ["#pass5"], ["#pass6"]] } diff --git a/test/integration/rules/nested-interactive/nested-interactive.html b/test/integration/rules/nested-interactive/nested-interactive.html index a11161f964..1af908b261 100644 --- a/test/integration/rules/nested-interactive/nested-interactive.html +++ b/test/integration/rules/nested-interactive/nested-interactive.html @@ -6,13 +6,13 @@ - -
- - - - - + +
+ + + + + ignored ignored diff --git a/test/integration/rules/nested-interactive/nested-interactive.json b/test/integration/rules/nested-interactive/nested-interactive.json index 7a9c0df654..4db1a12cdb 100644 --- a/test/integration/rules/nested-interactive/nested-interactive.json +++ b/test/integration/rules/nested-interactive/nested-interactive.json @@ -6,9 +6,7 @@ ["#fail2"], ["#fail3"], ["#fail4"], - ["#fail5"], - ["#fail6"], - ["#fail7"] + ["#fail5"] ], "passes": [ ["#pass1"], @@ -18,6 +16,9 @@ ["#pass5"], ["#pass6"], ["#pass7"], - ["#pass8"] + ["#pass8"], + ["#pass9"], + ["#pass10"], + ["#pass11"] ] } diff --git a/test/integration/virtual-rules/nested-interactive.js b/test/integration/virtual-rules/nested-interactive.js index cd364e2b22..fbb94c136b 100644 --- a/test/integration/virtual-rules/nested-interactive.js +++ b/test/integration/virtual-rules/nested-interactive.js @@ -74,7 +74,7 @@ describe('nested-interactive virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); - it('should fail for element with focusable content', function() { + it('should pass for element with non-widget content', function() { var node = new axe.SerialVirtualNode({ nodeName: 'button' }); @@ -89,12 +89,12 @@ describe('nested-interactive virtual-rule', function() { var results = axe.runVirtualRule('nested-interactive', node); - assert.lengthOf(results.passes, 0); - assert.lengthOf(results.violations, 1); + assert.lengthOf(results.passes, 1); + assert.lengthOf(results.violations, 0); assert.lengthOf(results.incomplete, 0); }); - it('should fail for element with natively focusable content', function() { + it('should fail for element with native widget content', function() { var node = new axe.SerialVirtualNode({ nodeName: 'div', attributes: { From 92dc637e75d01be40f3ff5c7e79c1789e5341f7c Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 27 Nov 2021 20:36:54 -0500 Subject: [PATCH 09/24] work in progress --- test/integration/virtual-rules/nested-interactive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/virtual-rules/nested-interactive.js b/test/integration/virtual-rules/nested-interactive.js index fbb94c136b..acdb54f389 100644 --- a/test/integration/virtual-rules/nested-interactive.js +++ b/test/integration/virtual-rules/nested-interactive.js @@ -38,7 +38,7 @@ describe('nested-interactive virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); - it('should pass for element with content with tabindex=-1', function() { + it('should pass for element with non-widget content which has negative tabindex', function() { var node = new axe.SerialVirtualNode({ nodeName: 'button' }); From 6d8a0f652b732e59d1c64af430196722369abadd Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Fri, 3 Sep 2021 08:48:36 -0400 Subject: [PATCH 10/24] test commit 1 --- test/testutils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/testutils.js b/test/testutils.js index fdc5a8741d..1d86c4f115 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -575,3 +575,6 @@ testUtils.shadowQuerySelector = function shadowQuerySelector(axeSelector, doc) { }); return elm; }; + +// test commit 1 + From 9373c580e4770f8a2cc2572464e0b869239a8e87 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Fri, 3 Sep 2021 09:28:29 -0400 Subject: [PATCH 11/24] Revert "test commit 1" This reverts commit 9f996bc6f54092541db77b9c3e62e2a5d9d9643e. --- test/testutils.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/testutils.js b/test/testutils.js index 1d86c4f115..fdc5a8741d 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -575,6 +575,3 @@ testUtils.shadowQuerySelector = function shadowQuerySelector(axeSelector, doc) { }); return elm; }; - -// test commit 1 - From 0a4fd4fa7813f0263971a5d54bd95ec20471d3e2 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Thu, 23 Sep 2021 21:12:17 -0400 Subject: [PATCH 12/24] fix(rule): allow "tabindex=-1" for rules "aria-text" and "nested-interactive" Closes issue #2934 --- test/checks/keyboard/no-focusable-content.js | 22 +++++++++++++++++++ .../rules/aria-text/aria-text.html | 6 ++--- .../rules/aria-text/aria-text.json | 4 ++-- .../nested-interactive.html | 12 +++++----- .../virtual-rules/nested-interactive.js | 20 +++++++++++++++++ 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/test/checks/keyboard/no-focusable-content.js b/test/checks/keyboard/no-focusable-content.js index 1389e0241a..fdea6a0b05 100644 --- a/test/checks/keyboard/no-focusable-content.js +++ b/test/checks/keyboard/no-focusable-content.js @@ -70,4 +70,26 @@ describe('no-focusable-content tests', function() { assert.deepEqual(checkContext._data, { messageKey: 'notHidden' }); assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]); }); + + it('should return true on span with tabindex=-1', function() { + var vNode = queryFixture(' some text ' + +'JavaScript is able to focus this ' + +''); + assert.isTrue(noFocusableContent(null, null, vNode)); + }); + + it('should return true on aria-hidden span with tabindex=-1', function() { + var vNode = queryFixture(' some text ' + +' ' + +''); + assert.isTrue(noFocusableContent(null, null, vNode)); + }); + + it('should return false on span with tabindex=0', function() { + var vNode = queryFixture(' some text ' + +'anyone is able to focus this ' + +''); + assert.isFalse(noFocusableContent(null, null, vNode)); + }); + }); diff --git a/test/integration/rules/aria-text/aria-text.html b/test/integration/rules/aria-text/aria-text.html index 28252c0bce..4059f1e53b 100644 --- a/test/integration/rules/aria-text/aria-text.html +++ b/test/integration/rules/aria-text/aria-text.html @@ -15,8 +15,8 @@

Flattened text because of the explicit role.
-
+
Flattened text because of the - explicit role. + explicit role. Considered non-focusable because of tabindex=-1...
-

+

diff --git a/test/integration/rules/aria-text/aria-text.json b/test/integration/rules/aria-text/aria-text.json index f6c3f1d2d9..3aa00ff23b 100644 --- a/test/integration/rules/aria-text/aria-text.json +++ b/test/integration/rules/aria-text/aria-text.json @@ -1,6 +1,6 @@ { "description": "aria-text tests", "rule": "aria-text", - "violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"]], - "passes": [["#pass1"], ["#pass2"], ["#pass3"]] + "violations": [["#fail1"], ["#fail2"], ["#fail3"]], + "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"]] } diff --git a/test/integration/rules/nested-interactive/nested-interactive.html b/test/integration/rules/nested-interactive/nested-interactive.html index fb42dd24dc..adec643ff2 100644 --- a/test/integration/rules/nested-interactive/nested-interactive.html +++ b/test/integration/rules/nested-interactive/nested-interactive.html @@ -1,12 +1,14 @@ -
pass
- - - + +
pass
+ + + +
- + diff --git a/test/integration/virtual-rules/nested-interactive.js b/test/integration/virtual-rules/nested-interactive.js index ba963b99b5..cd364e2b22 100644 --- a/test/integration/virtual-rules/nested-interactive.js +++ b/test/integration/virtual-rules/nested-interactive.js @@ -38,6 +38,26 @@ describe('nested-interactive virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); + it('should pass for element with content with tabindex=-1', function() { + var node = new axe.SerialVirtualNode({ + nodeName: 'button' + }); + var child = new axe.SerialVirtualNode({ + nodeName: 'span', + attributes: { + tabindex: -1 + } + }); + child.children = []; + node.children = [child]; + + var results = axe.runVirtualRule('nested-interactive', node); + + assert.lengthOf(results.passes, 1); + assert.lengthOf(results.violations, 0); + assert.lengthOf(results.incomplete, 0); + }); + it('should pass for empty element without', function() { var node = new axe.SerialVirtualNode({ nodeName: 'div', From d50b56ae3526f12f245218f19902be4bf103294a Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 27 Nov 2021 20:19:49 -0500 Subject: [PATCH 13/24] work in progress --- .../keyboard/no-focusable-content-evaluate.js | 4 ++- test/checks/keyboard/no-focusable-content.js | 34 +++++++++++++------ .../rules/aria-text/aria-text.html | 14 ++++++-- .../rules/aria-text/aria-text.json | 4 +-- .../nested-interactive.html | 14 ++++---- .../nested-interactive.json | 10 +++--- .../virtual-rules/nested-interactive.js | 8 ++--- 7 files changed, 56 insertions(+), 32 deletions(-) diff --git a/lib/checks/keyboard/no-focusable-content-evaluate.js b/lib/checks/keyboard/no-focusable-content-evaluate.js index 27824fc4f4..8fc8aa3b34 100644 --- a/lib/checks/keyboard/no-focusable-content-evaluate.js +++ b/lib/checks/keyboard/no-focusable-content-evaluate.js @@ -1,4 +1,5 @@ import isFocusable from '../../commons/dom/is-focusable'; +import { getRole, getRoleType } from '../../commons/aria'; export default function noFocusableContentEvaluate(node, options, virtualNode) { if (!virtualNode.children) { @@ -40,7 +41,8 @@ function getFocusableDescendants(vNode) { const retVal = []; vNode.children.forEach(child => { - if (isFocusable(child)) { + const role = getRole(child); + if(getRoleType(role) === 'widget' && isFocusable(child)) { retVal.push(child); } else { retVal.push(...getFocusableDescendants(child)); diff --git a/test/checks/keyboard/no-focusable-content.js b/test/checks/keyboard/no-focusable-content.js index fdea6a0b05..871169f202 100644 --- a/test/checks/keyboard/no-focusable-content.js +++ b/test/checks/keyboard/no-focusable-content.js @@ -28,17 +28,22 @@ describe('no-focusable-content tests', function() { assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return false if element has focusable content', function() { + it('should return true if element has content which is focusable (tabindex=0) and does not have a widget role', function() { var params = checkSetup( '' ); - assert.isFalse(noFocusableContent.apply(checkContext, params)); - assert.deepEqual(checkContext._data, null); - assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]); + assert.isTrue(noFocusableContent.apply(checkContext, params)); + }); + + it('should return true if element has content which has negative tabindex and non-widget role', function() { + var vNode = queryFixture( + '' + ); + assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return false if element has natively focusable content', function() { + it('should return false if element has content which is natively focusable and has a widget role', function() { var params = checkSetup( '' ); @@ -50,7 +55,7 @@ describe('no-focusable-content tests', function() { it('should add each focusable child as related nodes', function() { var params = checkSetup( - '' + '' ); assert.isFalse(noFocusableContent.apply(checkContext, params)); @@ -61,7 +66,7 @@ describe('no-focusable-content tests', function() { ]); }); - it('should return false if element has natively focusable content with negative tabindex', function() { + it('should return false if element has natively focusable widget role content with negative tabindex', function() { var params = checkSetup( '' ); @@ -71,25 +76,32 @@ describe('no-focusable-content tests', function() { assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]); }); - it('should return true on span with tabindex=-1', function() { + it('should return true if element has content which is natively focusable and has a widget role but is disabled', function() { + var vNode = queryFixture( + '' + ); + assert.isTrue(noFocusableContent(null, null, vNode)); + }); + + it('should return true on span with negative tabindex (focusable, does not have a widget role)', function() { var vNode = queryFixture(' some text ' +'JavaScript is able to focus this ' +''); assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return true on aria-hidden span with tabindex=-1', function() { + it('should return true on aria-hidden span with negative tabindex (focusable, does not have a widget role)', function() { var vNode = queryFixture(' some text ' +' ' +''); assert.isTrue(noFocusableContent(null, null, vNode)); }); - it('should return false on span with tabindex=0', function() { + it('should return true on nested span with tabindex=0 (focusable, does not have a widget role)', function() { var vNode = queryFixture(' some text ' +'anyone is able to focus this ' +''); - assert.isFalse(noFocusableContent(null, null, vNode)); + assert.isTrue(noFocusableContent(null, null, vNode)); }); }); diff --git a/test/integration/rules/aria-text/aria-text.html b/test/integration/rules/aria-text/aria-text.html index 4059f1e53b..54809b6bd5 100644 --- a/test/integration/rules/aria-text/aria-text.html +++ b/test/integration/rules/aria-text/aria-text.html @@ -15,8 +15,16 @@

Flattened text because of the explicit role.
-
+
Flattened text because of the - explicit role. Considered non-focusable because of tabindex=-1... + explicit role. +
+

+

+

Hello

+ + -

diff --git a/test/integration/rules/aria-text/aria-text.json b/test/integration/rules/aria-text/aria-text.json index 3aa00ff23b..9443502a16 100644 --- a/test/integration/rules/aria-text/aria-text.json +++ b/test/integration/rules/aria-text/aria-text.json @@ -1,6 +1,6 @@ { "description": "aria-text tests", "rule": "aria-text", - "violations": [["#fail1"], ["#fail2"], ["#fail3"]], - "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"]] + "violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"]], + "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"], ["#pass5"], ["#pass6"]] } diff --git a/test/integration/rules/nested-interactive/nested-interactive.html b/test/integration/rules/nested-interactive/nested-interactive.html index adec643ff2..1af908b261 100644 --- a/test/integration/rules/nested-interactive/nested-interactive.html +++ b/test/integration/rules/nested-interactive/nested-interactive.html @@ -6,13 +6,13 @@ - -
- - - - - + +
+ + + + + ignored ignored diff --git a/test/integration/rules/nested-interactive/nested-interactive.json b/test/integration/rules/nested-interactive/nested-interactive.json index 434b22bb90..4db1a12cdb 100644 --- a/test/integration/rules/nested-interactive/nested-interactive.json +++ b/test/integration/rules/nested-interactive/nested-interactive.json @@ -6,9 +6,7 @@ ["#fail2"], ["#fail3"], ["#fail4"], - ["#fail5"], - ["#fail6"], - ["#fail7"] + ["#fail5"] ], "passes": [ ["#pass1"], @@ -17,6 +15,10 @@ ["#pass4"], ["#pass5"], ["#pass6"], - ["#pass7"] + ["#pass7"], + ["#pass8"], + ["#pass9"], + ["#pass10"], + ["#pass11"] ] } diff --git a/test/integration/virtual-rules/nested-interactive.js b/test/integration/virtual-rules/nested-interactive.js index cd364e2b22..fbb94c136b 100644 --- a/test/integration/virtual-rules/nested-interactive.js +++ b/test/integration/virtual-rules/nested-interactive.js @@ -74,7 +74,7 @@ describe('nested-interactive virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); - it('should fail for element with focusable content', function() { + it('should pass for element with non-widget content', function() { var node = new axe.SerialVirtualNode({ nodeName: 'button' }); @@ -89,12 +89,12 @@ describe('nested-interactive virtual-rule', function() { var results = axe.runVirtualRule('nested-interactive', node); - assert.lengthOf(results.passes, 0); - assert.lengthOf(results.violations, 1); + assert.lengthOf(results.passes, 1); + assert.lengthOf(results.violations, 0); assert.lengthOf(results.incomplete, 0); }); - it('should fail for element with natively focusable content', function() { + it('should fail for element with native widget content', function() { var node = new axe.SerialVirtualNode({ nodeName: 'div', attributes: { From 74d5656c1e9e7b21a16fa226d1f5c8ec407d4d4b Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 27 Nov 2021 20:36:54 -0500 Subject: [PATCH 14/24] work in progress --- test/integration/virtual-rules/nested-interactive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/virtual-rules/nested-interactive.js b/test/integration/virtual-rules/nested-interactive.js index fbb94c136b..acdb54f389 100644 --- a/test/integration/virtual-rules/nested-interactive.js +++ b/test/integration/virtual-rules/nested-interactive.js @@ -38,7 +38,7 @@ describe('nested-interactive virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); - it('should pass for element with content with tabindex=-1', function() { + it('should pass for element with non-widget content which has negative tabindex', function() { var node = new axe.SerialVirtualNode({ nodeName: 'button' }); From 54329dd5048656f4c1f81c200a9027d783cad3a2 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Mon, 29 Nov 2021 20:42:32 -0500 Subject: [PATCH 15/24] fix whitespace --- lib/checks/keyboard/no-focusable-content-evaluate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checks/keyboard/no-focusable-content-evaluate.js b/lib/checks/keyboard/no-focusable-content-evaluate.js index 8fc8aa3b34..f72bad79d7 100644 --- a/lib/checks/keyboard/no-focusable-content-evaluate.js +++ b/lib/checks/keyboard/no-focusable-content-evaluate.js @@ -42,7 +42,7 @@ function getFocusableDescendants(vNode) { const retVal = []; vNode.children.forEach(child => { const role = getRole(child); - if(getRoleType(role) === 'widget' && isFocusable(child)) { + if (getRoleType(role) === 'widget' && isFocusable(child)) { retVal.push(child); } else { retVal.push(...getFocusableDescendants(child)); From 499768f95466e6545a0410dda5a342fd576e25a6 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Mon, 29 Nov 2021 20:54:09 -0500 Subject: [PATCH 16/24] add new case to test test/checks/keyboard/no-focusable-content.js --- test/checks/keyboard/no-focusable-content.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/checks/keyboard/no-focusable-content.js b/test/checks/keyboard/no-focusable-content.js index 871169f202..68137b433b 100644 --- a/test/checks/keyboard/no-focusable-content.js +++ b/test/checks/keyboard/no-focusable-content.js @@ -43,6 +43,16 @@ describe('no-focusable-content tests', function() { assert.isTrue(noFocusableContent(null, null, vNode)); }); + it('should return false if element has content which has negative tabindex and an explicit widget role', function() { + var params = checkSetup( + '' + ); + axe.utils.getFlattenedTree(document.documentElement); + assert.isFalse(check.evaluate.apply(checkContext, params)); + assert.deepEqual(checkContext._data, { messageKey: 'notHidden' }); + assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]); + }); + it('should return false if element has content which is natively focusable and has a widget role', function() { var params = checkSetup( '' From 8c32f0306e866acfff167d8183e1091321732eb7 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Mon, 29 Nov 2021 20:55:50 -0500 Subject: [PATCH 17/24] change "disabled" test case in test/checks/keyboard/no-focusable-content.js --- test/checks/keyboard/no-focusable-content.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/checks/keyboard/no-focusable-content.js b/test/checks/keyboard/no-focusable-content.js index 68137b433b..d642bbd15e 100644 --- a/test/checks/keyboard/no-focusable-content.js +++ b/test/checks/keyboard/no-focusable-content.js @@ -88,7 +88,7 @@ describe('no-focusable-content tests', function() { it('should return true if element has content which is natively focusable and has a widget role but is disabled', function() { var vNode = queryFixture( - '' + '' ); assert.isTrue(noFocusableContent(null, null, vNode)); }); From d6a5573af6c5d23c4ec906db2536f8679e8de8c0 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sun, 5 Dec 2021 11:51:02 -0500 Subject: [PATCH 18/24] fix merge problem --- test/checks/keyboard/no-focusable-content.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/checks/keyboard/no-focusable-content.js b/test/checks/keyboard/no-focusable-content.js index 79d847d31c..d642bbd15e 100644 --- a/test/checks/keyboard/no-focusable-content.js +++ b/test/checks/keyboard/no-focusable-content.js @@ -41,7 +41,6 @@ describe('no-focusable-content tests', function() { '' ); assert.isTrue(noFocusableContent(null, null, vNode)); -<<<<<<< HEAD }); it('should return false if element has content which has negative tabindex and an explicit widget role', function() { @@ -52,8 +51,6 @@ describe('no-focusable-content tests', function() { assert.isFalse(check.evaluate.apply(checkContext, params)); assert.deepEqual(checkContext._data, { messageKey: 'notHidden' }); assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]); -======= ->>>>>>> 7e692b4a67fec1f93e362d627b94ca94980bf4f6 }); it('should return false if element has content which is natively focusable and has a widget role', function() { From e2ae194ef3ab38e4646d395fb15d2cff3c17a966 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Mon, 21 Feb 2022 18:27:31 -0500 Subject: [PATCH 19/24] fix(rules): unsupportedrole check bugs Closes issue #3282 --- lib/checks/aria/unsupportedrole-evaluate.js | 8 ++- test/checks/aria/unsupportedrole.js | 57 +++++++++++++++++---- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/lib/checks/aria/unsupportedrole-evaluate.js b/lib/checks/aria/unsupportedrole-evaluate.js index 947d8f5c8b..ec1c11cda9 100644 --- a/lib/checks/aria/unsupportedrole-evaluate.js +++ b/lib/checks/aria/unsupportedrole-evaluate.js @@ -9,7 +9,13 @@ import { isUnsupportedRole, getRole } from '../../commons/aria'; * @return {Boolean} True if the elements semantic role is unsupported. False otherwise. */ function unsupportedroleEvaluate(node, options, virtualNode) { - return isUnsupportedRole(getRole(virtualNode)); + const role = getRole(virtualNode, { dpub: true, fallback: true }); + const isUnsupported = isUnsupportedRole(role); + if (isUnsupported) { + this.data([role]); + } + return isUnsupported; + } export default unsupportedroleEvaluate; diff --git a/test/checks/aria/unsupportedrole.js b/test/checks/aria/unsupportedrole.js index 2fcf4613b3..a4949f75ee 100644 --- a/test/checks/aria/unsupportedrole.js +++ b/test/checks/aria/unsupportedrole.js @@ -1,7 +1,9 @@ describe('unsupportedrole', function() { 'use strict'; - var queryFixture = axe.testUtils.queryFixture; + var checkContext = axe.testUtils.MockCheckContext(); + var checkSetup = axe.testUtils.checkSetup; + var check = checks['unsupportedrole']; it('should return true if applied to an unsupported role', function() { axe.configure({ @@ -15,22 +17,59 @@ describe('unsupportedrole', function() { } }); - var vNode = queryFixture( + var params = checkSetup( '
Contents
' ); - assert.isTrue(checks.unsupportedrole.evaluate(null, null, vNode)); + assert.isTrue(check.evaluate.apply(checkContext, params)); }); it('should return false if applied to a supported role', function() { - var vNode = queryFixture(''); - assert.isFalse(checks.unsupportedrole.evaluate(null, null, vNode)); + var params = checkSetup(''); + assert.isFalse(check.evaluate.apply(checkContext, params)); - var vNode = queryFixture(''); - assert.isFalse(checks.unsupportedrole.evaluate(null, null, vNode)); + var params = checkSetup(''); + assert.isFalse(check.evaluate.apply(checkContext, params)); }); it('should return false if applied to an invalid role', function() { - var vNode = queryFixture(''); - assert.isFalse(checks.unsupportedrole.evaluate(null, null, vNode)); + var params = checkSetup(''); + assert.isFalse(check.evaluate.apply(checkContext, params)); }); + + it('should return true if applied to an unsupported dpub role', function() { + axe.configure({ + standards: { + ariaRoles: { + 'doc-abstract': { + type: 'section', + unsupported: true + } + } + } + }); + + var params = checkSetup( + '
Contents
' + ); + assert.isTrue(check.evaluate.apply(checkContext, params)); + }); + + it('should return true if applied to an unsupported fallback role', function() { + axe.configure({ + standards: { + ariaRoles: { + alert: { + type: 'widget', + unsupported: true + } + } + } + }); + + var params = checkSetup( + '
Contents
' + ); + assert.isTrue(check.evaluate.apply(checkContext, params)); + }); + }); From 3096c922b824479bca56952179f2579254f02ff3 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Mon, 21 Feb 2022 18:35:15 -0500 Subject: [PATCH 20/24] lint fix --- test/checks/aria/unsupportedrole.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/checks/aria/unsupportedrole.js b/test/checks/aria/unsupportedrole.js index a4949f75ee..b124265ceb 100644 --- a/test/checks/aria/unsupportedrole.js +++ b/test/checks/aria/unsupportedrole.js @@ -3,7 +3,7 @@ describe('unsupportedrole', function() { var checkContext = axe.testUtils.MockCheckContext(); var checkSetup = axe.testUtils.checkSetup; - var check = checks['unsupportedrole']; + var check = checks.unsupportedrole; it('should return true if applied to an unsupported role', function() { axe.configure({ From 9df22d11ba1bc6845024cebade439a4d5004537d Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 26 Feb 2022 19:04:01 -0500 Subject: [PATCH 21/24] add assertion on checkContext._data to unit tests --- test/checks/aria/unsupportedrole.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/checks/aria/unsupportedrole.js b/test/checks/aria/unsupportedrole.js index b124265ceb..73b2a6043f 100644 --- a/test/checks/aria/unsupportedrole.js +++ b/test/checks/aria/unsupportedrole.js @@ -4,6 +4,10 @@ describe('unsupportedrole', function() { var checkContext = axe.testUtils.MockCheckContext(); var checkSetup = axe.testUtils.checkSetup; var check = checks.unsupportedrole; + afterEach(function() { + checkContext.reset(); + axe.reset(); + }); it('should return true if applied to an unsupported role', function() { axe.configure({ @@ -21,19 +25,23 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); + assert.deepEqual(checkContext._data, ["mccheddarton"]); }); it('should return false if applied to a supported role', function() { var params = checkSetup(''); assert.isFalse(check.evaluate.apply(checkContext, params)); + assert.isNull(checkContext._data); var params = checkSetup(''); assert.isFalse(check.evaluate.apply(checkContext, params)); + assert.isNull(checkContext._data); }); it('should return false if applied to an invalid role', function() { var params = checkSetup(''); assert.isFalse(check.evaluate.apply(checkContext, params)); + assert.isNull(checkContext._data); }); it('should return true if applied to an unsupported dpub role', function() { @@ -52,6 +60,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); + assert.deepEqual(checkContext._data, ["doc-abstract"]); }); it('should return true if applied to an unsupported fallback role', function() { @@ -70,6 +79,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); + assert.deepEqual(checkContext._data, ["alert"]); }); }); From c284508503b356ab20c0f333366cef6577fd950f Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 26 Feb 2022 19:06:43 -0500 Subject: [PATCH 22/24] refactor(checks/unsupportedrole): change this.data from using array to single string to match lib/checks/aria/deprecatedrole-evaluate.js --- lib/checks/aria/unsupportedrole-evaluate.js | 2 +- test/checks/aria/unsupportedrole.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/checks/aria/unsupportedrole-evaluate.js b/lib/checks/aria/unsupportedrole-evaluate.js index ec1c11cda9..ee7ff3d71e 100644 --- a/lib/checks/aria/unsupportedrole-evaluate.js +++ b/lib/checks/aria/unsupportedrole-evaluate.js @@ -12,7 +12,7 @@ function unsupportedroleEvaluate(node, options, virtualNode) { const role = getRole(virtualNode, { dpub: true, fallback: true }); const isUnsupported = isUnsupportedRole(role); if (isUnsupported) { - this.data([role]); + this.data(role); } return isUnsupported; diff --git a/test/checks/aria/unsupportedrole.js b/test/checks/aria/unsupportedrole.js index 73b2a6043f..cf7e8e6c81 100644 --- a/test/checks/aria/unsupportedrole.js +++ b/test/checks/aria/unsupportedrole.js @@ -25,7 +25,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, ["mccheddarton"]); + assert.deepEqual(checkContext._data, "mccheddarton"); }); it('should return false if applied to a supported role', function() { @@ -60,7 +60,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, ["doc-abstract"]); + assert.deepEqual(checkContext._data, "doc-abstract"); }); it('should return true if applied to an unsupported fallback role', function() { @@ -79,7 +79,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, ["alert"]); + assert.deepEqual(checkContext._data, "alert"); }); }); From 840a581b10031ac3443615006379d3a4fc05d251 Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 26 Feb 2022 19:21:37 -0500 Subject: [PATCH 23/24] Revert "refactor(checks/unsupportedrole): change this.data from using array to single string" This reverts commit e7c757f9330b635b1ed16385b3526f2e71786488. --- lib/checks/aria/unsupportedrole-evaluate.js | 2 +- test/checks/aria/unsupportedrole.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/checks/aria/unsupportedrole-evaluate.js b/lib/checks/aria/unsupportedrole-evaluate.js index ee7ff3d71e..ec1c11cda9 100644 --- a/lib/checks/aria/unsupportedrole-evaluate.js +++ b/lib/checks/aria/unsupportedrole-evaluate.js @@ -12,7 +12,7 @@ function unsupportedroleEvaluate(node, options, virtualNode) { const role = getRole(virtualNode, { dpub: true, fallback: true }); const isUnsupported = isUnsupportedRole(role); if (isUnsupported) { - this.data(role); + this.data([role]); } return isUnsupported; diff --git a/test/checks/aria/unsupportedrole.js b/test/checks/aria/unsupportedrole.js index cf7e8e6c81..73b2a6043f 100644 --- a/test/checks/aria/unsupportedrole.js +++ b/test/checks/aria/unsupportedrole.js @@ -25,7 +25,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, "mccheddarton"); + assert.deepEqual(checkContext._data, ["mccheddarton"]); }); it('should return false if applied to a supported role', function() { @@ -60,7 +60,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, "doc-abstract"); + assert.deepEqual(checkContext._data, ["doc-abstract"]); }); it('should return true if applied to an unsupported fallback role', function() { @@ -79,7 +79,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, "alert"); + assert.deepEqual(checkContext._data, ["alert"]); }); }); From 4bbd863f7828c74878527733b77ebffd4176385f Mon Sep 17 00:00:00 2001 From: Dan Tripp Date: Sat, 26 Feb 2022 19:26:13 -0500 Subject: [PATCH 24/24] refactor(checks/unsupportedrole): change this.data from using array to single string --- lib/checks/aria/unsupportedrole-evaluate.js | 2 +- lib/checks/aria/unsupportedrole.json | 2 +- test/checks/aria/unsupportedrole.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/checks/aria/unsupportedrole-evaluate.js b/lib/checks/aria/unsupportedrole-evaluate.js index ec1c11cda9..ee7ff3d71e 100644 --- a/lib/checks/aria/unsupportedrole-evaluate.js +++ b/lib/checks/aria/unsupportedrole-evaluate.js @@ -12,7 +12,7 @@ function unsupportedroleEvaluate(node, options, virtualNode) { const role = getRole(virtualNode, { dpub: true, fallback: true }); const isUnsupported = isUnsupportedRole(role); if (isUnsupported) { - this.data([role]); + this.data(role); } return isUnsupported; diff --git a/lib/checks/aria/unsupportedrole.json b/lib/checks/aria/unsupportedrole.json index a75e9da0d9..685ec6e2e4 100644 --- a/lib/checks/aria/unsupportedrole.json +++ b/lib/checks/aria/unsupportedrole.json @@ -5,7 +5,7 @@ "impact": "critical", "messages": { "pass": "ARIA role is supported", - "fail": "The role used is not widely supported in screen readers and assistive technologies: ${data.values}" + "fail": "The role used is not widely supported in screen readers and assistive technologies: ${data}" } } } diff --git a/test/checks/aria/unsupportedrole.js b/test/checks/aria/unsupportedrole.js index 73b2a6043f..cf7e8e6c81 100644 --- a/test/checks/aria/unsupportedrole.js +++ b/test/checks/aria/unsupportedrole.js @@ -25,7 +25,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, ["mccheddarton"]); + assert.deepEqual(checkContext._data, "mccheddarton"); }); it('should return false if applied to a supported role', function() { @@ -60,7 +60,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, ["doc-abstract"]); + assert.deepEqual(checkContext._data, "doc-abstract"); }); it('should return true if applied to an unsupported fallback role', function() { @@ -79,7 +79,7 @@ describe('unsupportedrole', function() { '
Contents
' ); assert.isTrue(check.evaluate.apply(checkContext, params)); - assert.deepEqual(checkContext._data, ["alert"]); + assert.deepEqual(checkContext._data, "alert"); }); });