From 522865cabbe1f4815b1f3e980018e24c062c8e5e Mon Sep 17 00:00:00 2001
From: Steven Lambert <2433219+straker@users.noreply.github.com>
Date: Fri, 28 Aug 2020 11:39:14 -0600
Subject: [PATCH] fix(required-parent): fail if intermediate role is not the
required parent (#2494)
* fix(required-parent): fail if intermediate role is not the required parent
* allow presentational intermediate roles
* typo
---
.../aria/aria-required-parent-evaluate.js | 5 +++
test/checks/aria/required-parent.js | 44 +++++++++++++++++++
.../aria-required-parent.html | 24 ++++++++++
.../aria-required-parent.json | 14 +++++-
4 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/lib/checks/aria/aria-required-parent-evaluate.js b/lib/checks/aria/aria-required-parent-evaluate.js
index 310a5772ac..e0694572a7 100644
--- a/lib/checks/aria/aria-required-parent-evaluate.js
+++ b/lib/checks/aria/aria-required-parent-evaluate.js
@@ -16,8 +16,13 @@ function getMissingContext(virtualNode, reqContext, includeElement) {
let vNode = includeElement ? virtualNode : virtualNode.parent;
while (vNode) {
const parentRole = getRole(vNode);
+
+ // if parent node has a role that is not the required role and not
+ // presentational we will fail the check
if (reqContext.includes(parentRole)) {
return null;
+ } else if (parentRole && !['presentation', 'none'].includes(parentRole)) {
+ return reqContext;
}
vNode = vNode.parent;
diff --git a/test/checks/aria/required-parent.js b/test/checks/aria/required-parent.js
index e082aa8b1c..10281731bf 100644
--- a/test/checks/aria/required-parent.js
+++ b/test/checks/aria/required-parent.js
@@ -106,6 +106,50 @@ describe('aria-required-parent', function() {
);
});
+ it('should fail when there is an intermediate role between the child and parent', function() {
+ var params = checkSetup(
+ '
'
+ );
+ assert.isFalse(
+ axe.testUtils
+ .getCheckEvaluate('aria-required-parent')
+ .apply(checkContext, params)
+ );
+ });
+
+ it('should pass when intermediate node is role=presentation', function() {
+ var params = checkSetup(
+ ''
+ );
+ assert.isTrue(
+ axe.testUtils
+ .getCheckEvaluate('aria-required-parent')
+ .apply(checkContext, params)
+ );
+ });
+
+ it('should pass when intermediate node is role=none', function() {
+ var params = checkSetup(
+ ''
+ );
+ assert.isTrue(
+ axe.testUtils
+ .getCheckEvaluate('aria-required-parent')
+ .apply(checkContext, params)
+ );
+ });
+
+ it('should pass when intermediate node is not owned by parent', function() {
+ var params = checkSetup(
+ ''
+ );
+ assert.isTrue(
+ axe.testUtils
+ .getCheckEvaluate('aria-required-parent')
+ .apply(checkContext, params)
+ );
+ });
+
(shadowSupported ? it : xit)(
'should pass when required parent is present across shadow boundary',
function() {
diff --git a/test/integration/rules/aria-required-parent/aria-required-parent.html b/test/integration/rules/aria-required-parent/aria-required-parent.html
index 5815dcf72d..36736ecf65 100644
--- a/test/integration/rules/aria-required-parent/aria-required-parent.html
+++ b/test/integration/rules/aria-required-parent/aria-required-parent.html
@@ -14,3 +14,27 @@
+
+
+
+
+
+
+
+
diff --git a/test/integration/rules/aria-required-parent/aria-required-parent.json b/test/integration/rules/aria-required-parent/aria-required-parent.json
index 91d50f2cfe..5bd7532210 100644
--- a/test/integration/rules/aria-required-parent/aria-required-parent.json
+++ b/test/integration/rules/aria-required-parent/aria-required-parent.json
@@ -1,7 +1,7 @@
{
"description": "aria-required-parent test",
"rule": "aria-required-parent",
- "violations": [["#fail1"], ["#fail2"], ["#fail3"]],
+ "violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"]],
"passes": [
["#pass1"],
["#pass2"],
@@ -16,6 +16,16 @@
["#pass11"],
["#pass12"],
["#pass13"],
- ["#pass14"]
+ ["#pass14"],
+ ["#pass15"],
+ ["#pass16"],
+ ["#pass17"],
+ ["#pass18"],
+ ["#pass19"],
+ ["#pass20"],
+ ["#pass21"],
+ ["#pass22"],
+ ["#pass23"],
+ ["#pass24"]
]
}