Skip to content

Commit

Permalink
feat(new-rule): check that treeitem role has an accessible name (#2615)
Browse files Browse the repository at this point in the history
  • Loading branch information
WilcoFiers authored Nov 2, 2020
1 parent fcdbdbc commit 5e95153
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/rule-descriptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Rules that do not necessarily conform to WCAG success criterion but are industry
| :----------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- | :----------------- | :---------------------------------------------- | :------------------------- |
| [accesskeys](https://dequeuniversity.com/rules/axe/4.0/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure |
| [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.0/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review |
| [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.0/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review |
| [empty-heading](https://dequeuniversity.com/rules/axe/4.0/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review |
| [frame-tested](https://dequeuniversity.com/rules/axe/4.0/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review |
| [frame-title-unique](https://dequeuniversity.com/rules/axe/4.0/frame-title-unique?application=RuleDescription) | Ensures <iframe> and <frame> elements contain a unique title attribute | Serious | cat.text-alternatives, best-practice | failure |
Expand Down
18 changes: 18 additions & 0 deletions lib/rules/aria-treeitem-name.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": "aria-treeitem-name",
"selector": "[role=\"treeitem\"]",
"matches": "no-naming-method-matches",
"tags": ["cat.aria", "best-practice"],
"metadata": {
"description": "Ensures every ARIA treeitem node has an accessible name",
"help": "ARIA treeitem nodes must have an accessible name"
},
"all": [],
"any": [
"has-visible-text",
"aria-labelledby",
"aria-label",
"non-empty-title"
],
"none": []
}
32 changes: 32 additions & 0 deletions test/integration/rules/aria-treeitem-name/aria-treeitem-name.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!-- PASS -->
<div role="tree">
<div id="pass1" role="treeitem">Item</div>
<div id="pass2" role="treeitem" title="Item"></div>
<div id="pass3" role="treeitem" aria-label="Item"></div>
<div id="pass4" role="treeitem" aria-labelledby="item"></div>
</div>

<div id="item">Item</div>

<!-- FAIL -->
<div role="tree">
<div id="fail1" role="treeitem"></div>
<div id="fail2" role="treeitem" aria-labelledby="item-non-existant"></div>
<div id="fail3" role="treeitem" aria-labelledby="item-empty"></div>
</div>

<div id="item-empty"></div>

<!-- INAPPLICABLE -->
<div role="tree">
<img role="treeitem" alt="Label" id="inapplicable1" />
<input role="treeitem" title="Label" id="inapplicable2" />
<button role="treeitem" title="Label" id="inapplicable3"></button>
<a href="#" role="treeitem" title="Label" id="inapplicable4"></a>
<select role="treeitem" title="Label" id="inapplicable5">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
</select>
<textarea role="treeitem" id="inapplicable6" title="Label"></textarea>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"description": "aria-treeitem-name test",
"rule": "aria-treeitem-name",
"passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"]],
"violations": [["#fail1"], ["#fail2"], ["#fail3"]]
}
89 changes: 89 additions & 0 deletions test/integration/virtual-rules/aria-treeitem-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
describe('aria-treeitem-name', function() {
it('should pass for aria-label', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'treeitem',
'aria-label': 'foobar'
}
});
node.parent = null;

var results = axe.runVirtualRule('aria-treeitem-name', node);

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});

it('should incomplete for aria-labelledby', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'treeitem',
'aria-labelledby': 'foobar'
}
});
node.parent = null;

var results = axe.runVirtualRule('aria-treeitem-name', node);

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 1);
});

it('should pass for title', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'treeitem',
title: 'foobar'
}
});
// children are required since titleText comes after subtree text
// in accessible name calculation
node.children = [];
node.parent = null;

var results = axe.runVirtualRule('aria-treeitem-name', node);

assert.lengthOf(results.passes, 1);
assert.lengthOf(results.violations, 0);
assert.lengthOf(results.incomplete, 0);
});

it('should fail when aria-label contains only whitespace', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'treeitem',
'aria-label': ' \t \n '
}
});
node.children = [];

var results = axe.runVirtualRule('aria-treeitem-name', node);

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});

it('should fail when title is empty', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'treeitem',
title: ''
}
});
node.children = [];

var results = axe.runVirtualRule('aria-treeitem-name', node);

assert.lengthOf(results.passes, 0);
assert.lengthOf(results.violations, 1);
assert.lengthOf(results.incomplete, 0);
});
});
1 change: 1 addition & 0 deletions test/integration/virtual-rules/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<script src="aria-progressbar-name.js"></script>
<script src="aria-toggle-field-name.js"></script>
<script src="aria-tooltip-name.js"></script>
<script src="aria-treeitem-name.js"></script>
<script src="autocomplete-valid.js"></script>
<script src="button-name.js"></script>
<script src="frame-title.js"></script>
Expand Down

0 comments on commit 5e95153

Please sign in to comment.