Skip to content

Commit

Permalink
fix(td-headers-attr): ignore table elements with their role changed (#…
Browse files Browse the repository at this point in the history
…3687)

* fix(td-headers-attr): ignore table elements with their role changed

* add aria-hidden test

* revert hidden cell code
  • Loading branch information
WilcoFiers committed Sep 28, 2022
1 parent 0fe4a00 commit 902d07c
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 9 deletions.
6 changes: 6 additions & 0 deletions lib/rules/table-or-grid-role-matches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { getRole } from '../commons/aria';

export default function tableOrGridRoleMatches(_, vNode) {
const role = getRole(vNode);
return ['treegrid', 'grid', 'table'].includes(role);
}
1 change: 1 addition & 0 deletions lib/rules/td-headers-attr.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"id": "td-headers-attr",
"selector": "table",
"matches": "table-or-grid-role-matches",
"tags": ["cat.tables", "wcag2a", "wcag131", "section508", "section508.22.g"],
"actIds": ["a25f45"],
"metadata": {
Expand Down
18 changes: 9 additions & 9 deletions test/checks/tables/td-headers-attr.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
describe('td-headers-attr', function() {
describe('td-headers-attr', function () {
'use strict';

var fixture = document.getElementById('fixture');
var checkContext = axe.testUtils.MockCheckContext();

afterEach(function() {
afterEach(function () {
fixture.innerHTML = '';
checkContext.reset();
});

it('returns true no headers attribute is present', function() {
it('returns true no headers attribute is present', function () {
fixture.innerHTML =
'<table>' +
' <tr> <th>hi</th> <td>hello</td> </tr>' +
Expand All @@ -22,7 +22,7 @@ describe('td-headers-attr', function() {
);
});

it('returns true if a valid header is present', function() {
it('returns true if a valid header is present', function () {
fixture.innerHTML =
'<table>' +
' <tr> <th id="hi">hello</th> </tr>' +
Expand All @@ -35,7 +35,7 @@ describe('td-headers-attr', function() {
);
});

it('returns true if multiple valid headers are present', function() {
it('returns true if multiple valid headers are present', function () {
fixture.innerHTML =
'<table>' +
' <tr> <th id="hi1">hello</th> <th id="hi2">hello</th> </tr>' +
Expand All @@ -48,7 +48,7 @@ describe('td-headers-attr', function() {
);
});

it('returns true with an empty header', function() {
it('returns true with an empty header', function () {
fixture.innerHTML =
'<table>' +
' <tr> <th id="hi1"></th> </tr>' +
Expand All @@ -61,7 +61,7 @@ describe('td-headers-attr', function() {
);
});

it('returns undefined if headers is empty', function() {
it('returns undefined if headers is empty', function () {
fixture.innerHTML =
'<table>' +
' <tr> <th id="hi"> </th> </tr>' +
Expand All @@ -74,7 +74,7 @@ describe('td-headers-attr', function() {
);
});

it('returns false if the header is a table cell', function() {
it('returns false if the header is a table cell', function () {
var node;

fixture.innerHTML =
Expand Down Expand Up @@ -109,7 +109,7 @@ describe('td-headers-attr', function() {
);
});

it('returns false if the header refers to the same cell', function() {
it('returns false if the header refers to the same cell', function () {
fixture.innerHTML =
'<table id="hi">' +
' <tr> <th>hello</th> </tr>' +
Expand Down
40 changes: 40 additions & 0 deletions test/integration/rules/td-headers-attr/td-headers-attr.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<table id="pass1">
<th>Hello</th>
<td>World</td>
</table>

<table id="pass2" role="grid">
<th id="p2h">Hello</th>
<td headers="p2h">World</td>
</table>

<table id="pass3" role="treegrid">
<th id="p3h1">Hello</th>
<th id="p3h2">Hello</th>
<td headers="p3h1 p3h2">World</td>
</table>

<table id="fail1">
<th id="f1h1">Hello</th>
<td headers="f1h1 non-existing">World</td>
</table>

<table id="fail2" role="table">
<td id="self" headers="self">World</td>
</table>

<table id="fail3" role="none" tabindex="0">
<td id="self" headers="self">World</td>
</table>

<table id="inapplicable1" role="none">
<td id="self" headers="self">World</td>
</table>

<table id="inapplicable2" role="presentation">
<td id="self" headers="self">World</td>
</table>

<table id="inapplicable3" role="region">
<td id="self" headers="self">World</td>
</table>
6 changes: 6 additions & 0 deletions test/integration/rules/td-headers-attr/td-headers-attr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"description": "td-headers-attr test",
"rule": "td-headers-attr",
"violations": [["#fail1"], ["#fail2"], ["#fail3"]],
"passes": [["#pass1"], ["#pass2"], ["#pass3"]]
}
51 changes: 51 additions & 0 deletions test/rule-matches/table-or-grid-role-matches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
describe('table-or-grid-role-matches', () => {
const { queryFixture } = axe.testUtils;
const rule = axe.utils.getRule('td-headers-attr');

it(`returns true for tables without role`, () => {
const vNode = queryFixture(`<table id="target">
<th id="h">foo</th> <td headers="h">bar</td>
</table>`);
assert.isTrue(rule.matches(vNode.actualNode, vNode));
});

['table', 'grid', 'treegrid'].forEach(role => {
it(`returns true for tables with role=${role}`, () => {
const vNode = queryFixture(`<table id="target" role="${role}">
<th id="h">foo</th> <td headers="h">bar</td>
</table>`);
assert.isTrue(rule.matches(vNode.actualNode, vNode));
});
});

['region', 'presentation', 'none'].forEach(role => {
it(`returns false for tables with role=${role}`, () => {
const vNode = queryFixture(`<table id="target" role="${role}">
<th id="h">foo</th> <td headers="h">bar</td>
</table>`);
assert.isFalse(rule.matches(vNode.actualNode, vNode));
});
});

it(`returns true for tables with an invalid role`, () => {
const vNode = queryFixture(`<table id="target" role="invalid-aria-role">
<th id="h">foo</th> <td headers="h">bar</td>
</table>`);
assert.isTrue(rule.matches(vNode.actualNode, vNode));
});

it(`returns true for focusable tables with role=none`, () => {
const vNode = queryFixture(`<table id="target" role="none" tabindex="0">
<th id="h">foo</th> <td headers="h">bar</td>
</table>`);
assert.isTrue(rule.matches(vNode.actualNode, vNode));
});

it(`returns true for tables with role=none but with a global ARIA attribute`, () => {
const vNode =
queryFixture(`<table id="target" role="none" aria-live="assertive">
<th id="h">foo</th> <td headers="h">bar</td>
</table>`);
assert.isTrue(rule.matches(vNode.actualNode, vNode));
});
});

0 comments on commit 902d07c

Please sign in to comment.