Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create wai-aria/hidden/aria-hidden-tested-via-label.html #45694

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Changes from 16 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e16967c
Create wpt/wai-aria/states-and-properties/aria-hidden.html
Apr 12, 2024
bb7a928
Misc cleanup
Apr 13, 2024
12040b6
Add documentation, test structure and initial aria-hidden=false tests
Apr 13, 2024
b22e721
Add more aria-hidden='false' tests
Apr 13, 2024
3a6c584
Add even more aria-hidden='false' tests
Apr 13, 2024
5d6fa4a
Organize test sets structure for aria-hidden='false'
Apr 13, 2024
17370cf
Uncomment ARIAUtils functions in <script>
Apr 13, 2024
4b3b582
Fix a couple malformed tests
Apr 13, 2024
e604ad5
Test cleanup (remove generics, table tests due to engine inconsistency)
Apr 13, 2024
1396b47
Add root html/body/main tests and setAttributes() helper function
Apr 13, 2024
7598a6e
Update rendering web techniques aria-hidden comment
rahimabdi Apr 16, 2024
522d723
Update web techniques for rendering comments
Apr 16, 2024
eefe90e
More updates to test file comments
Apr 16, 2024
d0cf940
Some more web techniques for hiding (opacity, color)
Apr 16, 2024
f80ba8b
Add role=tab test
Apr 16, 2024
75f1d73
Add aria-hidden=false to role=tab test
Apr 16, 2024
fa998d8
Update file location and name for specificity
Apr 27, 2024
05d8638
Re-structure test file for clarifying label testings, including secti…
Apr 27, 2024
4c53da4
Remove faulty tests, unneeded functions
Apr 27, 2024
ce2f252
Update future testing scope in comments
Apr 27, 2024
a36fdd2
Add aria-hidden=false/true tests
Apr 27, 2024
ee7620f
Updated comment for definition/false synonymity
Apr 28, 2024
a67fad6
Add more mixed aria-hidden tests
Apr 28, 2024
2b5d651
Fix validator errors
Apr 28, 2024
91d60cd
Restructure tests and sections
Apr 28, 2024
a36b2b4
Add alternative rendering & aria-hidden tests
Apr 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions wai-aria/states-and-properties/aria-hidden.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<!doctype html>
<html>
<head>
Copy link
Contributor

@cookiecrook cookiecrook Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding test methodology, your current approach of using computedrole may not get you what you need. In theory, any of these implementations may have the element marked as "hidden" but have the backing object retain the role it would have if it were not hidden.... So these "expected role" tests as written could have both false positives and false negatives.

Another approach that may yield more consistent results between engines is to check the computedlabel of a rendered container element, that includes its label from contents. That container could have a mix of rendered or unrendered elements with mixed states of aria-hidden true and false.

As an example that may cause a failure in recent Safari builds at the moment (recently resolved in current WebKit source but not yet shipped, IIRC), since it implemented the original definition of aria-hidden=false, not the newest draft PR that the spec aligned on.

<h1 data-expectedlabel="one"><!-- not "one three" -->
  one <!-- part of the label in all implementations -->
  <span aria-hidden="true">
    two <!-- should not be part of the label in any implementation -->
    <span aria-hidden="false">
      three <!-- was part of the label in at least one older implementation before recent spec change proposal -->
    </span>
  </span>
</h1>

Likewise, aria-hidden=false should not be able to "undo" or "invert" the hidden-ness of a rendering style like display: none; or visibility: hidden;.

<h1 data-expectedlabel="one"><!-- not "one three" -->
  one <!-- part of the label in all implementations -->
  <span style="display: none;">
    two <!-- unrendered contents should not be part of the label in any implementation  -->
    <span aria-hidden="false">
      three <!-- aria-hidden=false should no longer be able to "unhide" an unrendered, hidden element, unless perhaps referenced in accname directly via aria-labelledby  -->
    </span>
  </span>
</h1>

Moving from test methodology to file naming, I'm not sure there is a good reason to have an overall states-and-properties dir, especially since some of the other features we're testing elsewhere (aria-label, aria-labelledby, etc.) are themselves properties.

I do agree that there could be a hidden or ignored directory with various files included... I expect there will be a lot more "hidden" or "ignored" tests once more test accessors are available.

Also, this file does not cover everything we'll want to determine about aria-hidden, so aria-hidden.html is too general a name, IMO. This might be renamed aria-hidden-tested-via-label.html or something more specific. Perhaps this file has a further logical split into two or more files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @cookiecrook! Ready for another review.

<title>aria-hidden 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>
<style>
.sr-only {
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
width: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}
</style>
</head>
<body>
<main id="main-element">
<h1><code>aria-hidden</code> Tests</h1>
<p>Tests the <a href="https://pr-preview.s3.amazonaws.com/w3c/aria/pull/2090.html#aria-hidden">aria-hidden</a>
ARIA state and its potential values (e.g., <code>true</code>, <code>false</code>, <code>undefined</code>)</p>
<!-- Possible aria-hidden values:
- "true" = The element is hidden from the accessibility API
- "false" = The element's hidden state is determined by the user agent based on whether it is rendered. Synonym of undefined
- "undefined" = synonym of "false"

