@revoloo/cypress6
Version:
Cypress.io end to end testing tool
641 lines (549 loc) • 32.3 kB
text/typescript
export {} // make typescript see this as a module
const { $ } = Cypress
describe('src/cypress/dom/visibility - shadow dom', () => {
let add
beforeEach(() => {
cy.visit('/fixtures/empty.html').then((win) => {
win.customElements.define('shadow-root', class extends win.HTMLElement {
constructor () {
super()
// @ts-ignore
this.attachShadow({ mode: 'open' })
this.style.display = 'block'
}
})
add = (el, shadowEl, rootIdentifier) => {
const $el = $(el).appendTo(cy.$$('body'))
// @ts-ignore
$(shadowEl).appendTo(cy.$$(rootIdentifier)[0].shadowRoot)
return $el
}
// ensure all tests run against a scrollable window
const scrollThisIntoView = $(`<div style='height: 1000px; width: 10px;' /><div>Should be in view</div>`).appendTo(cy.$$('body'))
// scroll the 2nd element into view so that
// there is always a scrollTop so we ensure
// its factored in (window vs viewport) calculations
scrollThisIntoView.get(1).scrollIntoView()
})
})
describe('css visibility', () => {
it('is hidden if parent is shadow root and has .css(visibility) hidden', () => {
const $shadowRootVisHidden = add(
`<shadow-root id="shadow-root-vis-hidden" style="visibility: hidden;"></shadow-root>`,
`<button>parent visibility: hidden</button>`,
'#shadow-root-vis-hidden',
)
cy.wrap($shadowRootVisHidden).find('button', { includeShadowDom: true }).should('be.hidden')
cy.wrap($shadowRootVisHidden).find('button', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden if parent outside of shadow dom has .css(visibility) hidden', () => {
const $outsideParentVisHidden = add(
`<div style="visibility: hidden;">
<shadow-root id="outside-parent-vis-hidden"></shadow-root>
</div>`,
`<button>parent visibility: hidden</button>`,
'#outside-parent-vis-hidden',
)
cy.wrap($outsideParentVisHidden).find('button', { includeShadowDom: true }).should('be.hidden')
cy.wrap($outsideParentVisHidden).find('button', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden if parent outside of shadow dom has visibility collapse', () => {
const $outsideParentVisCollapse = add(
`<table>
<tr>
<td>Naruto</td>
<td style='visibility: collapse;'><shadow-root id="outside-parent-vis-collapse"></shadow-root></td>
<td>Sakura</td>
</tr>
</table>`,
`<span id='collapse-span'>Sasuke</span>`,
'#outside-parent-vis-collapse',
)
cy.wrap($outsideParentVisCollapse).find('#collapse-span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($outsideParentVisCollapse).find('#collapse-span', { includeShadowDom: true }).should('not.be.visible')
})
})
describe('width and height', () => {
it('is hidden if parent is shadow root and has overflow: hidden and no width', () => {
const $shadowRootNoWidth = add(
`<shadow-root id="shadow-root-no-width" style='width: 0; height: 100px; overflow: hidden;'></shadow-root>`,
`<div style='height: 500px; width: 500px;'>
<span>parent width: 0</span>
</div>`,
'#shadow-root-no-width',
)
cy.wrap($shadowRootNoWidth).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($shadowRootNoWidth).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden if parent outside of shadow dom has overflow: hidden and no width', () => {
const $outsideParentNoWidth = add(
`<div style='width: 0; height: 100px; overflow: hidden;'>
<shadow-root id="outside-parent-no-width"></shadow-root>
</div>`,
`<div style='height: 500px; width: 500px;'>
<span>parent width: 0</span>
</div>`,
'#outside-parent-no-width',
)
cy.wrap($outsideParentNoWidth).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($outsideParentNoWidth).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden if parent is shadow root and has overflow: hidden and no height', () => {
const $shadowRootNoHeight = add(
`<shadow-root id="shadow-root-no-height" style='width: 100px; height: 0; overflow: hidden;'></shadow-root>`,
`<div style='height: 500px; width: 500px;'>
<span>parent height: 0</span>
</div>`,
'#shadow-root-no-height',
)
cy.wrap($shadowRootNoHeight).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($shadowRootNoHeight).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden if parent outside of shadow dom has overflow: hidden and no height', () => {
const $outsideParentNoHeight = add(
`<div style='width: 100px; height: 0; overflow: hidden;'>
<shadow-root id="outside-parent-no-height"></shadow-root>
</div>`,
`<div style='height: 500px; width: 500px;'>
<span>parent height: 0</span>
</div>`,
'#outside-parent-no-height',
)
cy.wrap($outsideParentNoHeight).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($outsideParentNoHeight).find('span', { includeShadowDom: true }).should('not.be.visible')
})
})
describe('css position', () => {
it('is visible if child has position: absolute', () => {
const $childPosAbs = add(
`<div style='width: 0; height: 100px; overflow: hidden;'>
<shadow-root id="child-pos-absolute"></shadow-root>
</div>`,
`<div style='height: 500px; width: 500px;'>
<span style="position: absolute;">position: absolute</span>
</div>`,
'#child-pos-absolute',
)
cy.wrap($childPosAbs).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($childPosAbs).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible if child has position: fixed', () => {
const $childPosFixed = add(
`<div style='width: 0; height: 100px; overflow: hidden;'>
<shadow-root id="child-pos-fixed"></shadow-root>
</div>`,
`<div style='height: 500px; width: 500px;'>
<button style="position: fixed; top: 0;">position: fixed</button>
</div>`,
'#child-pos-fixed',
)
cy.wrap($childPosFixed).find('button', { includeShadowDom: true }).should('be.visible')
cy.wrap($childPosFixed).find('button', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible if descendent from parent has position: absolute and descendent is outside shadow dom', () => {
const $descendentPosAbsOutside = add(
`<div style='width: 0; height: 100px; overflow: hidden;'>
<div style='height: 500px; width: 500px; position: absolute;'>
<shadow-root id="descendent-pos-abs-outside"></shadow-root>
</div>
</div>`,
`<span>no width, descendant position: absolute</span>`,
'#descendent-pos-abs-outside',
)
cy.wrap($descendentPosAbsOutside).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($descendentPosAbsOutside).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible if descendent from parent has position: absolute and descendent is inside shadow dom', () => {
const $descendentPosAbsInside = add(
`<div style='width: 0; height: 100px; overflow: hidden;'>
<shadow-root id="descendent-pos-abs-inside"></shadow-root>
</div>`,
`<div style='height: 500px; width: 500px; position: absolute;'>
<span>no width, descendant position: absolute</span>
</div>`,
'#descendent-pos-abs-inside',
)
cy.wrap($descendentPosAbsInside).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($descendentPosAbsInside).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible if descendent from parent has position: fixed and descendent is outside shadow dom', () => {
const $descendentPosFixedOutside = add(
`<div style='width: 0; height: 100px; overflow: hidden;'>
<div style='height: 500px; width: 500px; position: fixed; top: 0; right: 0;'>
<shadow-root id="descendent-pos-fixed-outside"></shadow-root>
</div>
</div>`,
`<button>no width, descendant position: fixed</button>`,
'#descendent-pos-fixed-outside',
)
cy.wrap($descendentPosFixedOutside).find('button', { includeShadowDom: true }).should('be.visible')
cy.wrap($descendentPosFixedOutside).find('button', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible if descendent from parent has position: fixed and descendent is inside shadow dom', () => {
const $descendentPosFixedInside = add(
`<div style='width: 0; height: 100px; overflow: hidden;'>
<shadow-root id="descendent-pos-fixed-inside"></shadow-root>
</div>`,
`<div style='height: 500px; width: 500px; position: fixed; top: 100px; right: 0;'>
<button>no width, descendant position: fixed</button>
</div>`,
'#descendent-pos-fixed-inside',
)
cy.wrap($descendentPosFixedInside).find('button', { includeShadowDom: true }).should('be.visible')
cy.wrap($descendentPosFixedInside).find('button', { includeShadowDom: true }).should('not.be.hidden')
})
it('is hidden if position: fixed and covered by element outside of shadow dom', () => {
const $coveredUpByOutsidePosFixed = add(
`<div>
<shadow-root id="covered-up-by-outside-pos-fixed"></shadow-root>
<div style="position: fixed; bottom: 0; left: 0">on top</div>
</div>`,
`<div id="inside-underneath" style="position: fixed; bottom: 0; left: 0">underneath</div>`,
'#covered-up-by-outside-pos-fixed',
)
cy.wrap($coveredUpByOutsidePosFixed).find('#inside-underneath', { includeShadowDom: true }).should('be.hidden')
cy.wrap($coveredUpByOutsidePosFixed).find('#inside-underneath', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden if outside of shadow dom with position: fixed and covered by element inside of shadow dom', () => {
const $coveredUpByShadowPosFixed = add(
`<div>
<div id="outside-underneath" style="position: fixed; bottom: 0; left: 0">underneath</div>
<shadow-root id="covered-up-by-shadow-pos-fixed"></shadow-root>
</div>`,
`<div style="position: fixed; bottom: 0; left: 0">on top</div>`,
'#covered-up-by-shadow-pos-fixed',
)
cy.wrap($coveredUpByShadowPosFixed).find('#outside-underneath', { includeShadowDom: true }).should('be.hidden')
cy.wrap($coveredUpByShadowPosFixed).find('#outside-underneath', { includeShadowDom: true }).should('not.be.visible')
})
it('is visible if position: fixed and parent outside shadow dom has pointer-events: none', () => {
const $parentPointerEventsNone = add(
`<div style="pointer-events: none;">
<shadow-root id="parent-pointer-events-none"></shadow-root>
</div>`,
`<span style="position: fixed; top: 20px;">parent pointer-events: none</span>`,
'#parent-pointer-events-none',
)
cy.wrap($parentPointerEventsNone).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($parentPointerEventsNone).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is hidden if covered when position: fixed and parent outside shadow dom has pointer-events: none', () => {
const $parentPointerEventsNoneCovered = add(
`<div style="pointer-events: none;">
<shadow-root id="parent-pointer-events-none-covered"></shadow-root>
</div>
<span style="position: fixed; top: 40px; background: red;">covering the element with pointer-events: none</span>`,
`<span style="position: fixed; top: 40px;">parent pointer-events: none</span>`,
'#parent-pointer-events-none-covered',
)
cy.wrap($parentPointerEventsNoneCovered).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($parentPointerEventsNoneCovered).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is visible if pointer-events: none and parent outside shadow dom has position: fixed', () => {
const $childPointerEventsNone = add(
`<div style="position: fixed; top: 60px;">
<shadow-root id="child-pointer-events-none-covered"></shadow-root>
</div>`,
`<span style="pointer-events: none;">child pointer-events: none</span>`,
'#child-pointer-events-none-covered',
)
cy.wrap($childPointerEventsNone).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($childPointerEventsNone).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
})
describe('css overflow', () => {
it('is hidden when parent outside of shadow dom overflow hidden and out of bounds to left', () => {
const $elOutOfParentBoundsToLeft = add(
`<div style='width: 100px; height: 100px; overflow: hidden; position: relative;'>
<shadow-root id="el-out-of-parent-bounds-to-left"></shadow-root>
</div>`,
`<span style='position: absolute; left: -400px; top: 0;'>position: absolute, out of bounds left</span>`,
'#el-out-of-parent-bounds-to-left',
)
cy.wrap($elOutOfParentBoundsToLeft).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfParentBoundsToLeft).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent outside of shadow dom overflow hidden and out of bounds to right', () => {
const $elOutOfParentBoundsToRight = add(
`<div style='width: 100px; height: 100px; overflow: hidden; position: relative;'>
<shadow-root id="el-out-of-parent-bounds-to-right"></shadow-root>
</div>`,
`<span style='position: absolute; left: 200px; top: 0;'>position: absolute, out of bounds right</span>`,
'#el-out-of-parent-bounds-to-right',
)
cy.wrap($elOutOfParentBoundsToRight).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfParentBoundsToRight).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent outside of shadow dom overflow hidden and out of bounds above', () => {
const $elOutOfParentBoundsAbove = add(
`<div style='width: 100px; height: 100px; overflow: hidden; position: relative;'>
<shadow-root id="el-out-of-parent-bounds-above"></shadow-root>
</div>`,
`<span style='position: absolute; top: -100px; left: 0;'>position: absolute, out of bounds above</span>`,
'#el-out-of-parent-bounds-above',
)
cy.wrap($elOutOfParentBoundsAbove).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfParentBoundsAbove).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent outside of shadow dom overflow hidden and out of bounds below', () => {
const $elOutOfParentBoundsBelow = add(
`<div style='width: 100px; height: 100px; overflow: hidden; position: relative;'>
<shadow-root id="el-out-of-parent-bounds-below"></shadow-root>
</div>`,
`<span style='position: absolute; top: 200px; left: 0;'>position: absolute, out of bounds below</span>`,
'#el-out-of-parent-bounds-below',
)
cy.wrap($elOutOfParentBoundsBelow).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfParentBoundsBelow).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent outside of shadow dom overflow hidden-y and out of bounds', () => {
const $elOutOfParentWithOverflowYHiddenBounds = add(
`<div style='width: 100px; height: 100px; overflow-y: hidden; position: relative;'>
<shadow-root id="el-out-of-parent-with-overflow-y-hidden-bounds"></shadow-root>
</div>`,
`<span style='position: absolute; top: 200px; left: 0;'>position: absolute, out of bounds below</span>`,
'#el-out-of-parent-with-overflow-y-hidden-bounds',
)
cy.wrap($elOutOfParentWithOverflowYHiddenBounds).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfParentWithOverflowYHiddenBounds).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent outside of shadow dom overflow hidden-x and out of bounds', () => {
const $elOutOfParentWithOverflowXHiddenBounds = add(
`<div style='width: 100px; height: 100px; overflow-x: hidden; position: relative;'>
<shadow-root id="el-out-of-parent-with-overflow-x-hidden-bounds"></shadow-root>
</div>`,
`<span style='position: absolute; top: 0; left: 200px;'>position: absolute, out of bounds below</span>`,
'#el-out-of-parent-with-overflow-x-hidden-bounds',
)
cy.wrap($elOutOfParentWithOverflowXHiddenBounds).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfParentWithOverflowXHiddenBounds).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is visible when parent overflow hidden but el in a closer parent outside of shadow dom with position absolute', () => {
const $elOutOfParentWithOverflowHiddenBoundsButCloserPositionAbsoluteParent = add(
`<div style="border: 1px solid red; width: 200px; height: 200px; overflow: hidden;">
<div style="position: absolute; left: 300px; border: 1px solid blue; width: 200px; height: 200px;">
<shadow-root id="el-out-of-parent-with-overflow-hidden-bounds-but-closer-position-absolute-parent"></shadow-root>
</div>
</div>`,
`<span style="border: 1px solid green;">Hello</span>`,
'#el-out-of-parent-with-overflow-hidden-bounds-but-closer-position-absolute-parent',
)
cy.wrap($elOutOfParentWithOverflowHiddenBoundsButCloserPositionAbsoluteParent).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($elOutOfParentWithOverflowHiddenBoundsButCloserPositionAbsoluteParent).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is hidden when parent is wide and ancestor outside shadow dom is overflow auto', () => {
const $elOutOfAncestorOverflowAutoBoundsOutside = add(
`<div style='width: 100px; height: 100px; overflow: auto;'>
<div style='width: 1000px; position: relative;'>
<shadow-root id="el-out-of-ancestor-overflow-auto-bounds-outside"></shadow-root>
</div>
</div>`,
`<span style='position: absolute; left: 300px; top: 0px;'>out of bounds, parent wide, ancestor overflow: auto</span>`,
'#el-out-of-ancestor-overflow-auto-bounds-outside',
)
cy.wrap($elOutOfAncestorOverflowAutoBoundsOutside).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfAncestorOverflowAutoBoundsOutside).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent is wide and ancestor inside shadow dom is overflow auto', () => {
const $elOutOfAncestorOverflowAutoBoundsInside = add(
`<div style='width: 100px; height: 100px; overflow: auto;'>
<shadow-root id="el-out-of-ancestor-overflow-auto-bounds-inside"></shadow-root>
</div>`,
`<div style='width: 1000px; position: relative;'>
<span style='position: absolute; left: 300px; top: 0px;'>out of bounds, parent wide, ancestor overflow: auto</span>
</div>`,
'#el-out-of-ancestor-overflow-auto-bounds-inside',
)
cy.wrap($elOutOfAncestorOverflowAutoBoundsInside).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfAncestorOverflowAutoBoundsInside).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent outside of shadow dom has overflow scroll and out of bounds', () => {
const $elOutOfScrollingParentBounds = add(
`<div style='width: 100px; height: 100px; overflow: scroll; position: relative; top: 700px; left: 700px;'>
<shadow-root id="el-out-of-scrolling-parent-bounds"></shadow-root>
</div>`,
`<span style='position: absolute; left: 300px; top: 0;'>out of scrolling bounds, position: absolute</span>`,
'#el-out-of-scrolling-parent-bounds',
)
cy.wrap($elOutOfScrollingParentBounds).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfScrollingParentBounds).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when parent absolutely positioned and overflow hidden and out of bounds', () => {
const $elOutOfPosAbsParentBounds = add(
`<div id="ancestor-el" style='width: 100px; height: 100px; overflow: hidden; position: relative; top: 700px; left: 700px;'>
<div>
<div id="parent-el" style='position: absolute;'>
<shadow-root id="el-out-of-pos-abs-parent-bounds"></shadow-root>
</div>
</div>
</div>`,
`<span id="el-under-test" style='position: absolute; left: -350px; top: 0;'>out of bounds, position: absolute</span>`,
'#el-out-of-pos-abs-parent-bounds',
)
cy.wrap($elOutOfPosAbsParentBounds).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elOutOfPosAbsParentBounds).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is visible when parent absolutely positioned and overflow hidden and not out of bounds', () => {
const $elInPosAbsParentsBounds = add(
`<div style='width: 200px; height: 200px; overflow: hidden; position: relative;'>
<div style='position: absolute;'>
<shadow-root id="el-in-pos-abs-parent-bounds"></shadow-root>
</div>
</div>`,
`<span style='position: absolute; left: 50px; top: 50px;'>in bounds, parent position: absolute</span>`,
'#el-in-pos-abs-parent-bounds',
)
cy.wrap($elInPosAbsParentsBounds).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($elInPosAbsParentsBounds).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible when parent overflow hidden and not out of bounds', () => {
const $elInParentBounds = add(
`<div style='width: 100px; height: 100px; overflow: hidden; position: relative;'>
<shadow-root id="el-in-parent-bounds"></shadow-root>
</div>`,
`<span style='position: absolute; left: 0; top: 0;'>in bounds, position: absolute</span>`,
'#el-in-parent-bounds',
)
cy.wrap($elInParentBounds).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($elInParentBounds).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible when ancestor outside shadow dom is overflow hidden but more distant ancestor is the offset parent', () => {
const $elIsOutOfBoundsOfOutsideAncestorsOverflowButWithinRelativeAncestor = add(
`<div style='padding: 100px; position: relative;'>
<div style='overflow: hidden;'>
<div>
<shadow-root id="el-is-out-of-bounds-of-outside-ancestors-overflow-but-within-relative-ancestor"></shadow-root>
</div>
</div>
</div>`,
`<span style='position: absolute; left: 0; top: 0;'>in bounds of ancestor, position: absolute, parent overflow: hidden</span>`,
'#el-is-out-of-bounds-of-outside-ancestors-overflow-but-within-relative-ancestor',
)
cy.wrap($elIsOutOfBoundsOfOutsideAncestorsOverflowButWithinRelativeAncestor).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($elIsOutOfBoundsOfOutsideAncestorsOverflowButWithinRelativeAncestor).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible when ancestor inside shadow dom is overflow hidden but more distant ancestor is the offset parent', () => {
const $elIsOutOfBoundsOfInsideAncestorsOverflowButWithinRelativeAncestor = add(
`<div style='padding: 100px; position: relative;'>
<shadow-root id="el-is-out-of-bounds-of-inside-ancestors-overflow-but-within-relative-ancestor"></shadow-root>
</div>`,
`<div style='overflow: hidden;'>
<div>
<span style='position: absolute; left: 0; top: 0;'>in bounds of ancestor, position: absolute, parent overflow: hidden</span>
</div>
</div>`,
'#el-is-out-of-bounds-of-inside-ancestors-overflow-but-within-relative-ancestor',
)
cy.wrap($elIsOutOfBoundsOfInsideAncestorsOverflowButWithinRelativeAncestor).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($elIsOutOfBoundsOfInsideAncestorsOverflowButWithinRelativeAncestor).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is hidden when relatively positioned outside of ancestor outside shadow dom with overflow hidden', () => {
const $elIsRelativeAndOutOfBoundsOfAncestorOverflow = add(
`<div style='overflow: hidden;'>
<div>
<shadow-root id="el-is-relative-and-out-of-bounds-of-ancestor-overflow"></shadow-root>
</div>
</div>`,
`<span style='position: relative; left: 0; top: -200px;'>out of bounds, position: relative</span>`,
'#el-is-relative-and-out-of-bounds-of-ancestor-overflow',
)
cy.wrap($elIsRelativeAndOutOfBoundsOfAncestorOverflow).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($elIsRelativeAndOutOfBoundsOfAncestorOverflow).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is visible when relatively positioned outside of ancestor outside shadow dom that does not hide overflow', () => {
const $elIsRelativeAndOutOfBoundsOfAncestorButAncestorShowsOverflow = add(
`<div>
<shadow-root id="el-is-relative-and-out-of-bounds-of-ancestor-but-ancestor-shows-overflow"></shadow-root>
</div>`,
`<span style='position: relative; left: 0; top: -200px;'>out of bounds but visible, position: relative</span>`,
'#el-is-relative-and-out-of-bounds-of-ancestor-but-ancestor-shows-overflow',
)
cy.wrap($elIsRelativeAndOutOfBoundsOfAncestorButAncestorShowsOverflow).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($elIsRelativeAndOutOfBoundsOfAncestorButAncestorShowsOverflow).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible when parent inside shadow dom is relatively positioned out of bounds but el is relatively positioned back in bounds', () => {
const $insideParentOutOfBoundsButElInBounds = add(
`<div style='position: relative; padding: 20px;'>
<div style='overflow: hidden;'>
<shadow-root id="inside-parent-out-of-bounds-but-el-in-bounds"></shadow-root>
</div>
</div>`,
`<div style='position: relative; left: 0; top: -100px;'>
<span style='position: relative; left: 0; top: 100px;'>in bounds of ancestor, parent out of bounds</span>
</div>`,
'#inside-parent-out-of-bounds-but-el-in-bounds',
)
cy.wrap($insideParentOutOfBoundsButElInBounds).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($insideParentOutOfBoundsButElInBounds).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is visible when parent outside shadow dom is relatively positioned out of bounds but el is relatively positioned back in bounds', () => {
const $outsideParentOutOfBoundsButElInBounds = add(
`<div style='position: relative; padding: 20px;'>
<div style='overflow: hidden;'>
<div style='position: relative; left: 0; top: -100px;'>
<shadow-root id="outside-parent-out-of-bounds-but-el-in-bounds"></shadow-root>
</div>
</div>
</div>`,
`<span style='position: relative; left: 0; top: 100px;'>in bounds of ancestor, parent out of bounds</span>`,
'#outside-parent-out-of-bounds-but-el-in-bounds',
)
cy.wrap($outsideParentOutOfBoundsButElInBounds).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($outsideParentOutOfBoundsButElInBounds).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
})
describe('css transform', () => {
it('is hidden when outside parent outside of shadow dom transform scale', () => {
const $parentWithTransformScaleElOutsideScale = add(
`<div style="transform: scale(0,0)">
<shadow-root id="parent-with-transform-scale-el-outside-scale"></shadow-root>
</div>`,
`<span>TRANSFORMERS</span>`,
'#parent-with-transform-scale-el-outside-scale',
)
cy.wrap($parentWithTransformScaleElOutsideScale).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($parentWithTransformScaleElOutsideScale).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is visible when inside parent outside of shadow dom transform scale', () => {
const $parentWithTransformScaleElInsideScale = add(
`<div style="transform: scale(1,1)">
<shadow-root id="parent-with-transform-scale-el-inside-scale"></shadow-root>
</div>`,
`<span>TRANSFORMERS</span>`,
'#parent-with-transform-scale-el-inside-scale',
)
cy.wrap($parentWithTransformScaleElInsideScale).find('span', { includeShadowDom: true }).should('be.visible')
cy.wrap($parentWithTransformScaleElInsideScale).find('span', { includeShadowDom: true }).should('not.be.hidden')
})
it('is hidden when out of ancestor bounds due to ancestor within shadow dom transform', () => {
const $ancestorInsideTransformMakesElOutOfBoundsOfAncestor = add(
`<div style='margin-left: 100px; overflow: hidden; width: 100px;'>
<shadow-root id="ancestor-inside-transform-makes-el-out-of-bounds-of-ancestor"></shadow-root>
</div>`,
`<div style='transform: translateX(-100px); width: 200px;'>
<div style='width: 100px;'>
<span>out of ancestor's bounds due to ancestor translate</span>
</div>
</div>`,
'#ancestor-inside-transform-makes-el-out-of-bounds-of-ancestor',
)
cy.wrap($ancestorInsideTransformMakesElOutOfBoundsOfAncestor).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($ancestorInsideTransformMakesElOutOfBoundsOfAncestor).find('span', { includeShadowDom: true }).should('not.be.visible')
})
it('is hidden when out of ancestor bounds due to ancestor outside shadow dom transform', () => {
const $ancestorOutsideTransformMakesElOutOfBoundsOfAncestor = add(
`<div style='margin-left: 100px; overflow: hidden; width: 100px;'>
<div style='transform: translateX(-100px); width: 200px;'>
<shadow-root id="ancestor-outside-transform-makes-el-out-of-bounds-of-ancestor"></shadow-root>
</div>
</div>`,
`<div style='width: 100px;'>
<span>out of ancestor's bounds due to ancestor translate</span>
</div>`,
'#ancestor-outside-transform-makes-el-out-of-bounds-of-ancestor',
)
cy.wrap($ancestorOutsideTransformMakesElOutOfBoundsOfAncestor).find('span', { includeShadowDom: true }).should('be.hidden')
cy.wrap($ancestorOutsideTransformMakesElOutOfBoundsOfAncestor).find('span', { includeShadowDom: true }).should('not.be.visible')
})
})
})