From 63e12725220db2bcaa70432d4baf80a5824b80a8 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Tue, 14 Nov 2017 13:32:47 +0100 Subject: [PATCH] fix: Several of fixes for IE and Edge (#577) * fix(IE): color-contrast was railing on elementsFromPoint * fix(IE): Properly test IE default button labels * fix(IE): Sort documentElement in elementsFromPoint pollyfill * fix(Edge): Give color tests enough time to scroll * fix(IE): Skip non-empty-if-present test --- lib/checks/shared/non-empty-if-present.js | 2 +- lib/commons/color/get-background-color.js | 2 +- lib/commons/text/index.js | 3 +- lib/core/utils/pollyfills.js | 7 ++++ test/checks/color/color-contrast.js | 46 +++++++++++++--------- test/checks/shared/non-empty-if-present.js | 7 +++- test/commons/text/accessible-text.js | 11 ++++-- 7 files changed, 50 insertions(+), 28 deletions(-) diff --git a/lib/checks/shared/non-empty-if-present.js b/lib/checks/shared/non-empty-if-present.js index ea9fd78bdc..7e51a539d9 100644 --- a/lib/checks/shared/non-empty-if-present.js +++ b/lib/checks/shared/non-empty-if-present.js @@ -5,7 +5,7 @@ let label = node.getAttribute('value'); this.data(label); -if (nodeName === 'INPUT' && ['submit', 'reset'].indexOf(type) !== -1) { +if (nodeName === 'INPUT' && ['submit', 'reset'].includes(type)) { return label === null; } return false; \ No newline at end of file diff --git a/lib/commons/color/get-background-color.js b/lib/commons/color/get-background-color.js index f439ebb634..e63140c085 100644 --- a/lib/commons/color/get-background-color.js +++ b/lib/commons/color/get-background-color.js @@ -203,7 +203,7 @@ color.getBackgroundStack = function(elm) { Math.ceil(rect.top + (rect.height / 2)), window.innerHeight - 1); - let elmStack = document.elementsFromPoint(x, y); + let elmStack = Array.from(document.elementsFromPoint(x, y)); elmStack = includeMissingElements(elmStack, elm); elmStack = dom.reduceToElementsBelowFloating(elmStack, elm); elmStack = sortPageBackground(elmStack); diff --git a/lib/commons/text/index.js b/lib/commons/text/index.js index b8e4b503f2..e29297d09c 100644 --- a/lib/commons/text/index.js +++ b/lib/commons/text/index.js @@ -5,5 +5,4 @@ * @namespace text * @memberof axe.commons */ - -var text = commons.text = {}; +var text = commons.text = { EdgeFormDefaults: {} }; diff --git a/lib/core/utils/pollyfills.js b/lib/core/utils/pollyfills.js index 9f63aa8f9e..d0d876f701 100644 --- a/lib/core/utils/pollyfills.js +++ b/lib/core/utils/pollyfills.js @@ -91,6 +91,13 @@ axe.utils.pollyfillElementsFromPoint = function () { current.style.setProperty(cssProp, cssDisableVal, 'important'); } + // Due to negative index, documentElement could actually not be the last, + // so we'll simply move it to the end + if (elements.indexOf(document.documentElement) < elements.length - 1) { + elements.splice(elements.indexOf(document.documentElement), 1); + elements.push(document.documentElement); + } + // restore the previous pointer-events values for (i = previousPointerEvents.length; !!(d = previousPointerEvents[--i]);) { elements[i].style.setProperty(cssProp, d.value ? d.value : '', d.priority); diff --git a/test/checks/color/color-contrast.js b/test/checks/color/color-contrast.js index faca6291bb..0e03b6e7b0 100644 --- a/test/checks/color/color-contrast.js +++ b/test/checks/color/color-contrast.js @@ -158,14 +158,18 @@ describe('color-contrast', function () { assert.equal(checkContext._data.contrastRatio, 0); }); - it('should return undefined when there are elements overlapping', function () { - fixture.innerHTML = '
' + - 'My text
'; - var target = fixture.querySelector('#target'); - var result = checks['color-contrast'].evaluate.call(checkContext, target); - assert.isUndefined(result); - assert.equal(checkContext._data.missingData, 'bgOverlap'); - assert.equal(checkContext._data.contrastRatio, 0); + it('should return undefined when there are elements overlapping', function (done) { + // Give Edge time to scroll... :/ + setTimeout(function () { + fixture.innerHTML = '
' + + 'My text
'; + var target = fixture.querySelector('#target'); + var result = checks['color-contrast'].evaluate.call(checkContext, target); + assert.isUndefined(result); + assert.equal(checkContext._data.missingData, 'bgOverlap'); + assert.equal(checkContext._data.contrastRatio, 0); + done(); + }, 10); }); it('should return true when a form wraps mixed content', function() { @@ -203,17 +207,21 @@ describe('color-contrast', function () { assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target)); assert.deepEqual(checkContext._relatedNodes, []); }); - - it('should return undefined if element overlaps text content', function () { - fixture.innerHTML = '
' + - '
Hi
' + - '
' + - '
'; - var target = fixture.querySelector('#target'); - var actual = checks['color-contrast'].evaluate.call(checkContext, target); - assert.isUndefined(actual); - assert.equal(checkContext._data.missingData, 'bgOverlap'); - assert.equal(checkContext._data.contrastRatio, 0); + + it('should return undefined if element overlaps text content', function (done) { + // Give Edge time to scroll + setTimeout(function () { + fixture.innerHTML = '
' + + '
Hi
' + + '
' + + '
'; + var target = fixture.querySelector('#target'); + var actual = checks['color-contrast'].evaluate.call(checkContext, target); + assert.isUndefined(actual); + assert.equal(checkContext._data.missingData, 'bgOverlap'); + assert.equal(checkContext._data.contrastRatio, 0); + done(); + }, 10); }); it('should return undefined if element has same color as background', function () { diff --git a/test/checks/shared/non-empty-if-present.js b/test/checks/shared/non-empty-if-present.js index b67906f777..a2a89ebc85 100644 --- a/test/checks/shared/non-empty-if-present.js +++ b/test/checks/shared/non-empty-if-present.js @@ -3,6 +3,11 @@ describe('non-empty-if-present', function () { var fixture = document.getElementById('fixture'); + // These defaults are only available in IE and Edge + var input = document.createElement('input'); + input.type = 'submit'; + var isEdgeOrIe = typeof input.getAttribute('value') === 'string'; + var checkContext = { _data: null, data: function (d) { @@ -24,7 +29,7 @@ describe('non-empty-if-present', function () { assert.isFalse(checks['non-empty-if-present'].evaluate.call(checkContext, node)); }); - it('should return true if a value is not present', function () { + (isEdgeOrIe ? xit : it)('should return true if a value is not present', function () { var node = document.createElement('input'); node.setAttribute('type', 'submit'); fixture.appendChild(node); diff --git a/test/commons/text/accessible-text.js b/test/commons/text/accessible-text.js index d69f7faa86..368c44914e 100644 --- a/test/commons/text/accessible-text.js +++ b/test/commons/text/accessible-text.js @@ -576,8 +576,9 @@ describe('text.accessibleTextVirtual', function() { axe._tree = axe.utils.getFlattenedTree(fixture); var target = axe.utils.querySelectorAll(axe._tree, 'input')[0]; + // IE inserts this for us, thanks! - assert.equal(axe.commons.text.accessibleTextVirtual(target), target.value || 'Submit'); + assert.equal(axe.commons.text.accessibleTextVirtual(target), target.actualNode.value || 'Submit'); }); it('should provide a default value for input type="reset"', function() { @@ -587,7 +588,9 @@ describe('text.accessibleTextVirtual', function() { var target = axe.utils.querySelectorAll(axe._tree, 'input')[0]; var defaultText = axe.commons.text.accessibleTextVirtual(target); assert.isString(defaultText); - assert.notEqual(defaultText.trim(), ''); + + // IE inserts this for us, thanks! + assert.equal(defaultText, target.actualNode.value || 'Reset'); }); it('should find title for input type=button', function() { @@ -604,7 +607,7 @@ describe('text.accessibleTextVirtual', function() { var target = axe.utils.querySelectorAll(axe._tree, 'input')[0]; // IE does not use title; but will use default value instead - assert.equal(axe.commons.text.accessibleTextVirtual(target), target.value || 'Hello'); + assert.equal(axe.commons.text.accessibleTextVirtual(target), target.actualNode.value || 'Hello'); }); it('should find title for input type=submit', function() { @@ -613,7 +616,7 @@ describe('text.accessibleTextVirtual', function() { var target = axe.utils.querySelectorAll(axe._tree, 'input')[0]; // Again, default value takes precedence over title - assert.equal(axe.commons.text.accessibleTextVirtual(target), target.value || 'Hello'); + assert.equal(axe.commons.text.accessibleTextVirtual(target), target.actualNode.value || 'Hello'); }); });