General web techniques related to showing/hiding content:
Rendered:
- display: <anything besides 'none'> = rendered
- visibility: visible = rendered
- clipped/off-screen text = rendered
- inert = rendered (but hidden from assistive technologies)
- aria-hidden=true = rendered (but hidden from assistive technologies)
- opacity: o
- color: transparent
Not rendered:
- visibility: hidden/collapse = not rendered
- display: none = not rendered
- HTML5 hidden = not rendered
- transform: scale(0) = not rendered (but conveyed by assistive technologies)
rahimabdi marked this conversation as resolved.
Show resolved Hide resolved
-->

<h2><code>aria-hidden="true"</code></h2>
<!-- Blocked, awaiting WebDriver extension for querying accessibility tree outside of role/name per aom #203 https://github.com/WICG/aom/issues/203 -->

<!-- To-dos:
- Non-interactives: <h1>, <p>, <div>, <span> <img>, etc.
- Sectioning elements: <main>, <nav>, etc.
- Parent element is aria-hidden="true" with non-hidden children (should be hidden)
- Nested content: <span> inside <button>, <span> inside <span>, etc.
- Focusable elements (note: these should remove aria-hidden on the element and its ancestors per aria #1255 https://github.com/w3c/aria/issues/1255)
- natively focusable elements: <a>, <button>, <input type"..."">, <textarea>, etc.
- script focusable elements: <div tabindex="-1">, etc.
- ARIA role equivalents that are focusable: link, button, tab, etc.
- General ARIA roles: heading, tabpanel, tree, cell, gridcell, listitem etc.
- Root elements: <html> <body> (note: aria-hidden must be ignored on document root elements per aria #1254 https://github.com/w3c/aria/issues/1254)
- Also need additional tests for standalone SVG documents
- SVG fragments
- inert
-->

<h2><code>aria-hidden="false"</code></h2>
<!-- generics with various display properties -->
<div aria-hidden="false" data-testname="div with aria-hidden='false' is not hidden" class="ex-generic">x</div>
<div aria-hidden="false" style="display: inline;" data-testname="div with display: inline, aria-hidden='false' is not hidden" class="ex-generic">x></div>
<div aria-hidden="false" style="display: grid;" data-testname="div with display: grid, aria-hidden='false' is not hidden" class="ex-generic">x></div>
<div aria-hidden="false" style="display: flex;" data-testname="div with display: flex, aria-hidden='false' is not hidden" class="ex-generic">x></div>
<div aria-hidden="false" style="display: contents;" data-testname="div with display: contents, aria-hidden='false' is not hidden" class="ex-generic">x></div>
<span aria-hidden="false" data-testname="span with aria-hidden='false' is not hidden" class="ex-generic">x</span>
<span aria-hidden="false" style="display: block;" data-testname="span with aria-hidden='false', display: block is not hidden" class="ex-generic">x</span>
<span aria-hidden="false" style="display: grid;" data-testname="span with aria-hidden='false', display: grid is not hidden" class="ex-generic">x</span>
<span aria-hidden="false" style="display: flex;" data-testname="span with aria-hidden='false', display: flex is not hidden" class="ex-generic">x</span>
<span aria-hidden="false" style="display: contents;" data-testname="span with aria-hidden='false', display: contents is not hidden" class="ex-generic">x</span>
<div aria-hidden="false" style="transform: scale(0);" data-testname="div with transform: scale(0) and aria-hidden='false' is not hidden" class="ex-generic">x></div>
<span aria-hidden="false" data-testname="span with aria-hidden='false' and clip-path sr-only class is not hidden" class="sr-only ex-generic">x</span>

<!-- native platform elements with default display properties -->
<p aria-hidden="false" data-testname="p with aria-hidden='false' is not hidden" data-expectedrole="paragraph" class="ex-role">x</p>
<button aria-hidden="false" data-testname="button with aria-hidden='false' is not hidden" data-expectedrole="button" class="ex-role">x></button>
<input type="checkbox" aria-hidden="false" data-testname="input[checkbox] with aria-hidden='false' is not hidden" data-expectedrole="checkbox" class="ex-role">
<h3 aria-hidden="false" data-testname="h3 with aria-hidden='false' is not hidden" data-expectedrole="heading" class="ex-role">x</h3>
<nav aria-hidden="false" data-testname="nav with aria-hidden='false' is not hidden" data-expectedrole="navigation" class="ex-role">x</nav>
<table aria-hidden="false" role="table" data-testname="table with aria-hidden='false' is not hidden" data-expectedrole="table" class="ex-role">
<thead>
<tr aria-hidden="false" data-testname="tr with aria-hidden='false', inside table, are not hidden" data-expectedrole="row" class="ex-role">
<th aria-hidden="false" data-testname="th within tr and table, all with aria-hidden='false', are not hidden" data-expectedrole="columnheader" class="ex-role">x</th>
<th>x</th>
</tr>
</thead>
<tbody>
<tr>
<td aria-hidden="false" data-testname="td within table, both with aria-hidden='false', is not hidden" data-expectedrole="cell" class="ex-role">x</td>
<td>x</td>
</tr>
</tbody>
</table>
<ul aria-hidden="false" role="list" data-testname="ul with aria-hidden='false' is not hidden" data-expectedrole="list" class="ex-role">
<li aria-hidden="false" role="listitem" data-testname="li with aria-hidden='false' within ul is not hidden" data-expectedrole="listitem" class="ex-role">x</li>
<li>y</li>
</ul>

<!-- native platform elements with non-default rendering -->
<button aria-hidden="false" style="display: flex;" data-testname="button with display: contents, aria-hidden='false' is not hidden" data-expectedrole="button" class="ex-role">x></button>
<input aria-hidden="false" style="display: flex;" type="checkbox" data-testname="input[checkbox] with display: contents, aria-hidden='false' is not hidden" data-expectedrole="checkbox" class="ex-role">
<h3 aria-hidden="false" style="display: contents;" data-testname="h3 with display: contents, aria-hidden='false' is not hidden" data-expectedrole="heading" class="ex-role">x</h3>
<nav aria-hidden="false" style="display: contents;" data-testname="nav with display: contents nav, aria-hidden='false' is not hidden" data-expectedrole="navigation" class="ex-role">x</nav>
<button aria-hidden="false" style="transform: scale(0);" data-testname="button with transform: scale(0) and aria-hidden='false' is not hidden" data-expectedrole="button" class="ex-role">x></button>
<p aria-hidden="false" data-testname="p with aria-hidden='false' and clip-path sr-only class is not hidden" data-expectedrole="paragraph" class="sr-only ex-role">x</p>

<!-- explicit ARIA roles -->
<div aria-hidden="false" role="button" tabindex="0" data-testname="div with aria-hidden='false', button role and tabindex='0' is not hidden" data-expectedrole="button" class="ex-role">x</div>
<div aria-hidden="false" role="heading" aria-level="3" data-testname="div with aria-hidden='false', heading role and aria-level='3' is not hidden" data-expectedrole="heading" class="ex-role">x</div>
<div aria-hidden="false" role="navigation" aria-label="label" data-testname="div with aria-hidden='false', navigation role and aria-label is not hidden" data-expectedrole="navigation" class="ex-role">x</div>
<span aria-hidden="false" role="link" tabindex="0" data-testname="span with aria-hidden='false', link role and tabindex='0' is not hidden" data-expectedrole="link" class="ex-role">x</span>
<span aria-hidden="false" role="region" aria-label="label" data-testname="span with aria-hidden='false', region role and aria-label is not hidden" data-expectedrole="region" class="ex-role">x</span>
<span aria-hidden="false" role="checkbox" aria-checked="true" data-testname="span with aria-hidden='false' and checkbox role is not hidden" data-expectedrole="checkbox" class="ex-role">x</span>
<div role="tablist">
<div role="tab">x</div>
<div aria-hidden="false" role="tab" aria-selected="true" data-testname="div with aria-hidden='false' and tab role is not hidden" data-expectedrole="tab" class="ex-role">x</div>
</div>
<div aria-hidden="false" role="tabpanel" hidden>x</div>
<div aria-hidden="false" role="tabpanel" data-testname="div with aria-hidden='false' and tabpanel role is not hidden" data-expectedrole="tabpanel" class="ex-role">x</div>

<script>
AriaUtils.verifyRolesBySelector(".ex-role");
AriaUtils.verifyGenericRolesBySelector(".ex-generic");
verifyAriaHiddenFalseForOtherElements();

function verifyAriaHiddenFalseForOtherElements() {
var htmlElement = document.documentElement;
var bodyElement = document.body;
var mainElement = document.getElementById("main-element");

setAttributesForTesting(htmlElement, {
'aria-hidden': 'false',
'data-testname': 'html root element with aria-hidden=\'false\' is not hidden',
'data-expectedrole': 'document',
'class': 'ex-role-other-elements'
})
setAttributesForTesting(bodyElement, {
'aria-hidden': 'false',
'data-testname': 'body element with aria-hidden=\'false\' is not hidden',
'class': 'ex-generic-other-elements'
})
setAttributesForTesting(mainElement, {
'aria-hidden': 'false',
'data-testname': 'main element with aria-hidden=\'false\' is not hidden',
'data-expectedrole': 'main',
'class': 'ex-role-other-elements'
})

AriaUtils.verifyRolesBySelector(".ex-role-other-elements");
AriaUtils.verifyGenericRolesBySelector(".ex-generic-other-elements");
};

function setAttributesForTesting(el, elAttributes) {
for (let i in elAttributes) {
el.setAttribute(i, elAttributes[i]);
}
}
</script>
</main>
</body>
</html>