From e0403f48ee86e883548cd1f40927a3b5edaeb974 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Wed, 28 Sep 2022 18:10:17 +0200 Subject: [PATCH] fix(td-headers-attr): ignore hidden cells with headers attr (#3684) * fix(td-headers-attr): ignore table elements with their role changed * add aria-hidden test --- lib/checks/tables/td-headers-attr-evaluate.js | 3 +- test/checks/tables/td-headers-attr.js | 140 ++++++++++-------- .../td-headers-attr/td-headers-attr.html | 5 + .../td-headers-attr/td-headers-attr.json | 2 +- 4 files changed, 84 insertions(+), 66 deletions(-) diff --git a/lib/checks/tables/td-headers-attr-evaluate.js b/lib/checks/tables/td-headers-attr-evaluate.js index e781330794..caef8f9a3a 100644 --- a/lib/checks/tables/td-headers-attr-evaluate.js +++ b/lib/checks/tables/td-headers-attr-evaluate.js @@ -1,4 +1,5 @@ import { tokenList } from '../../core/utils'; +import { isVisibleForScreenreader } from '../../commons/dom'; function tdHeadersAttrEvaluate(node) { const cells = []; @@ -24,7 +25,7 @@ function tdHeadersAttrEvaluate(node) { let isSelf = false; let notOfTable = false; - if (!cell.hasAttribute('headers')) { + if (!cell.hasAttribute('headers') || !isVisibleForScreenreader(cell)) { return; } diff --git a/test/checks/tables/td-headers-attr.js b/test/checks/tables/td-headers-attr.js index 8df3cc03e3..4fe08bc0b6 100644 --- a/test/checks/tables/td-headers-attr.js +++ b/test/checks/tables/td-headers-attr.js @@ -3,122 +3,134 @@ describe('td-headers-attr', function () { var fixture = document.getElementById('fixture'); var checkContext = axe.testUtils.MockCheckContext(); + var fixtureSetup = axe.testUtils.fixtureSetup; + var check = axe.testUtils.getCheckEvaluate('td-headers-attr'); afterEach(function () { - fixture.innerHTML = ''; checkContext.reset(); }); it('returns true no headers attribute is present', function () { - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
hi hello
hi hello
'; + ' hi hello ' + + ' hi hello ' + + '' + ); var node = fixture.querySelector('table'); - assert.isTrue( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) - ); + assert.isTrue(check.call(checkContext, node)); }); it('returns true if a valid header is present', function () { - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
hello
goodbye
'; + ' hello ' + + ' goodbye ' + + '' + ); var node = fixture.querySelector('table'); - assert.isTrue( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) - ); + assert.isTrue(check.call(checkContext, node)); }); it('returns true if multiple valid headers are present', function () { - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
hello hello
goodbye
'; + ' hello hello ' + + ' goodbye ' + + '' + ); var node = fixture.querySelector('table'); - assert.isTrue( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) - ); + assert.isTrue(check.call(checkContext, node)); }); it('returns true with an empty header', function () { - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
goodbye
'; + ' ' + + ' goodbye ' + + '' + ); var node = fixture.querySelector('table'); - assert.isTrue( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) - ); + assert.isTrue(check.call(checkContext, node)); }); it('returns undefined if headers is empty', function () { - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
goodbye
'; + ' ' + + ' goodbye ' + + '' + ); var node = fixture.querySelector('table'); - assert.isUndefined( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) - ); + assert.isUndefined(check.call(checkContext, node)); }); it('returns false if the header is a table cell', function () { var node; - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
hello
goodbye
'; - node = fixture.querySelector('table'); - assert.isFalse( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) + ' hello ' + + ' goodbye ' + + '' ); + node = fixture.querySelector('table'); + assert.isFalse(check.call(checkContext, node)); - fixture.innerHTML = + fixtureSetup( 'hello' + - '' + - ' ' + - ' ' + - '
goodbye
'; - node = fixture.querySelector('table'); - assert.isFalse( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) + '' + + ' ' + + ' ' + + '
goodbye
' ); + node = fixture.querySelector('table'); + assert.isFalse(check.call(checkContext, node)); - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
hello
goodbye
'; - node = fixture.querySelector('table'); - assert.isFalse( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) + ' hello ' + + ' goodbye ' + + '' ); + node = fixture.querySelector('table'); + assert.isFalse(check.call(checkContext, node)); }); it('returns false if the header refers to the same cell', function () { - fixture.innerHTML = + fixtureSetup( '' + - ' ' + - ' ' + - '
hello
goodbye
'; + ' hello ' + + ' goodbye ' + + '' + ); var node = fixture.querySelector('table'); - assert.isFalse( - axe.testUtils.getCheckEvaluate('td-headers-attr').call(checkContext, node) + assert.isFalse(check.call(checkContext, node)); + }); + + it('returns true if td[headers] is hidden', function () { + fixtureSetup( + '' + + ' ' + + '
Hello
' ); + var node = fixture.querySelector('table'); + assert.isTrue(check.call(checkContext, node)); + }); + + it('returns true if td[headers] has aria-hidden=true', function () { + fixtureSetup( + '' + + ' ' + + '
Hello
' + ); + var node = fixture.querySelector('table'); + assert.isTrue(check.call(checkContext, node)); }); }); diff --git a/test/integration/rules/td-headers-attr/td-headers-attr.html b/test/integration/rules/td-headers-attr/td-headers-attr.html index c0afe4060a..64fc6cb33c 100644 --- a/test/integration/rules/td-headers-attr/td-headers-attr.html +++ b/test/integration/rules/td-headers-attr/td-headers-attr.html @@ -14,6 +14,11 @@ World + + + +
Hello
+ diff --git a/test/integration/rules/td-headers-attr/td-headers-attr.json b/test/integration/rules/td-headers-attr/td-headers-attr.json index cda7bf99cb..e687869b6b 100644 --- a/test/integration/rules/td-headers-attr/td-headers-attr.json +++ b/test/integration/rules/td-headers-attr/td-headers-attr.json @@ -2,5 +2,5 @@ "description": "td-headers-attr test", "rule": "td-headers-attr", "violations": [["#fail1"], ["#fail2"], ["#fail3"]], - "passes": [["#pass1"], ["#pass2"], ["#pass3"]] + "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"]] }
Hello World