Skip to content

Commit

Permalink
AX: Fix failing WPT menu-roles test
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=261457
rdar://problem/115336495

Reviewed by Tyler Wilcock.

Currently, some of the WPT menu-roles tests[1] have failed. According to
the ARIA spec[2], if a menuitem has a group as first parent and a menu
or menubar as the second parent, it must be a menuitem role.

[1]: https://wpt.fyi/results/wai-aria/role/menu-roles.html
[2]: https://w3c.github.io/aria/#menu

* LayoutTests/accessibility/roles-computedRoleString.html:
* LayoutTests/platform/mac/accessibility/roles-computedRoleString-expected.txt:
* Source/WebCore/accessibility/AccessibilityNodeObject.cpp:
(WebCore::AccessibilityNodeObject::remapAriaRoleDueToParent const):

Canonical link: https://commits.webkit.org/267955@main
  • Loading branch information
hs85jeong authored and twilco committed Sep 13, 2023
1 parent 32c5191 commit 2e6a387
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 3 deletions.
6 changes: 6 additions & 0 deletions LayoutTests/accessibility/roles-computedRoleString.html
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,17 @@ <h2 id="section-label">X</h2>
<div role="menuitem" data-role="menuitem" data-platform="atspi,mac" class="ex">X</div>
<div role="menuitemcheckbox" data-role="menuitemcheckbox" data-platform="atspi,mac" class="ex">X</div>
<div role="menuitemradio" data-role="menuitemradio" data-platform="atspi,mac" class="ex">X</div>
<div role="group" data-role="group" data-platform="atspi,mac" class="ex">
<div role="menuitem" data-role="menuitem" data-platform="atspi,mac" class="ex">x</div>
</div>
</div>
<div role="menubar" data-role="menubar" data-platform="atspi,mac" class="ex">
<div role="menuitem" data-role="menuitem" data-platform="atspi,mac" class="ex">X</div>
<div role="menuitemcheckbox" data-role="menuitemcheckbox" data-platform="atspi,mac" class="ex">X</div>
<div role="menuitemradio" data-role="menuitemradio" data-platform="atspi,mac" class="ex">X</div>
<div role="group" data-role="group" data-platform="atspi,mac" class="ex">
<div role="menuitem" data-role="menuitem" data-platform="atspi,mac" class="ex">x</div>
</div>
</div>
<div role="meter" data-role="meter" data-platform="atspi,mac" class="ex">X</div>
<div role="navigation" data-role="navigation" data-platform="atspi,mac" class="ex">X</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Tests menu and related roles.

x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

PASS role is menu
PASS role is menuitem (in menu)
PASS role is group (in menu)
PASS role is menuitem (in group, in menu)
PASS role is menuitemradio (in group, in menu)
PASS role is menuitemcheckbox (in group, in menu)
PASS role is menubar
PASS role is menuitem (in menubar)
PASS role is group (in menubar)
PASS role is menuitem (in group, in menubar)
PASS role is menuitemradio (in group, in menubar)
PASS role is menuitemcheckbox (in group, in menubar)
FAIL orphaned menuitem outside the context of menu/menubar assert_equals: <nav role="menuitem" data-testname="orphaned menuitem outside the context of menu/menubar" data-expectedrole="navigation" class="ex">x
</nav> expected "navigation" but got "menuitem"
FAIL orphaned menuitemradio outside the context of menu/menubar assert_equals: <nav role="menuitemradio" data-testname="orphaned menuitemradio outside the context of menu/menubar" data-expectedrole="navigation" class="ex">x
</nav> expected "navigation" but got "menuitemradio"
FAIL orphaned menuitemcheckbox outside the context of menu/menubar assert_equals: <nav role="menuitemcheckbox" data-testname="orphaned menuitemcheckbox outside the context of menu/menubar" data-expectedrole="navigation" class="ex">x
</nav> expected "navigation" but got "menuitemcheckbox"

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!doctype html>
<html>
<head>
<title>Menu-related Role Verification Tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/wai-aria/scripts/aria-utils.js"></script>
</head>
<style>
/* Typically horizontal */
[role="menubar"] {
display: flex;
}
</style>
<body>

<p>Tests <a href="https://w3c.github.io/aria/#menu">menu</a> and related roles.</p>

