Skip to content

Commit

Permalink
fix(rule): disallow select options for labeling
Browse files Browse the repository at this point in the history
Closes #754
  • Loading branch information
Marcy Sutton committed Apr 17, 2018
1 parent adc4410 commit 7da5c9a
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 6 deletions.
8 changes: 4 additions & 4 deletions lib/commons/text/accessible-text-virtual.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function shouldCheckSubtree({ actualNode }) {
}

function shouldNeverCheckSubtree({ actualNode }) {
return ['TABLE', 'FIGURE'].includes(actualNode.nodeName.toUpperCase());
return ['TABLE', 'FIGURE', 'SELECT'].includes(actualNode.nodeName.toUpperCase());
}

/**
Expand All @@ -55,7 +55,7 @@ function shouldNeverCheckSubtree({ actualNode }) {
* @param {VirtualNode} element The VirtualNode instance whose value we want
* @return {string} The calculated value
*/
function formValueText({ actualNode }) {
function formValueText({ actualNode }, inLabelledByContext) {
const nodeName = actualNode.nodeName.toUpperCase();
if (nodeName === 'INPUT') {
if (!actualNode.hasAttribute('type') ||
Expand All @@ -65,7 +65,7 @@ function formValueText({ actualNode }) {
return '';
}

if (nodeName === 'SELECT') {
if (nodeName === 'SELECT' && inLabelledByContext) {
var opts = actualNode.options;
if (opts && opts.length) {
var returnText = '';
Expand Down Expand Up @@ -311,7 +311,7 @@ text.accessibleTextVirtual = function accessibleTextVirtual(element, inLabelledB

//Step 2e
if (inControlContext) {
returnText = formValueText(element);
returnText = formValueText(element, inLabelledByContext);
if (nonEmptyText(returnText)) {
return returnText;
}
Expand Down
37 changes: 37 additions & 0 deletions test/checks/label/implicit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ describe('implicit-label', function () {

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

afterEach(function () {
fixture.innerHTML = '';
Expand Down Expand Up @@ -39,4 +41,39 @@ describe('implicit-label', function () {
assert.isFalse(checks['implicit-label'].evaluate(node, {}, virtualNode));
});

it('should return false if label is empty for select', function () {
var params = checkSetup('<label>' +
'<span class="label"></span>' +
'<select id="target">' +
'<option value="1" selected="selected">Please choose a region</option>' +
'<option value="2">Coastal</option>' +
'<option value="3">Forest</option>' +
'<option value="4">Grasslands</option>' +
'<option value="5">Mountains</option>' +
'</select>' +
'</label>');
assert.isFalse(checks['implicit-label'].evaluate.apply(checkContext, params));
});

it('should return false if input is labeled only by select options', function () {
var params = checkSetup('<label for="target">' +
'<select id="select">' +
' <option selected="selected">Chosen</option>' +
' <option>Not Selected</option>' +
'</select>' +
'</label>' +
'<input id="target" type="text" />');
assert.isFalse(checks['implicit-label'].evaluate.apply(checkContext, params));
});

it('should return false if input is aria-labelled only by select options', function () {
var params = checkSetup('<label for="target">' +
'<select id="select">' +
' <option selected="selected">Chosen</option>' +
' <option>Not Selected</option>' +
'</select>' +
'</label>' +
'<input aria-labelledby="select" type="text" id="target" />');
assert.isFalse(checks['implicit-label'].evaluate.apply(checkContext, params));
});
});
13 changes: 13 additions & 0 deletions test/integration/rules/label/label.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<label for="fail7"></label><input type="text" id="fail7">
<label for="fail8"></label><select id="fail8"></select>
<label for="fail9"></label><textarea id="fail9"></textarea>
<label for="fail10"><select id="fail10"><option>Thing</option></select></label>
<label for="pass10">Label</label><input type="text" id="pass10">
<label for="pass11">Label</label><select id="pass11"></select>
<label for="pass12">Label</label><textarea id="pass12"></textarea>
Expand All @@ -34,4 +35,16 @@

<label><label><input type="text" id="fail22"></label></label>
<label for="fail23">Hi</label><label for="fail23">Foo</label><input type="text" id="fail23">

<div>
<label for="fail24">My Select</label>
<label for="pass16">
<select id="fail24">
<option selected="selected">Chosen</option>
<option>Not Selected</option>
</select>
</label>
<input type="text" id="pass16" />
<input aria-labelledby="fail24" type="text" id="pass17" />
</div>
</form>
8 changes: 6 additions & 2 deletions test/integration/rules/label/label.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
["#fail7"],
["#fail8"],
["#fail9"],
["#fail10"],
["#fail22"],
["#fail23"]
["#fail23"],
["#fail24"]
],
"passes": [
["#pass1"],
Expand All @@ -29,6 +31,8 @@
["#pass12"],
["#pass13"],
["#pass14"],
["#pass15"]
["#pass15"],
["#pass16"],
["#pass17"]
]
}

0 comments on commit 7da5c9a

Please sign in to comment.