UNPKG

axe-core

Version:

Accessibility engine for automated Web UI testing

392 lines (330 loc) • 18 kB
describe('color-contrast-matches', function () { 'use strict'; var fixture = document.getElementById('fixture'); var shadowSupport = document.body && typeof document.body.attachShadow === 'function'; var rule; beforeEach(function () { rule = axe._audit.rules.find(function (rule) { return rule.id === 'color-contrast'; }); }); afterEach(function () { fixture.innerHTML = ''; axe._tree = undefined; }); it('is a function', function () { assert.isFunction(rule.matches); }); it('should not match when there is no text', function () { fixture.innerHTML = '<div style="color: yellow; background-color: white;" id="target">' + ' </div>'; var target = fixture.querySelector('#target'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should match when there is text', function () { fixture.innerHTML = '<div style="color: yellow; background-color: white;" id="target">' + 'My text</div>'; var target = fixture.querySelector('#target'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match when there is text that is out of the container', function () { fixture.innerHTML = '<div style="color: yellow; text-indent: -9999px; background-color: white;" id="target">' + 'My text</div>'; var target = fixture.querySelector('#target'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match when there is text that is out of the container with overflow hidden', function () { fixture.innerHTML = '<div style="color: yellow; width: 100px; overflow: hidden; text-indent: 200px; background-color: white;" id="target">' + 'text</div>'; var target = fixture.querySelector('#target'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should match when there is text that is in the scroll reach of container', function () { fixture.innerHTML = '<div style="color: yellow; width: 100px; overflow: scroll; text-indent: 200px; background-color: white;" id="target">' + 'text</div>'; var target = fixture.querySelector('#target'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should match when there is text that is only partially out of the container', function () { fixture.innerHTML = '<div style="color: yellow; text-indent: -20px; background-color: white;" id="target">' + 'My text</div>'; var target = fixture.querySelector('#target'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should match <input type="text">', function () { fixture.innerHTML = '<input type="text">'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <input type="hidden">', function () { fixture.innerHTML = '<input type="hidden">'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <input type="checkbox">', function () { fixture.innerHTML = '<input type="checkbox">'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <input type="radio">', function () { fixture.innerHTML = '<input type="radio">'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <input type="color">', function () { fixture.innerHTML = '<input type="color">'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); // Some browsers will fallback to type=text for unknown input types (looking at you IE) if (target.type === 'color') { assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); } }); it('should not match <input type="range">', function () { fixture.innerHTML = '<input type="range">'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); // Some browsers will fallback to type=text for unknown input types (looking at you IE) if (target.type === 'range') { assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); } }); it('should match <select> with options', function () { fixture.innerHTML = '<select><option>Hello</option></select>'; var target = fixture.querySelector('select'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <select> with no options', function () { fixture.innerHTML = '<select></select>'; var target = fixture.querySelector('select'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should match <textarea>', function () { fixture.innerHTML = '<textarea></textarea>'; var target = fixture.querySelector('textarea'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <option>', function () { fixture.innerHTML = '<select><option>hi</option></select>'; var target = fixture.querySelector('option'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match inputs that are disabled', function () { fixture.innerHTML = '<input type="text" disabled>'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a disabled implicit label child', function () { fixture.innerHTML = '<label>' + '<input type="checkbox" style="position: absolute;display: inline-block;width: 1.5rem;height: 1.5rem;opacity: 0;" disabled checked>' + '<span style="background-color:rgba(0, 0, 0, 0.26);display:inline-block;width: 1.5rem;height: 1.5rem;" aria-hidden="true"></span>' + '<span style="color:rgba(0, 0, 0, 0.38);" id="target">Baseball</span>' + '</label>'; var target = fixture.querySelector('#target'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); var result = rule.matches(target, axe.utils.getNodeFromTree(tree[0], target)); assert.isFalse(result); }); it('should not match <textarea disabled>', function () { fixture.innerHTML = '<textarea disabled></textarea>'; var target = fixture.querySelector('textarea'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <select> with options', function () { fixture.innerHTML = '<select disabled><option>Hello</option></select>'; var target = fixture.querySelector('select'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should match <button>', function () { fixture.innerHTML = '<button>hi</button>'; var target = fixture.querySelector('button'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <button disabled>', function () { fixture.innerHTML = '<button disabled>hi</button>'; var target = fixture.querySelector('button'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match <button disabled><span></span></button>', function () { fixture.innerHTML = '<button disabled><span>Hi</span></button>'; var target = fixture.querySelector('button'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target.querySelector('span'), axe.utils.getNodeFromTree(tree[0], target.querySelector('span')))); }); it('should not match <button disabled><span><i></i></span></button>', function () { fixture.innerHTML = '<button disabled><span><i>Hi</i></span></button>'; var target = fixture.querySelector('button'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target.querySelector('i'), axe.utils.getNodeFromTree(tree[0], target.querySelector('i')))); }); it('should not match <input type=image>', function () { fixture.innerHTML = '<input type="image">'; var target = fixture.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a disabled input\'s label - explicit label', function () { fixture.innerHTML = '<label for="t1">Test</label><input type="text" id="t1" disabled>'; var target = fixture.querySelector('label'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a disabled input\'s label - implicit label (input)', function () { fixture.innerHTML = '<label>Test<input type="text" disabled></label>'; var target = fixture.querySelector('label'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a disabled input\'s label - implicit label (textarea)', function () { fixture.innerHTML = '<label>Test<textarea disabled>Hi</textarea></label>'; var target = fixture.querySelector('label'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a disabled input\'s label - implicit label (select)', function () { fixture.innerHTML = '<label>Test<select disabled><option>Test</option></select></label>'; var target = fixture.querySelector('label'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a disabled input\'s label - aria-labelledby', function () { fixture.innerHTML = '<div id="t1">Test</div><input type="text" aria-labelledby="bob t1 fred" disabled>'; var target = fixture.querySelector('div'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match aria-disabled=true', function () { fixture.innerHTML = '<div aria-disabled="true">hi</div>'; var target = fixture.querySelector('div'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a descendant of aria-disabled=true', function () { fixture.innerHTML = '<div aria-disabled="true"><span>hi</span></div>'; var target = fixture.querySelector('span'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a descendant of a disabled fieldset', function () { fixture.innerHTML = '<fieldset disabled><label>hi <input type="checkbox"></label></fieldset>'; var target = fixture.querySelector('label'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a descendant of an explicit label for a disabled input', function () { fixture.innerHTML = '<input id="input" type="checkbox" disabled><label for="input"><span>hi</span></label>'; var target = fixture.querySelector('span'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); it('should not match a descendant of an implicit label for a disabled input', function () { fixture.innerHTML = '<label for="input"><span>hi</span><input id="input" type="checkbox" disabled></label>'; var target = fixture.querySelector('span'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(tree[0], target))); }); if (shadowSupport) { it('should match a descendant of an element across a shadow boundary', function () { fixture.innerHTML = '<div id="parent" style="background-color: #000;">' + '</div>'; var shadowRoot = document.getElementById('parent').attachShadow({ mode: 'open' }); shadowRoot.innerHTML = '<div id="shadowTarget" style="color: #333">Text</div>'; var shadowTarget = fixture.firstChild.shadowRoot.querySelector('#shadowTarget'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(shadowTarget, axe.utils.getNodeFromTree(tree[0], shadowTarget))); }); it('should look at the correct root node when looking up an explicit label and disabled input', function () { fixture.innerHTML = '<div id="parent">'+ '<input id="input">' + '</div>'; var shadowRoot = document.getElementById('parent').attachShadow({ mode: 'open' }); shadowRoot.innerHTML = '<div id="shadowParent">' + '<label for="input" id="shadowLabel">Label</label>' + '<input id="input" disabled>' + '</div>'; var shadowLabel = fixture.firstChild.shadowRoot.querySelector('#shadowLabel'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(shadowLabel, axe.utils.getNodeFromTree(tree[0], shadowLabel))); }); it('should look at the correct root node when looking up implicit label and disabled input', function () { fixture.innerHTML = '<div id="parent">'+ '<input>' + '</div>'; var shadowRoot = document.getElementById('parent').attachShadow({ mode: 'open' }); shadowRoot.innerHTML = '<div id="shadowParent">' + '<label id="shadowLabel">Label <input disabled></label>' + '</div>'; var shadowLabel = fixture.firstChild.shadowRoot.querySelector('#shadowLabel'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(shadowLabel, axe.utils.getNodeFromTree(tree[0], shadowLabel))); }); it('should look at the correct root node for a disabled control\'s label associated w/ aria-labelledby', function () { fixture.innerHTML = '<div id="parent">'+ '<input id="input">' + '</div>'; var shadowRoot = document.getElementById('parent').attachShadow({ mode: 'open' }); shadowRoot.innerHTML = '<div id="shadowParent">' + '<label id="shadowLabel">Label</label>' + '<input aria-labelledby="shadowLabel" disabled>' + '</div>'; var shadowLabel = fixture.firstChild.shadowRoot.querySelector('#shadowLabel'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(shadowLabel, axe.utils.getNodeFromTree(tree[0], shadowLabel))); }); it('should handle input/label spread across the shadow boundary', function () { fixture.innerHTML = '<label>Text <div id="firstChild"></div></label>'; var container = document.getElementById('firstChild'); var shadowRoot = container.attachShadow({ mode: 'open' }); shadowRoot.innerHTML = '<input type="text" id="input" disabled />'; var shadowTarget = container.shadowRoot.querySelector('#input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isFalse(rule.matches(shadowTarget, axe.utils.getNodeFromTree(tree[0], shadowTarget))); }); it('should look at the children of a virtual node for overlap', function () { fixture.innerHTML = '<div id="parent">'+ '<div id="firstChild" style="background-color: #ccc; color: #fff;"></div>' + '</div>'; var shadowRoot = document.getElementById('firstChild').attachShadow({ mode: 'open' }); shadowRoot.innerHTML = 'Some text' + '<p style="color: #fff;" id="shadowTarget">Other text</p>'; var firstChild = fixture.querySelector('#firstChild'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(firstChild, axe.utils.getNodeFromTree(tree[0], firstChild))); }); it('should handle an input added through slotted content', function () { fixture.innerHTML = '<label>Option 1 <span class="slotted">' + '<input type="text" name="slottedLabel" />' + '</span></label>'; function createContentSlotted() { var group = document.createElement('span'); group.innerHTML = '<slot></slot>'; return group; } var slotted = fixture.querySelector('.slotted'); var shadowRoot = slotted.attachShadow({mode: 'open'}); shadowRoot.appendChild(createContentSlotted()); var input = slotted.querySelector('input'); var tree = axe._tree = axe.utils.getFlattenedTree(fixture); assert.isTrue(rule.matches(input, axe.utils.getNodeFromTree(tree[0], input))); }); } });