From 3f96aa106d061f9aa64d32a5be9e0425e82b6bab Mon Sep 17 00:00:00 2001 From: Paul Grenier Date: Thu, 2 May 2019 15:59:34 -0400 Subject: [PATCH] fix(multiple-label): no longer raises issue when aria-labelledby overrides how AT views multiple labels --- lib/checks/label/multiple-label.js | 20 ++++++------ test/checks/label/multiple-label.js | 48 +++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/lib/checks/label/multiple-label.js b/lib/checks/label/multiple-label.js index 67dd91ae7c..59787c3c4c 100644 --- a/lib/checks/label/multiple-label.js +++ b/lib/checks/label/multiple-label.js @@ -4,15 +4,7 @@ let parent = node.parentNode; if (labels.length) { // filter out hidden labels because they're fine - // except: fail first label if hidden because of VO - labels = labels.filter(function(label, index) { - if ( - (index === 0 && !axe.commons.dom.isVisible(label, true)) || - axe.commons.dom.isVisible(label, true) - ) { - return label; - } - }); + labels = labels.filter(label => axe.commons.dom.isVisible(label, true)); } while (parent) { @@ -26,4 +18,14 @@ while (parent) { } this.relatedNodes(labels); + +if (labels.length > 1) { + const labelledby = axe.commons.dom.idrefs(node, 'aria-labelledby'); + return !labels.every(function(label) { + return ( + labelledby.includes(label) || !axe.commons.dom.isVisible(label, true) + ); + }); +} + return labels.length > 1; diff --git a/test/checks/label/multiple-label.js b/test/checks/label/multiple-label.js index 971a5137b7..f1948f845a 100644 --- a/test/checks/label/multiple-label.js +++ b/test/checks/label/multiple-label.js @@ -69,19 +69,7 @@ describe('multiple-label', function() { assert.deepEqual(checkContext._relatedNodes, [l1]); }); - it('should return true if there are multiple explicit labels but the first one is hidden', function() { - fixture.innerHTML = - '' + - '' + - ''; - var target = fixture.querySelector('#test-input2'); - var l1 = fixture.querySelector('#l1'); - var l2 = fixture.querySelector('#l2'); - assert.isTrue(checks['multiple-label'].evaluate.call(checkContext, target)); - assert.deepEqual(checkContext._relatedNodes, [l1, l2]); - }); - - it('should return true if there are multiple explicit labels but the first one is hidden', function() { + it('should return true if there are multiple explicit labels but some are hidden', function() { fixture.innerHTML = '' + '' + @@ -112,4 +100,38 @@ describe('multiple-label', function() { checks['multiple-label'].evaluate.call(checkContext, target) ); }); + + it('should return false given multiple labels if aria-labelledby points to visible label', function() { + fixture.innerHTML = ''; + fixture.innerHTML += ''; + fixture.innerHTML += + ''; + var target = fixture.querySelector('#target'); + assert.isFalse( + checks['multiple-label'].evaluate.call(checkContext, target) + ); + }); + + it('should return false given multiple labels if aria-labelledby points non aria-hidden label', function() { + fixture.innerHTML = ''; + fixture.innerHTML += ''; + fixture.innerHTML += + ''; + var target = fixture.querySelector('#target'); + assert.isFalse( + checks['multiple-label'].evaluate.call(checkContext, target) + ); + }); + + it('should return false given multiple labels if aria-labelledby points to all labels', function() { + fixture.innerHTML = + ''; + fixture.innerHTML += ''; + fixture.innerHTML += + ''; + var target = fixture.querySelector('#target'); + assert.isFalse( + checks['multiple-label'].evaluate.call(checkContext, target) + ); + }); });