diff --git a/lib/core/utils/dq-element.js b/lib/core/utils/dq-element.js index 93498e91..373675e3 100644 --- a/lib/core/utils/dq-element.js +++ b/lib/core/utils/dq-element.js @@ -246,6 +246,9 @@ DqElement.prototype = { * @return {String} */ get selector() { + if (axe._cache.get('targetFormat') === 'ancestry') { + return this.spec.selector || [getAncestry(this.element)]; + } if (axe._cache.get('runTypeAOpt')) { return this.spec.selector || [generateSelectorWithShadow(this.element)]; } diff --git a/lib/core/utils/get-ancestry.js b/lib/core/utils/get-ancestry.js index b80edb93..7321a6da 100644 --- a/lib/core/utils/get-ancestry.js +++ b/lib/core/utils/get-ancestry.js @@ -13,8 +13,28 @@ function generateAncestry(node) { nodeName !== 'body' && parent.children.length > 1 ) { - const index = Array.prototype.indexOf.call(parent.children, node) + 1; - nthChild = `:nth-child(${index})`; + let index = 0; + if (parent.nodeName === 'BODY') { + let count = 0; + // Single pass over siblings: count valid children & locate node position. + for ( + let sib = parent.firstElementChild; + sib; + sib = sib.nextElementSibling + ) { + if (sib.hasAttribute('data-percy-injected')) { + continue; + } + count++; + if (sib === node) { + index = count; + } + } + nthChild = count > 1 ? `:nth-child(${index})` : ''; + } else { + index = Array.prototype.indexOf.call(parent.children, node) + 1; + nthChild = `:nth-child(${index})`; + } } return generateAncestry(parent) + ' > ' + nodeName + nthChild;