<div role="menu" data-testname="role is menu" data-expectedrole="menu" class="ex">
<div role="menuitem" data-testname="role is menuitem (in menu)" data-expectedrole="menuitem" class="ex">x</div>
<div role="menuitem">x</div>
<div role="menuitem">x</div>
<div role="group" data-testname="role is group (in menu)" data-expectedrole="group" class="ex">
<div role="menuitem" data-testname="role is menuitem (in group, in menu)" data-expectedrole="menuitem" class="ex">x</div>
<div role="menuitem">x</div>
</div>
<div role="group">
<div role="menuitemradio" aria-checked="true" data-testname="role is menuitemradio (in group, in menu)" data-expectedrole="menuitemradio" class="ex">x</div>
<div role="menuitemradio">x</div>
</div>
<div role="group">
<div role="menuitemcheckbox" aria-checked="true" data-testname="role is menuitemcheckbox (in group, in menu)" data-expectedrole="menuitemcheckbox" class="ex">x</div>
<div role="menuitemcheckbox">x</div>
</div>
</div>

<div role="menubar" data-testname="role is menubar" data-expectedrole="menubar" class="ex">
<div role="menuitem" data-testname="role is menuitem (in menubar)" data-expectedrole="menuitem" class="ex">x</div>
<div role="menuitem">x</div>
<div role="menuitem">x</div>
<div role="group" data-testname="role is group (in menubar)" data-expectedrole="group" class="ex">
<div role="menuitem" data-testname="role is menuitem (in group, in menubar)" data-expectedrole="menuitem" class="ex">x</div>
<div role="menuitem">x</div>
</div>
<div role="group">
<div role="menuitemradio" aria-checked="true" data-testname="role is menuitemradio (in group, in menubar)" data-expectedrole="menuitemradio" class="ex">x</div>
<div role="menuitemradio">x</div>
</div>
<div role="group">
<div role="menuitemcheckbox" aria-checked="true" data-testname="role is menuitemcheckbox (in group, in menubar)" data-expectedrole="menuitemcheckbox" class="ex">x</div>
<div role="menuitemcheckbox">x</div>
</div>
</div>

<nav role="menuitem" data-testname="orphaned menuitem outside the context of menu/menubar" data-expectedrole="navigation"
class="ex">x
</nav>
<nav role="menuitemradio" data-testname="orphaned menuitemradio outside the context of menu/menubar" data-expectedrole="navigation"
class="ex">x
</nav>
<nav role="menuitemcheckbox" data-testname="orphaned menuitemcheckbox outside the context of menu/menubar" data-expectedrole="navigation"
class="ex">x
</nav>

<script>
AriaUtils.verifyRolesBySelector(".ex");
</script>

</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ PASS div[role="menu"] -> menu.
PASS div[role="menuitem"] -> menuitem.
PASS div[role="menuitemcheckbox"] -> menuitemcheckbox.
PASS div[role="menuitemradio"] -> menuitemradio.
PASS div[role="group"] -> group.
PASS div[role="menuitem"] -> menuitem.
PASS div[role="menubar"] -> menubar.
PASS div[role="menuitem"] -> menuitem.
PASS div[role="menuitemcheckbox"] -> menuitemcheckbox.
PASS div[role="menuitemradio"] -> menuitemradio.
PASS div[role="group"] -> group.
PASS div[role="menuitem"] -> menuitem.
PASS div[role="meter"] -> meter.
PASS div[role="navigation"] -> navigation.
PASS div[role="note"] -> note.
Expand Down
3 changes: 0 additions & 3 deletions Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2894,9 +2894,6 @@ AccessibilityRole AccessibilityNodeObject::remapAriaRoleDueToParent(Accessibilit
// Selects and listboxes both have options as child roles, but they map to different roles within WebCore.
if (role == AccessibilityRole::ListBoxOption && parentAriaRole == AccessibilityRole::Menu)
return AccessibilityRole::MenuItem;
// An aria "menuitem" may map to MenuButton or MenuItem depending on its parent.
if (role == AccessibilityRole::MenuItem && parentAriaRole == AccessibilityRole::ApplicationGroup)
return AccessibilityRole::MenuButton;

// If the parent had a different role, then we don't need to continue searching up the chain.
if (parentAriaRole != AccessibilityRole::Unknown)
Expand Down

0 comments on commit 2e6a387

Please sign in to comment.