UNPKG

@revoloo/cypress6

Version:

Cypress.io end to end testing tool

641 lines (549 loc) 32.3 kB
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') }) }) })