Skip to content

Commit

Permalink
fix(get-role): handle presentation role inheritance for vnodes with n…
Browse files Browse the repository at this point in the history
…o parent (#3801)
  • Loading branch information
dbowling committed Dec 6, 2022
1 parent 6d01604 commit b971caf
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 8 deletions.
4 changes: 4 additions & 0 deletions lib/commons/aria/get-role.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ function getInheritedRole(vNode, explicitRoleOptions) {
// if we can't look at the parent then we can't know if the node
// inherits the presentational role or not
if (!vNode.parent) {
if (!vNode.actualNode) {
return null;
}

throw new ReferenceError(
'Cannot determine role presentational inheritance of a required parent outside the current scope.'
);
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/empty-table-header.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "empty-table-header",
"selector": "th, [role=\"rowheader\"], [role=\"columnheader\"]",
"selector": "th:not([role]), [role=\"rowheader\"], [role=\"columnheader\"]",
"tags": ["cat.name-role-value", "best-practice"],
"metadata": {
"description": "Ensures table headers have discernible text",
Expand Down
22 changes: 22 additions & 0 deletions test/commons/aria/get-role.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,26 @@ describe('aria.getRole', function () {
assert.isNull(aria.getRole(node, { noPresentational: true }));
});
});

describe('SerialVirtualNode', function () {
it('works with the SerialVirtualNode', function () {
var vNode = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'button'
}
});
assert.equal(aria.getRole(vNode), 'button');
});

it('does not throw for missing parent in presentational role inheritance', function () {
var vNode = new axe.SerialVirtualNode({
nodeName: 'li'
});

assert.doesNotThrow(function () {
assert.equal(aria.getRole(vNode), 'listitem');
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,11 @@
</td>
</tr>
</table>

<table>
<tr>
<th id="ignore1" role="spinbutton">rowheader with a role</th>
</tr>
</table>
</body>
</html>
72 changes: 65 additions & 7 deletions test/integration/virtual-rules/empty-table-header.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
describe('empty-table-header virtual-rule', function () {
it('should incomplete when children are missing', function () {
it('should fail when children contain no visible text', function () {
var thNode = new axe.SerialVirtualNode({
nodeName: 'th'
});
thNode.children = [];

var results = axe.runVirtualRule('empty-table-header', thNode);

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

it('should incomplete when children are missing', function () {
var thNode = new axe.SerialVirtualNode({
nodeName: 'th'
});

var results = axe.runVirtualRule('empty-table-header', thNode);

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

it('should fail for role=rowheader', function () {
var vNode = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'rowheader'
}
});
vNode.children = [];

var results = axe.runVirtualRule('empty-table-header', vNode);

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

it('should fail for role=columnheader', function () {
var vNode = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
role: 'columnheader'
}
});
vNode.children = [];

var results = axe.runVirtualRule('empty-table-header', vNode);

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

it('should pass with a table header', function () {
var tableNode = new axe.SerialVirtualNode({
nodeName: 'table'
Expand Down Expand Up @@ -137,19 +181,33 @@ describe('empty-table-header virtual-rule', function () {
assert.lengthOf(results.incomplete, 0);
});

it('should fail if table header has no child nodes', function () {
var node = new axe.SerialVirtualNode({
it('should be inapplicable when the th has role of cell', function () {
var table = new axe.SerialVirtualNode({
nodeName: 'table'
});

var tr = new axe.SerialVirtualNode({
nodeName: 'tr'
});

var th = new axe.SerialVirtualNode({
nodeName: 'th',
attributes: {
role: 'rowheader'
role: 'cell'
}
});
node.children = [];

var results = axe.runVirtualRule('empty-table-header', node);
tr.children = [th];
tr.parent = table;
th.parent = tr;
th.children = [];
table.children = [tr];

var results = axe.runVirtualRule('empty-table-header', th);

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

0 comments on commit b971caf

Please sign in to comment.