From fb2a30647c8de5fff42c22feb0b58fabe98bf6e0 Mon Sep 17 00:00:00 2001 From: Dylan Barrell Date: Tue, 4 Jul 2017 13:28:04 -0400 Subject: [PATCH] Correct flattened tree algorithm to include the shadow host in the flattened tree --- lib/core/utils/flattened-tree.js | 4 +++- test/core/utils/contains.js | 2 +- test/core/utils/flattened-tree.js | 33 ++++++++++++++++++------------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/core/utils/flattened-tree.js b/lib/core/utils/flattened-tree.js index 010da0fc66..8d7aabb38a 100644 --- a/lib/core/utils/flattened-tree.js +++ b/lib/core/utils/flattened-tree.js @@ -80,9 +80,11 @@ axe.utils.getFlattenedTree = function (node, shadowId) { if (node.shadowRoot && nodeName !== 'marquee') { // generate an ID for this shadow root and overwrite the current // closure shadowId with this value so that it cascades down the tree + retVal = virtualDOMfromNode(node, shadowId); shadowId = 'a' + Math.random().toString().substring(2); realArray = Array.from(node.shadowRoot.childNodes); - return realArray.reduce(reduceShadowDOM, []); + retVal.children = realArray.reduce(reduceShadowDOM, []); + return [retVal]; } else { if (nodeName === 'content') { realArray = Array.from(node.getDistributedNodes()); diff --git a/test/core/utils/contains.js b/test/core/utils/contains.js index 24e7f848d2..c82cd24638 100644 --- a/test/core/utils/contains.js +++ b/test/core/utils/contains.js @@ -104,7 +104,7 @@ describe('axe.utils.contains', function () { if (document.body && typeof document.body.attachShadow === 'function') { fixture.innerHTML = '
'; makeShadowTree(fixture.firstChild); - tree = axe.utils.getFlattenedTree(fixture.firstChild); + tree = axe.utils.getFlattenedTree(fixture.firstChild)[0].children; node1 = axe.utils.querySelectorAll(tree, '#target')[0]; node2 = axe.utils.querySelectorAll(tree, 'a')[0]; assert.isTrue(axe.utils.contains(node1, node2)); diff --git a/test/core/utils/flattened-tree.js b/test/core/utils/flattened-tree.js index c8c5acfac0..0ebba613d3 100644 --- a/test/core/utils/flattened-tree.js +++ b/test/core/utils/flattened-tree.js @@ -14,6 +14,10 @@ function flattenedTreeAssertions () { 'use strict'; var virtualDOM = axe.utils.getFlattenedTree(fixture.firstChild); + assert.equal(virtualDOM.length, 1); // host + assert.equal(virtualDOM[0].actualNode.nodeName, 'DIV'); + + virtualDOM = virtualDOM[0].children; assert.equal(virtualDOM.length, 3); assert.equal(virtualDOM[0].actualNode.nodeName, 'STYLE'); @@ -44,19 +48,20 @@ function shadowIdAssertions () { 'use strict'; var virtualDOM = axe.utils.getFlattenedTree(fixture); - assert.isUndefined(virtualDOM[0].shadowId); - assert.isDefined(virtualDOM[0].children[0].shadowId); - assert.isDefined(virtualDOM[0].children[1].shadowId); - assert.isDefined(virtualDOM[0].children[4].shadowId); + assert.isUndefined(virtualDOM[0].shadowId); //fixture + assert.isUndefined(virtualDOM[0].children[0].shadowId); //host + assert.isDefined(virtualDOM[0].children[0].children[0].shadowId); + assert.isDefined(virtualDOM[0].children[0].children[1].shadowId); + assert.isDefined(virtualDOM[0].children[1].children[0].shadowId); // shadow IDs in the same shadowRoot must be the same - assert.equal(virtualDOM[0].children[0].shadowId, - virtualDOM[0].children[1].shadowId); + assert.equal(virtualDOM[0].children[0].children[0].shadowId, + virtualDOM[0].children[0].children[1].shadowId); // should cascade - assert.equal(virtualDOM[0].children[1].shadowId, - virtualDOM[0].children[1].children[0].shadowId); + assert.equal(virtualDOM[0].children[0].children[1].shadowId, + virtualDOM[0].children[0].children[1].children[0].shadowId); // shadow IDs in different shadowRoots must be different - assert.notEqual(virtualDOM[0].children[0].shadowId, - virtualDOM[0].children[4].shadowId); + assert.notEqual(virtualDOM[0].children[0].children[0].shadowId, + virtualDOM[0].children[1].children[0].shadowId); } @@ -143,10 +148,10 @@ if (document.body && typeof document.body.attachShadow === 'function') { it('getFlattenedTree\'s virtual DOM should give an ID to the shadow DOM', shadowIdAssertions); it('getFlattenedTree\'s virtual DOM should have the fallback content', function () { var virtualDOM = axe.utils.getFlattenedTree(fixture); - assert.isTrue(virtualDOM[0].children[7].children[0].children.length === 2); - assert.isTrue(virtualDOM[0].children[7].children[0].children[0].actualNode.nodeType === 3); - assert.isTrue(virtualDOM[0].children[7].children[0].children[0].actualNode.textContent === 'fallback content'); - assert.isTrue(virtualDOM[0].children[7].children[0].children[1].actualNode.nodeName === 'LI'); + assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children.length === 2); + assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[0].actualNode.nodeType === 3); + assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[0].actualNode.textContent === 'fallback content'); + assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[1].actualNode.nodeName === 'LI'); }); }); describe('flattened-tree shadow DOM v1: boxed slots', function () {