From 4685270af0d1f737d38a0c06b59137c967679227 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 3 Jun 2022 08:26:28 -0600 Subject: [PATCH] fix(aria-required-parent): allow nested group and presentational roles (#3492) * fix(aria-required-parent): allow nested group and presentational roles * update * remove comments --- .../aria/aria-required-parent-evaluate.js | 25 +++++++++---------- test/checks/aria/required-parent.js | 11 ++++++++ .../aria-required-parent.html | 12 +++++++++ .../aria-required-parent.json | 3 ++- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/checks/aria/aria-required-parent-evaluate.js b/lib/checks/aria/aria-required-parent-evaluate.js index d29e0789a0..c985cedc27 100644 --- a/lib/checks/aria/aria-required-parent-evaluate.js +++ b/lib/checks/aria/aria-required-parent-evaluate.js @@ -18,31 +18,30 @@ function getMissingContext( return null; } + const allowsGroup = reqContext.includes('group'); let vNode = includeElement ? virtualNode : virtualNode.parent; + while (vNode) { - const parentRole = getRole(vNode); + const role = getRole(vNode, { noPresentational: true }); - // if parent node has role=group and role=group is an allowed - // context, check next parent - if (reqContext.includes('group') && parentRole === 'group') { + // if parent node has no role or is presentational, or if role + // allows group, we keep parsing the parent tree. + // this means intermediate roles between a required parent and + // child will fail the check + if (!role) { + vNode = vNode.parent; + } else if (role === 'group' && allowsGroup) { // Allow the own role; i.e. tree > treeitem > group > treeitem if (ownGroupRoles.includes(explicitRole)) { reqContext.push(explicitRole); } reqContext = reqContext.filter(r => r !== 'group'); vNode = vNode.parent; - continue; - } - - // if parent node has a role that is not the required role and not - // presentational we will fail the check - if (reqContext.includes(parentRole)) { + } else if (reqContext.includes(role)) { return null; - } else if (parentRole && !['presentation', 'none'].includes(parentRole)) { + } else { return reqContext; } - - vNode = vNode.parent; } return reqContext; diff --git a/test/checks/aria/required-parent.js b/test/checks/aria/required-parent.js index 1933be5992..adbb3ea33a 100644 --- a/test/checks/aria/required-parent.js +++ b/test/checks/aria/required-parent.js @@ -243,6 +243,17 @@ describe('aria-required-parent', function() { ); }); + it('should pass for multiple group and presentational roles', function() { + var params = checkSetup( + '