Skip to content

Commit

Permalink
Merge pull request #437 from dequelabs/sd/media-checks
Browse files Browse the repository at this point in the history
shadowDOM for media checks
  • Loading branch information
dylanb authored Jul 15, 2017
2 parents 3087e90 + f996d0f commit b7008e1
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 42 deletions.
17 changes: 7 additions & 10 deletions lib/checks/media/caption.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
var tracks = node.querySelectorAll('track');
var tracks = axe.utils.querySelectorAll(virtualNode, 'track');

if (tracks.length) {
for (var i=0; i<tracks.length; i++) {
var kind = tracks[i].getAttribute('kind');
if (kind && kind === 'captions') {
// only return for matching track, in case there are multiple
return false;
}
}
return true;
// return false if any track has kind === 'caption'
return !tracks.some(({ actualNode }) => (
(actualNode.getAttribute('kind') || '').toLowerCase() === 'captions'
));
}
// for multiple track elements, return the first one that matches
// Undefined if there are no tracks - media may be decorative
return undefined;
18 changes: 9 additions & 9 deletions lib/checks/media/description.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
var tracks = node.querySelectorAll('track');
var tracks = axe.utils.querySelectorAll(virtualNode, 'track');

if (tracks.length) {
for (var i=0; i<tracks.length; i++) {
var kind = tracks[i].getAttribute('kind');
if (kind && kind === 'descriptions') {
// only return for matching track, in case there are multiple
return false;
}
}
return true;
// return false if any track has kind === 'description'
var out = !tracks.some(({ actualNode }) => (
(actualNode.getAttribute('kind') || '').toLowerCase() === 'descriptions'
));
axe.log(tracks.map(t => t.actualNode.getAttribute('kind')), out);
return out;
}
// Undefined if there are no tracks - media may be decorative
return undefined;
1 change: 1 addition & 0 deletions test/.jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"globals": {
"describe": true,
"it": true,
"xit": true,
"before": true,
"beforeEach": true,
"after": true,
Expand Down
31 changes: 21 additions & 10 deletions test/checks/media/caption.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,40 @@ describe('caption', function () {
'use strict';

var fixture = document.getElementById('fixture');
var shadowSupport = axe.testUtils.shadowSupport;
var checkSetup = axe.testUtils.checkSetup;

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

it('should return undefined if there is no track element', function () {
fixture.innerHTML = '<audio></audio>';
var node = fixture.querySelector('audio');

assert.isUndefined(checks.caption.evaluate(node));
var checkArgs = checkSetup('<audio></audio>', 'audio');
assert.isUndefined(checks.caption.evaluate.apply(null, checkArgs));
});

it('should fail if there is no kind=captions attribute', function () {
fixture.innerHTML = '<audio><track kind=descriptions></audio>';
var node = fixture.querySelector('audio');
var checkArgs = checkSetup('<audio><track kind=descriptions></audio>', 'audio');
assert.isTrue(checks.caption.evaluate.apply(null, checkArgs));
});

assert.isTrue(checks.caption.evaluate(node));
it('should fail if there is no kind attribute', function () {
var checkArgs = checkSetup('<video><track></video>', 'video');
assert.isTrue(checks.description.evaluate.apply(null, checkArgs));
});

it('should pass if there is a kind=captions attribute', function () {
fixture.innerHTML = '<audio><track kind=captions></audio>';
var node = fixture.querySelector('audio');
var checkArgs = checkSetup('<audio><track kind=captions></audio>', 'audio');
assert.isFalse(checks.caption.evaluate.apply(null, checkArgs));
});

(shadowSupport.v1 ? it : xit)('should get track from composed tree', function () {
var node = document.createElement('div');
node.innerHTML = '<track kind=descriptions>';
var shadow = node.attachShadow({ mode: 'open' });
shadow.innerHTML = '<audio><slot></slot></audio>';

assert.isFalse(checks.caption.evaluate(node));
var checkArgs = checkSetup(node, {}, 'audio');
assert.isTrue(checks.caption.evaluate.apply(null, checkArgs));
});
});
38 changes: 25 additions & 13 deletions test/checks/media/description.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
describe('description', function () {
'use strict';

var fixture = document.getElementById('fixture');
var shadowSupport = axe.testUtils.shadowSupport;
var checkSetup = axe.testUtils.checkSetup;

afterEach(function () {
fixture.innerHTML = '';
document.getElementById('fixture').innerHTML = '';
});

it('should return undefined if there is no track element', function () {
fixture.innerHTML = '<video></video>';
var node = fixture.querySelector('video');

assert.isUndefined(checks.description.evaluate(node));
var checkArgs = checkSetup('<video></video>', 'video');
assert.isUndefined(checks.description.evaluate.apply(null, checkArgs));
});

it('should fail if there is no kind=descriptions attribute', function () {
fixture.innerHTML = '<video><track kind=captions></video>';
var node = fixture.querySelector('video');
it('should fail if there is no kind=captions attribute', function () {
var checkArgs = checkSetup('<video><track kind=captions></video>', 'video');
assert.isTrue(checks.description.evaluate.apply(null, checkArgs));
});

assert.isTrue(checks.description.evaluate(node));
it('should fail if there is no kind attribute', function () {
var checkArgs = checkSetup('<video><track></video>', 'video');
assert.isTrue(checks.description.evaluate.apply(null, checkArgs));
});

it('should pass if there is a kind=descriptions attribute', function () {
fixture.innerHTML = '<video><track kind=descriptions></video>';
var node = fixture.querySelector('video');
var checkArgs = checkSetup('<video><track kind=descriptions></video>', 'video');
assert.isFalse(checks.description.evaluate.apply(null, checkArgs));
});

assert.isFalse(checks.description.evaluate(node));
(shadowSupport.v1 ? it : xit)('should get track from composed tree', function () {
var node = document.createElement('div');
node.innerHTML = '<track kind=descriptions>';
var shadow = node.attachShadow({ mode: 'open' });
shadow.innerHTML = '<video><slot></slot></video>';

var checkArgs = checkSetup(node, {}, 'video');
axe.log(checkArgs);
assert.isFalse(checks.description.evaluate.apply(null, checkArgs));
});

});
31 changes: 31 additions & 0 deletions test/testutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,35 @@ testUtils.shadowSupport = (function(document) {

})(document);

testUtils.fixtureSetup = function (content) {
'use strict';
var fixture = document.querySelector('#fixture');
if (typeof content === 'string') {
fixture.innerHTML = content;
} else if (content instanceof Node) {
fixture.appendChild(content);
}
axe._tree = axe.utils.getFlattenedTree(fixture);
return fixture;
};

/**
* Create check arguments
*
* @param Node|String Stuff to go into the fixture (html or node)
* @param Object Options argument for the check (optional, default: {})
* @param String Target for the check, CSS selector (default: '#target')
*/
testUtils.checkSetup = function (content, options, target) {
'use strict';
// Normalize the params
if (typeof options !== 'object') {
target = options;
options = {};
}
testUtils.fixtureSetup(content);
var node = axe.utils.querySelectorAll(axe._tree[0], target || '#target')[0];
return [node.actualNode, options, node];
};

axe.testUtils = testUtils;

0 comments on commit b7008e1

Please sign in to comment.