Skip to content

Commit

Permalink
Merge pull request #5 from dan-tripp/dequelabs-develop-2
Browse files Browse the repository at this point in the history
work in progress
  • Loading branch information
dan-tripp authored Nov 28, 2021
2 parents 5baa656 + 40025ad commit f12379e
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 32 deletions.
4 changes: 3 additions & 1 deletion lib/checks/keyboard/no-focusable-content-evaluate.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import isFocusable from '../../commons/dom/is-focusable';
import { getRole, getRoleType } from '../../commons/aria';

export default function noFocusableContentEvaluate(node, options, virtualNode) {
if (!virtualNode.children) {
Expand Down Expand Up @@ -40,7 +41,8 @@ function getFocusableDescendants(vNode) {

const retVal = [];
vNode.children.forEach(child => {
if (isFocusable(child)) {
const role = getRole(child);
if(getRoleType(role) === 'widget' && isFocusable(child)) {
retVal.push(child);
} else {
retVal.push(...getFocusableDescendants(child));
Expand Down
34 changes: 23 additions & 11 deletions test/checks/keyboard/no-focusable-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,22 @@ describe('no-focusable-content tests', function() {
assert.isTrue(noFocusableContent(null, null, vNode));
});

it('should return false if element has focusable content', function() {
it('should return true if element has content which is focusable (tabindex=0) and does not have a widget role', function() {
var params = checkSetup(
'<button id="target"><span tabindex="0">Hello</span></button>'
);

assert.isFalse(noFocusableContent.apply(checkContext, params));
assert.deepEqual(checkContext._data, null);
assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]);
assert.isTrue(noFocusableContent.apply(checkContext, params));
});

it('should return true if element has content which has negative tabindex and non-widget role', function() {
var vNode = queryFixture(
'<button id="target"><span tabindex="-1">Hello</span></button>'
);
assert.isTrue(noFocusableContent(null, null, vNode));
});

it('should return false if element has natively focusable content', function() {
it('should return false if element has content which is natively focusable and has a widget role', function() {
var params = checkSetup(
'<button id="target"><a href="foo.html">Hello</a></button>'
);
Expand All @@ -50,7 +55,7 @@ describe('no-focusable-content tests', function() {

it('should add each focusable child as related nodes', function() {
var params = checkSetup(
'<button id="target"><span tabindex="0">Hello</span><a href="foo.html">Hello</a></button>'
'<button id="target"><input type="checkbox"><a href="foo.html">Hello</a></button>'
);

assert.isFalse(noFocusableContent.apply(checkContext, params));
Expand All @@ -61,7 +66,7 @@ describe('no-focusable-content tests', function() {
]);
});

it('should return false if element has natively focusable content with negative tabindex', function() {
it('should return false if element has natively focusable widget role content with negative tabindex', function() {
var params = checkSetup(
'<button id="target"><a href="foo.html" tabindex="-1">Hello</a></button>'
);
Expand All @@ -71,25 +76,32 @@ describe('no-focusable-content tests', function() {
assert.deepEqual(checkContext._relatedNodes, [params[2].children[0]]);
});

it('should return true on span with tabindex=-1', function() {
it('should return true if element has content which is natively focusable and has a widget role but is disabled', function() {
var vNode = queryFixture(
'<button id="target"><a href="foo.html" disabled>Hello</a></button>'
);
assert.isTrue(noFocusableContent(null, null, vNode));
});

it('should return true on span with negative tabindex (focusable, does not have a widget role)', function() {
var vNode = queryFixture('<span id="target" role="text"> some text '
+'<span tabIndex="-1">JavaScript is able to focus this</span> '
+'</span>');
assert.isTrue(noFocusableContent(null, null, vNode));
});

it('should return true on aria-hidden span with tabindex=-1', function() {
it('should return true on aria-hidden span with negative tabindex (focusable, does not have a widget role)', function() {
var vNode = queryFixture('<span id="target" role="text"> some text '
+'<span tabIndex="-1" aria-hidden="true">JavaScript is able to focus this</span> '
+'</span>');
assert.isTrue(noFocusableContent(null, null, vNode));
});

it('should return false on span with tabindex=0', function() {
it('should return true on nested span with tabindex=0 (focusable, does not have a widget role)', function() {
var vNode = queryFixture('<span id="target" role="text"> some text '
+'<span tabIndex="0">anyone is able to focus this</span> '
+'</span>');
assert.isFalse(noFocusableContent(null, null, vNode));
assert.isTrue(noFocusableContent(null, null, vNode));
});

});
14 changes: 11 additions & 3 deletions test/integration/rules/aria-text/aria-text.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@ <h1>
<div role="text" id="fail2">
<a href="#" role="none">Flattened text</a> because of the explicit role.
</div>
<div role="text" id="pass4">
<div role="text" id="fail3">
<a href="#" tabindex="-1" role="none">Flattened text</a> because of the
explicit role. Considered non-focusable because of tabindex=-1...
explicit role.
</div>
<p role="text" id="fail4"><button>Hello</button></p>
<p role="text" id="fail5"><button tabindex="-1">Hello</button></p>
<p role="text" id="pass4"><span tabindex="-1">Hello</span></p>
<div role="text" id="pass5">
<a tabindex="-1">passes because no href makes this not have the implicit role of 'link'</a>
</div>
<div role="text" id="pass6">
<a>passes because no href makes this not have the implicit role of 'link'</a>
</div>
<p role="text" id="fail3"><button>Hello</button></p>
4 changes: 2 additions & 2 deletions test/integration/rules/aria-text/aria-text.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"description": "aria-text tests",
"rule": "aria-text",
"violations": [["#fail1"], ["#fail2"], ["#fail3"]],
"passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"]]
"violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"]],
"passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"], ["#pass5"], ["#pass6"]]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
<div role="radio" id="pass6"><span>pass</span></div>
<div role="radio" id="pass7"><span tabindex="-1">pass</span></div>

<button id="fail1"><span tabindex="0">fail</span></button>
<div role="button" id="fail2"><input /></div>
<div role="tab" id="fail3"><button id="pass8">div fails, button passes</button></div>
<div role="checkbox" id="fail4"><a href="foo.html">fail</a></div>
<div role="radio" id="fail5"><span tabindex="0">fail</span></div>
<div role="radio" id="fail6"><button id="pass7" tabindex="-1">not really hidden</button></div>
<div role="radio" id="fail7"><button aria-hidden="true" tabindex="-1">not really hidden</button></div>
<button id="pass8"><span tabindex="0">pass</span></button>
<div role="button" id="fail1"><input /></div>
<div role="tab" id="fail2"><button id="pass9">div fails, button passes</button></div>
<div role="checkbox" id="fail3"><a href="foo.html">fail</a></div>
<div role="radio" id="pass10"><span tabindex="0">pass</span></div>
<div role="radio" id="fail4"><button id="pass11" tabindex="-1">not really hidden</button></div>
<div role="radio" id="fail5"><button aria-hidden="true" tabindex="-1">not really hidden</button></div>

<a id="ignored1" href="foo.html">ignored</a>
<span id="ignored2">ignored</span>
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
["#fail2"],
["#fail3"],
["#fail4"],
["#fail5"],
["#fail6"],
["#fail7"]
["#fail5"]
],
"passes": [
["#pass1"],
Expand All @@ -18,6 +16,9 @@
["#pass5"],
["#pass6"],
["#pass7"],
["#pass8"]
["#pass8"],
["#pass9"],
["#pass10"],
["#pass11"]
]
}
8 changes: 4 additions & 4 deletions test/integration/virtual-rules/nested-interactive.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('nested-interactive virtual-rule', function() {
assert.lengthOf(results.incomplete, 0);
});

it('should fail for element with focusable content', function() {
it('should pass for element with non-widget content', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'button'
});
Expand All @@ -89,12 +89,12 @@ describe('nested-interactive virtual-rule', function() {

var results = axe.runVirtualRule('nested-interactive', node);

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

it('should fail for element with natively focusable content', function() {
it('should fail for element with native widget content', function() {
var node = new axe.SerialVirtualNode({
nodeName: 'div',
attributes: {
Expand Down

0 comments on commit f12379e

Please sign in to comment.