diff --git a/packages/driver/cypress/fixtures/shadow-dom.html b/packages/driver/cypress/fixtures/shadow-dom.html
index c75e753632f8..c4c1f240542c 100644
--- a/packages/driver/cypress/fixtures/shadow-dom.html
+++ b/packages/driver/cypress/fixtures/shadow-dom.html
@@ -3,7 +3,7 @@
Shadow DOM Fixture
-
+
Non Shadow
diff --git a/packages/driver/cypress/integration/commands/traversals_shadow_dom_spec.js b/packages/driver/cypress/integration/commands/traversals_shadow_dom_spec.js
index a8bfb9ca7397..d0e58307268a 100644
--- a/packages/driver/cypress/integration/commands/traversals_shadow_dom_spec.js
+++ b/packages/driver/cypress/integration/commands/traversals_shadow_dom_spec.js
@@ -266,15 +266,15 @@ describe('src/cy/commands/traversals - shadow dom', () => {
.then(($parents) => {
expect($parents.length).to.eq(10)
expect($parents[0]).to.have.class('shadow-div')
- expect($parents[1]).to.match('html')
- expect($parents[2]).to.match('body')
+ expect($parents[1]).to.have.id('shadow-element-3')
+ expect($parents[2]).to.have.id('parent-of-shadow-container-1')
expect($parents[3]).to.have.id('parent-of-shadow-container-0')
- expect($parents[4]).to.have.id('parent-of-shadow-container-1')
- expect($parents[5]).to.have.id('shadow-element-3')
- expect($parents[6]).to.have.class('shadow-div')
+ expect($parents[4]).to.have.class('shadow-div')
+ expect($parents[5]).to.have.id('shadow-element-8')
+ expect($parents[6]).to.have.id('parent-of-shadow-container-3')
expect($parents[7]).to.have.id('parent-of-shadow-container-2')
- expect($parents[8]).to.have.id('parent-of-shadow-container-3')
- expect($parents[9]).to.have.id('shadow-element-8')
+ expect($parents[8]).to.match('body')
+ expect($parents[9]).to.match('html')
})
})
})
@@ -321,9 +321,10 @@ describe('src/cy/commands/traversals - shadow dom', () => {
.find('p', { includeShadowDom: true })
.parents('.filter-me')
.then(($parents) => {
- expect($parents.length).to.eq(2)
+ expect($parents.length).to.eq(3)
expect($parents[0]).to.have.id('parent-of-shadow-container-1')
expect($parents[1]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[2]).to.match('body')
})
})
})
@@ -368,15 +369,15 @@ describe('src/cy/commands/traversals - shadow dom', () => {
.then(($parents) => {
expect($parents.length).to.eq(10)
expect($parents[0]).to.have.class('shadow-div')
- expect($parents[1]).to.match('html')
- expect($parents[2]).to.match('body')
+ expect($parents[1]).to.have.id('shadow-element-3')
+ expect($parents[2]).to.have.id('parent-of-shadow-container-1')
expect($parents[3]).to.have.id('parent-of-shadow-container-0')
- expect($parents[4]).to.have.id('parent-of-shadow-container-1')
- expect($parents[5]).to.have.id('shadow-element-3')
- expect($parents[6]).to.have.class('shadow-div')
+ expect($parents[4]).to.have.class('shadow-div')
+ expect($parents[5]).to.have.id('shadow-element-8')
+ expect($parents[6]).to.have.id('parent-of-shadow-container-3')
expect($parents[7]).to.have.id('parent-of-shadow-container-2')
- expect($parents[8]).to.have.id('parent-of-shadow-container-3')
- expect($parents[9]).to.have.id('shadow-element-8')
+ expect($parents[8]).to.match('body')
+ expect($parents[9]).to.match('html')
})
})
})
@@ -426,13 +427,13 @@ describe('src/cy/commands/traversals - shadow dom', () => {
.then(($parents) => {
expect($parents.length).to.eq(8)
expect($parents[0]).to.have.class('shadow-div')
- expect($parents[1]).to.have.id('parent-of-shadow-container-0')
+ expect($parents[1]).to.have.id('shadow-element-3')
expect($parents[2]).to.have.id('parent-of-shadow-container-1')
- expect($parents[3]).to.have.id('shadow-element-3')
+ expect($parents[3]).to.have.id('parent-of-shadow-container-0')
expect($parents[4]).to.have.class('shadow-div')
- expect($parents[5]).to.have.id('parent-of-shadow-container-2')
+ expect($parents[5]).to.have.id('shadow-element-8')
expect($parents[6]).to.have.id('parent-of-shadow-container-3')
- expect($parents[7]).to.have.id('shadow-element-8')
+ expect($parents[7]).to.have.id('parent-of-shadow-container-2')
})
})
})
@@ -455,9 +456,10 @@ describe('src/cy/commands/traversals - shadow dom', () => {
.find('.shadow-8-nested-3', { includeShadowDom: true })
.parentsUntil('#parent-of-shadow-container-0', '.filter-me')
.then(($parents) => {
- expect($parents.length).to.eq(2)
+ expect($parents.length).to.eq(3)
expect($parents[0]).to.have.class('shadow-8-nested-1')
expect($parents[1]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[2]).to.match('body')
})
})
@@ -475,11 +477,12 @@ describe('src/cy/commands/traversals - shadow dom', () => {
cy
.get('#shadow-element-3, #shadow-element-8')
.find('p', { includeShadowDom: true })
- .parentsUntil('body', '.filter-me')
+ .parentsUntil('html', '.filter-me')
.then(($parents) => {
- expect($parents.length).to.eq(2)
+ expect($parents.length).to.eq(3)
expect($parents[0]).to.have.id('parent-of-shadow-container-1')
expect($parents[1]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[2]).to.match('body')
})
})
})
@@ -536,17 +539,23 @@ describe('src/cy/commands/traversals - shadow dom', () => {
it('handles multiple elements in subject', () => {
cy
- .get('#shadow-element-8')
- .find('.shadow-div', { includeShadowDom: true })
+ .get('html')
.then(($untilEl) => {
cy
- .get('.shadow-8-nested-3, .shadow-8-nested-4', { includeShadowDom: true })
+ .get('#shadow-element-3, #shadow-element-8')
+ .find('p', { includeShadowDom: true })
.parentsUntil($untilEl[0])
.then(($parents) => {
- expect($parents.length).to.eq(3)
- expect($parents[0]).to.have.class('shadow-content')
- expect($parents[1]).to.have.class('shadow-8-nested-1')
- expect($parents[2]).to.have.class('shadow-8-nested-2')
+ expect($parents.length).to.eq(9)
+ expect($parents[0]).to.have.class('shadow-div')
+ expect($parents[1]).to.have.id('shadow-element-3')
+ expect($parents[2]).to.have.id('parent-of-shadow-container-1')
+ expect($parents[3]).to.have.id('parent-of-shadow-container-0')
+ expect($parents[4]).to.have.class('shadow-div')
+ expect($parents[5]).to.have.id('shadow-element-8')
+ expect($parents[6]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[7]).to.have.id('parent-of-shadow-container-2')
+ expect($parents[8]).to.match('body')
})
})
})
@@ -578,9 +587,10 @@ describe('src/cy/commands/traversals - shadow dom', () => {
.find('.shadow-8-nested-3', { includeShadowDom: true })
.parentsUntil($untilEl[0], '.filter-me')
.then(($parents) => {
- expect($parents.length).to.eq(2)
+ expect($parents.length).to.eq(3)
expect($parents[0]).to.have.class('shadow-8-nested-1')
expect($parents[1]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[2]).to.match('body')
})
})
})
@@ -601,15 +611,17 @@ describe('src/cy/commands/traversals - shadow dom', () => {
it('handles multiple elements in subject', () => {
cy
- .get('#shadow-element-8')
- .find('.shadow-div', { includeShadowDom: true })
+ .get('html')
.then(($untilEl) => {
cy
- .get('.shadow-8-nested-3, .shadow-8-nested-4', { includeShadowDom: true })
+ .get('#shadow-element-3, #shadow-element-8')
+ .find('p', { includeShadowDom: true })
.parentsUntil($untilEl[0], '.filter-me')
.then(($parents) => {
- expect($parents.length).to.eq(1)
- expect($parents[0]).to.have.class('shadow-8-nested-1')
+ expect($parents.length).to.eq(3)
+ expect($parents[0]).to.have.id('parent-of-shadow-container-1')
+ expect($parents[1]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[2]).to.match('body')
})
})
})
@@ -667,17 +679,23 @@ describe('src/cy/commands/traversals - shadow dom', () => {
it('handles multiple elements in subject', () => {
cy
- .get('#shadow-element-8')
- .find('.shadow-div', { includeShadowDom: true })
+ .get('html')
.then(($untilEl) => {
cy
- .get('.shadow-8-nested-3, .shadow-8-nested-4', { includeShadowDom: true })
+ .get('#shadow-element-3, #shadow-element-8')
+ .find('p', { includeShadowDom: true })
.parentsUntil($untilEl)
.then(($parents) => {
- expect($parents.length).to.eq(3)
- expect($parents[0]).to.have.class('shadow-content')
- expect($parents[1]).to.have.class('shadow-8-nested-1')
- expect($parents[2]).to.have.class('shadow-8-nested-2')
+ expect($parents.length).to.eq(9)
+ expect($parents[0]).to.have.class('shadow-div')
+ expect($parents[1]).to.have.id('shadow-element-3')
+ expect($parents[2]).to.have.id('parent-of-shadow-container-1')
+ expect($parents[3]).to.have.id('parent-of-shadow-container-0')
+ expect($parents[4]).to.have.class('shadow-div')
+ expect($parents[5]).to.have.id('shadow-element-8')
+ expect($parents[6]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[7]).to.have.id('parent-of-shadow-container-2')
+ expect($parents[8]).to.match('body')
})
})
})
@@ -709,9 +727,10 @@ describe('src/cy/commands/traversals - shadow dom', () => {
.find('.shadow-8-nested-3', { includeShadowDom: true })
.parentsUntil($untilEl, '.filter-me')
.then(($parents) => {
- expect($parents.length).to.eq(2)
+ expect($parents.length).to.eq(3)
expect($parents[0]).to.have.class('shadow-8-nested-1')
expect($parents[1]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[2]).to.match('body')
})
})
})
@@ -732,15 +751,17 @@ describe('src/cy/commands/traversals - shadow dom', () => {
it('handles multiple elements in subject', () => {
cy
- .get('#shadow-element-8')
- .find('.shadow-div', { includeShadowDom: true })
+ .get('html')
.then(($untilEl) => {
cy
- .get('.shadow-8-nested-3, .shadow-8-nested-4', { includeShadowDom: true })
+ .get('#shadow-element-3, #shadow-element-8')
+ .find('p', { includeShadowDom: true })
.parentsUntil($untilEl, '.filter-me')
.then(($parents) => {
- expect($parents.length).to.eq(1)
- expect($parents[0]).to.have.class('shadow-8-nested-1')
+ expect($parents.length).to.eq(3)
+ expect($parents[0]).to.have.id('parent-of-shadow-container-1')
+ expect($parents[1]).to.have.id('parent-of-shadow-container-3')
+ expect($parents[2]).to.match('body')
})
})
})
diff --git a/packages/driver/src/cy/commands/traversals.js b/packages/driver/src/cy/commands/traversals.js
index cdbe60396b7a..82e7145d4085 100644
--- a/packages/driver/src/cy/commands/traversals.js
+++ b/packages/driver/src/cy/commands/traversals.js
@@ -1,4 +1,3 @@
-const $ = require('jquery')
const _ = require('lodash')
const $dom = require('../../dom')
@@ -20,6 +19,14 @@ const optInShadowTraversals = {
},
}
+const sortedUnique = (cy, $el) => {
+ // we want _.uniq() to keep the elements with higher indexes instead of lower
+ // so we reverse, uniq, then reverse again
+ // so [div1, body, html, div2, body, html]
+ // becomes [div1, div2, body, html] and not [div1, body, html, div2]
+ return cy.$$(_($el).reverse().uniq().reverse().value())
+}
+
const autoShadowTraversals = {
closest: (cy, $el, selector) => {
const nodes = _.reduce($el, (nodes, el) => {
@@ -38,14 +45,14 @@ const autoShadowTraversals = {
return getClosest(el)
}, [])
- return $.uniqueSort(nodes)
+ return sortedUnique(cy, nodes)
},
parent: (cy, $el) => {
const parents = $el.map((i, el) => {
return $elements.getParent(el)
})
- return $.uniqueSort(parents)
+ return sortedUnique(cy, parents)
},
parents: (cy, $el, selector) => {
let $parents = $el.map((i, el) => {
@@ -53,7 +60,7 @@ const autoShadowTraversals = {
})
if ($el.length > 1) {
- $parents = $.uniqueSort($parents)
+ $parents = sortedUnique(cy, $parents)
}
if (!selector) {
@@ -68,7 +75,7 @@ const autoShadowTraversals = {
})
if ($el.length > 1) {
- $parents = $.uniqueSort($parents)
+ $parents = sortedUnique(cy, $parents)
}
if (!filter) {