const { $, dom } = Cypress export {} describe('src/cypress/dom/visibility', () => { beforeEach(() => { cy.visit('/fixtures/generic.html') }) context('isHidden', () => { it('exposes isHidden', () => { expect(dom.isHidden).to.be.a('function') }) it('throws when not passed a DOM element', () => { const fn = () => { dom.isHidden(null!) } expect(fn).to.throw('`Cypress.dom.isHidden()` failed because it requires a DOM element. The subject received was: `null`') }) }) context('isVisible', () => { it('exposes isVisible', () => { expect(dom.isVisible).to.be.a('function') }) it('throws when not passed a DOM element', () => { const fn = () => { // @ts-ignore dom.isVisible('form') } expect(fn).to.throw('`Cypress.dom.isVisible()` failed because it requires a DOM element. The subject received was: `form`') }) }) context('#isScrollable', () => { beforeEach(function () { this.add = (el) => { return $(el).appendTo(cy.$$('body')) } }) it('returns true if window and body > window height', function () { this.add('
') const win = cy.state('window') const fn = () => { return dom.isScrollable(win) } expect(fn()).to.be.true }) it('returns false window and body > window height', () => { cy.$$('body').html('
foo
') const win = cy.state('window') const fn = () => { return dom.isScrollable(win) } expect(fn()).to.be.false }) it('returns false el is not scrollable', function () { const noScroll = this.add(`\
No Scroll
\ `) const fn = () => { return dom.isScrollable(noScroll) } expect(fn()).to.be.false }) it('returns false el has no overflow', function () { const noOverflow = this.add(`\
No Overflow Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Etiam porta sem malesuada magna mollis euismod.
\ `) const fn = () => { return dom.isScrollable(noOverflow) } expect(fn()).to.be.false }) it('returns true when vertically scrollable', function () { const vertScrollable = this.add(`\
Vertical Scroll
\ `) const fn = () => { return dom.isScrollable(vertScrollable) } expect(fn()).to.be.true }) it('returns true when horizontal scrollable', function () { const horizScrollable = this.add(`\
Horizontal Scroll
\ `) const fn = () => { return dom.isScrollable(horizScrollable) } expect(fn()).to.be.true }) it('returns true when overflow scroll forced and content larger', function () { const forcedScroll = this.add(`\
Forced Scroll
\ `) const fn = () => { return dom.isScrollable(forcedScroll) } expect(fn()).to.be.true }) }) context('hidden/visible overrides', () => { beforeEach(function () { const add = (el) => { return $(el).appendTo(cy.$$('body')) } // ensure all tests run against a scrollable window const scrollThisIntoView = add('
Should be in view
') this.$visHidden = add('') this.$parentVisHidden = add('') this.$displayNone = add('') this.$inputHidden = add('') this.$divNoWidth = add('
width: 0
') this.$divNoHeight = add('
height: 0
') this.$divDetached = $('
foo
') this.$divVisible = add(`
visible
`) this.$optionInSelect = add(`\ \ `) this.$optgroupInSelect = add(`\ \ `) this.$optionInHiddenSelect = add(`\ \ `) this.$optionOutsideSelect = add(`\
\ `) this.$optionHiddenInSelect = add(`\ \ `) this.$btnOpacityZero = add(`\ \ `) this.$btnOpacityHalf = add(`\ \ `) this.$parentOpacityZero = add(`\
\ `) this.$tableVisCollapse = add(`\
Naruto Sasuke Sakura
Kaguya Madara Orochimaro
\ `) this.$parentNoWidth = add(`\
parent width: 0
`) this.$parentNoHeight = add(`\
parent height: 0
`) this.$parentNoWidthHeightOverflowAuto = add(`\
parent no size, overflow: auto
`) this.$parentWithWidthHeightNoOverflow = add(`\
parent with size, overflow: hidden
`) this.$childPosAbs = add(`\
position: absolute
`) this.$childPosFixed = add(`\
`) this.$childPointerEventsNone = add(`\
child pointer-events: none
\ `) this.$descendentPosAbs = add(`\
no width, descendant position: absolute
`) this.$descendentPosFixed = add(`\
`) this.$descendantInPosFixed = add(`\
underneath
on top of the other
\ `) this.$coveredUpPosFixed = add(`\
underneath
on top
\ `) this.$offScreenPosFixed = add(`\
off screen
\ `) this.$parentPosAbs = add(`\
parent position: absolute
`) this.$parentDisplayNone = add(`\ \ `) this.$parentPointerEventsNone = add(`\
parent pointer-events: none
\ `) this.$parentPointerEventsNoneCovered = add(`\
parent pointer-events: none
covering the element with pointer-events: none\ `) this.$parentDisplayInlineChildDisplayBlock = add(`\
\ `) this.$elOutOfParentBoundsToLeft = add(`\
position: absolute, out of bounds left
\ `) this.$elOutOfParentBoundsToRight = add(`\
position: absolute, out of bounds right
\ `) this.$elOutOfParentBoundsAbove = add(`\
position: absolute, out of bounds above
\ `) this.$elOutOfParentBoundsBelow = add(`\
position: absolute, out of bounds below
\ `) this.$elOutOfParentWithOverflowYHiddenBounds = add(`\
position: absolute, out of bounds below
\ `) this.$elOutOfParentWithOverflowXHiddenBounds = add(`\
position: absolute, out of bounds below
\ `) this.$elOutOfParentWithFlexAndOverflowHiddenBounds = add(`\
red
green
blue
\ `) this.$elOutOfParentWithOverflowHiddenBoundsButCloserPositionAbsoluteParent = add(`\
Hello
\ `) this.$elOutOfAncestorOverflowAutoBounds = add(`\
out of bounds, parent wide, ancestor overflow: auto
\ `) this.$elInPosAbsParentsBounds = add(`\
in bounds, parent position: absolute
\ `) this.$elOutOfPosAbsParentsBounds = add(`\
out of bounds, parent position: absolute
\ `) this.$elInParentBounds = add(`\
in bounds, position: absolute
\ `) this.$elOutOfScrollingParentBounds = add(`\
out of scrolling bounds, position: absolute
\ `) this.$elIsOutOfBoundsOfAncestorsOverflowButWithinRelativeAncestor = add(`\
in bounds of ancestor, position: absolute, parent overflow: hidden
\ `) this.$elIsRelativeAndOutOfBoundsOfAncestorOverflow = add(`\
out of bounds, position: relative
\ `) this.$elIsRelativeAndOutOfBoundsOfAncestorButAncestorShowsOverflow = add(`\
out of bounds but visible, position: relative
\ `) this.$parentOutOfBoundsButElInBounds = add(`\
in bounds of ancestor, parent out of bounds
\ `) this.$parentWithClipPathAbsolutePositionElOutsideClipPath = add(`\
clip-path
\ `) this.$parentWithClipPathAbsolutePositionElInsideClipPath = add(`\
clip-path
\ `) this.$parentWithTransformScaleElOutsideScale = add(`\
TRANSFORMERS
\ `) this.$parentWithTransformScaleElInsideScale = add(`\
TRANSFORMERS
\ `) this.$ancestorTransformMakesElOutOfBoundsOfAncestor = add(`\
out of ancestor's bounds due to ancestor translate
\ `) this.$ancestorTransformMakesElInBoundsOfAncestor = add(`\
out of ancestor's bounds due to ancestor translate
in ancestor's bounds due to ancestor translate
\ `) // 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('html or body', () => { it('is visible if html', () => { expect(cy.$$('html').is(':hidden')).to.be.false expect(cy.$$('html').is(':visible')).to.be.true expect(cy.$$('html')).not.to.be.hidden expect(cy.$$('html')).to.be.visible cy.wrap(cy.$$('html')).should('not.be.hidden') cy.wrap(cy.$$('html')).should('be.visible') }) it('is visible if body', () => { expect(cy.$$('body').is(':hidden')).to.be.false expect(cy.$$('body').is(':visible')).to.be.true expect(cy.$$('body')).not.to.be.hidden expect(cy.$$('body')).to.be.visible cy.wrap(cy.$$('body')).should('not.be.hidden') cy.wrap(cy.$$('body')).should('be.visible') }) it('is visible if display none on body or html', () => { cy.$$('html').css('display', 'none') cy.$$('body').css('display', 'none') expect(cy.$$('html')).not.to.be.hidden expect(cy.$$('html')).to.be.visible expect(cy.$$('body')).not.to.be.hidden expect(cy.$$('body')).to.be.visible }) }) describe('css visibility', () => { it('is hidden if .css(visibility) is hidden', function () { expect(this.$visHidden.is(':hidden')).to.be.true expect(this.$visHidden.is(':visible')).to.be.false expect(this.$visHidden).to.be.hidden expect(this.$visHidden).to.not.be.visible cy.wrap(this.$visHidden).should('be.hidden') cy.wrap(this.$visHidden).should('not.be.visible') }) it('is hidden if parents have .css(visibility) hidden', function () { expect(this.$parentVisHidden.find('button').is(':hidden')).to.be.true expect(this.$parentVisHidden.find('button').is(':visible')).to.be.false expect(this.$parentVisHidden.find('button')).to.be.hidden expect(this.$parentVisHidden.find('button')).to.not.be.visible cy.wrap(this.$parentVisHidden).find('button').should('be.hidden') cy.wrap(this.$parentVisHidden).find('button').should('not.be.visible') }) it('is hidden if visibility collapse', function () { expect(this.$tableVisCollapse.find('td.collapse')).to.be.hidden expect(this.$tableVisCollapse.find('td.collapse')).to.not.be.visible expect(this.$tableVisCollapse.find('tr.collapse')).to.be.hidden expect(this.$tableVisCollapse.find('tr.collapse')).to.not.be.visible expect(this.$tableVisCollapse.find('tr.collapse td')).to.be.hidden expect(this.$tableVisCollapse.find('tr.collapse td')).to.not.be.visible }) it('is hidden if parent has visibility collapse', function () { expect(this.$tableVisCollapse.find('tr.collapse td')).to.be.hidden expect(this.$tableVisCollapse.find('tr.collapse td')).to.not.be.visible expect(this.$tableVisCollapse.find('#collapse-span')).to.be.hidden expect(this.$tableVisCollapse.find('#collapse-span')).to.not.be.visible }) it('is hidden if input type hidden', function () { expect(this.$inputHidden.is(':hidden')).to.be.true expect(this.$inputHidden.is(':visible')).to.be.false expect(this.$inputHidden).to.be.hidden expect(this.$inputHidden).to.not.be.visible cy.wrap(this.$inputHidden).should('be.hidden') cy.wrap(this.$inputHidden).should('not.be.visible') }) }) describe('option and optgroup', () => { it('is visible if option in visible select', function () { expect(this.$optionInSelect.find('option').is(':hidden')).to.be.false expect(this.$optionInSelect.find('option').is(':visible')).to.be.true expect(this.$optionInSelect.find('option')).not.to.be.hidden expect(this.$optionInSelect.find('option')).to.be.visible cy.wrap(this.$optionInSelect.find('option')).should('not.be.hidden') cy.wrap(this.$optionInSelect.find('option')).should('be.visible') }) it('is visible if optgroup in visible select', function () { expect(this.$optgroupInSelect.find('optgroup').is(':hidden')).to.be.false expect(this.$optgroupInSelect.find('optgroup').is(':visible')).to.be.true expect(this.$optgroupInSelect.find('optgroup')).not.to.be.hidden expect(this.$optgroupInSelect.find('optgroup')).to.be.visible cy.wrap(this.$optgroupInSelect.find('optgroup')).should('not.be.hidden') cy.wrap(this.$optgroupInSelect.find('optgroup')).should('be.visible') }) it('is hidden if option in hidden select', function () { expect(this.$optionInHiddenSelect.find('option').is(':hidden')).to.be.true expect(this.$optionInHiddenSelect.find('option').is(':visible')).to.be.false expect(this.$optionInHiddenSelect.find('option')).to.be.hidden expect(this.$optionInHiddenSelect.find('option')).not.to.be.visible cy.wrap(this.$optionInHiddenSelect.find('option')).should('be.hidden') cy.wrap(this.$optionInHiddenSelect.find('option')).should('not.be.visible') }) it('is hidden if option is display none', function () { expect(this.$optionHiddenInSelect.find('#hidden-opt').is(':hidden')).to.be.true expect(this.$optionHiddenInSelect.find('#hidden-opt').is(':visible')).to.be.false expect(this.$optionHiddenInSelect.find('#hidden-opt')).to.be.hidden expect(this.$optionHiddenInSelect.find('#hidden-opt')).not.to.be.visible cy.wrap(this.$optionHiddenInSelect.find('#hidden-opt')).should('be.hidden') cy.wrap(this.$optionHiddenInSelect.find('#hidden-opt')).should('not.be.visible') }) it('follows regular visibility logic if option outside of select', function () { expect(this.$optionOutsideSelect.find('#option-hidden').is(':hidden')).to.be.true expect(this.$optionOutsideSelect.find('#option-hidden')).to.be.hidden cy.wrap(this.$optionOutsideSelect.find('#option-hidden')).should('be.hidden') expect(this.$optionOutsideSelect.find('#option-visible').is(':visible')).to.be.true expect(this.$optionOutsideSelect.find('#option-visible')).to.be.visible cy.wrap(this.$optionOutsideSelect.find('#option-visible')).should('be.visible') }) }) describe('css opacity', () => { it('is hidden if opacity is 0', function () { expect(this.$btnOpacityZero.is(':hidden')).to.be.true expect(this.$btnOpacityZero.is(':visible')).to.be.false expect(this.$btnOpacityZero).to.be.hidden expect(this.$btnOpacityZero).not.to.be.visible cy.wrap(this.$btnOpacityZero).should('be.hidden') cy.wrap(this.$btnOpacityZero).should('not.be.visible') }) it('is hidden if parent has `opacity: 0`', function () { expect(this.$parentOpacityZero.find('button').is(':hidden')).to.be.true expect(this.$parentOpacityZero.find('button').is(':visible')).to.be.false expect(this.$parentOpacityZero.find('button')).to.be.hidden expect(this.$parentOpacityZero.find('button')).not.to.be.visible cy.wrap(this.$parentOpacityZero.find('button')).should('be.hidden') cy.wrap(this.$parentOpacityZero.find('button')).should('not.be.visible') }) it('is visible if opacity is greater than 0 but less than 1', function () { expect(this.$btnOpacityHalf.is(':visible')).to.be.true expect(this.$btnOpacityHalf.is(':hidden')).to.be.false expect(this.$btnOpacityHalf).to.be.visible expect(this.$btnOpacityHalf).not.to.be.hidden cy.wrap(this.$btnOpacityHalf).should('be.visible') cy.wrap(this.$btnOpacityHalf).should('not.be.hidden') }) }) describe('width and height', () => { it('is hidden if offsetWidth is 0', function () { expect(this.$divNoWidth.is(':hidden')).to.be.true expect(this.$divNoWidth.is(':visible')).to.be.false expect(this.$divNoWidth).to.be.hidden expect(this.$divNoWidth).to.not.be.visible cy.wrap(this.$divNoWidth).should('be.hidden') cy.wrap(this.$divNoWidth).should('not.be.visible') }) it('is hidden if parent has overflow: hidden and no width', function () { expect(this.$parentNoWidth.find('span')).to.be.hidden expect(this.$parentNoWidth.find('span')).to.not.be.visible }) it('is hidden if parent has overflow: hidden and no height', function () { expect(this.$parentNoHeight.find('span')).to.be.hidden expect(this.$parentNoHeight.find('span')).to.not.be.visible }) it('is visible when parent has positive dimensions even with overflow hidden', function () { expect(this.$parentWithWidthHeightNoOverflow.find('span')).to.be.visible expect(this.$parentWithWidthHeightNoOverflow.find('span')).to.not.be.hidden }) }) describe('css position', () => { it('is visible if child has position: absolute', function () { expect(this.$childPosAbs.find('span')).to.be.visible expect(this.$childPosAbs.find('span')).not.be.hidden }) it('is visible if child has position: fixed', function () { expect(this.$childPosFixed.find('button')).to.be.visible expect(this.$childPosFixed.find('button')).not.to.be.hidden }) it('is visible if descendent from parent has position: fixed', function () { expect(this.$descendentPosFixed.find('button')).to.be.visible expect(this.$descendentPosFixed.find('button')).not.to.be.hidden }) it('is visible if has position: fixed and descendent is found', function () { expect(this.$descendantInPosFixed.find('#descendantInPosFixed')).to.be.visible expect(this.$descendantInPosFixed.find('#descendantInPosFixed')).not.to.be.hidden }) it('is hidden if position: fixed and covered up', function () { expect(this.$coveredUpPosFixed.find('#coveredUpPosFixed')).to.be.hidden expect(this.$coveredUpPosFixed.find('#coveredUpPosFixed')).not.to.be.visible }) it('is hidden if position: fixed and off screen', function () { expect(this.$offScreenPosFixed).to.be.hidden expect(this.$offScreenPosFixed).not.to.be.visible }) it('is visible if descendent from parent has position: absolute', function () { expect(this.$descendentPosAbs.find('span')).to.be.visible expect(this.$descendentPosAbs.find('span')).to.not.be.hidden }) it('is hidden if only the parent has position absolute', function () { expect(this.$parentPosAbs.find('span')).to.be.hidden expect(this.$parentPosAbs.find('span')).to.not.be.visible }) it('is visible if position: fixed and parent has pointer-events: none', function () { expect(this.$parentPointerEventsNone.find('span')).to.be.visible expect(this.$parentPointerEventsNone.find('span')).to.not.be.hidden }) it('is not visible if covered when position: fixed and parent has pointer-events: none', function () { expect(this.$parentPointerEventsNoneCovered.find('span')).to.be.hidden expect(this.$parentPointerEventsNoneCovered.find('span')).to.not.be.visible }) it('is visible if pointer-events: none and parent has position: fixed', function () { expect(this.$childPointerEventsNone.find('span')).to.be.visible expect(this.$childPointerEventsNone.find('span')).to.not.be.hidden }) it('is visible when position: sticky', () => { cy.visit('fixtures/sticky.html') cy.get('#button').should('be.visible') }) }) describe('css display', function () { // https://github.com/cypress-io/cypress/issues/6183 it('parent is visible if display inline and child has display block', function () { expect(this.$parentDisplayInlineChildDisplayBlock.find('span')).to.be.visible expect(this.$parentDisplayInlineChildDisplayBlock.find('span')).to.not.be.hidden }) }) describe('css overflow', () => { it('is visible when parent doesnt have overflow hidden', function () { expect(this.$parentNoWidthHeightOverflowAuto.find('span')).to.be.visible expect(this.$parentNoWidthHeightOverflowAuto.find('span')).to.not.be.hidden }) it('is hidden when parent overflow hidden and out of bounds to left', function () { expect(this.$elOutOfParentBoundsToLeft.find('span')).to.be.hidden }) it('is hidden when parent overflow hidden and out of bounds to right', function () { expect(this.$elOutOfParentBoundsToRight.find('span')).to.be.hidden }) it('is hidden when parent overflow hidden and out of bounds above', function () { expect(this.$elOutOfParentBoundsAbove.find('span')).to.be.hidden }) it('is hidden when parent overflow hidden and out of bounds below', function () { expect(this.$elOutOfParentBoundsBelow.find('span')).to.be.hidden }) it('is hidden when parent overflow-y hidden and out of bounds', function () { expect(this.$elOutOfParentWithOverflowYHiddenBounds.find('span')).to.be.hidden }) it('is hidden when parent overflow-x hidden and out of bounds', function () { expect(this.$elOutOfParentWithOverflowXHiddenBounds.find('span')).to.be.hidden }) it('is visible when parent overflow hidden but el in a closer parent with position absolute', function () { expect(this.$elOutOfParentWithOverflowHiddenBoundsButCloserPositionAbsoluteParent.find('span')).to.be.visible }) it('is hidden when parent flex and overflow hidden and el out of bounds', function () { expect(this.$elOutOfParentWithFlexAndOverflowHiddenBounds.find('#red')).to.be.visible expect(this.$elOutOfParentWithFlexAndOverflowHiddenBounds.find('#green')).to.be.visible expect(this.$elOutOfParentWithFlexAndOverflowHiddenBounds.find('#blue')).to.be.hidden }) it('is hidden when parent is wide and ancestor is overflow auto', function () { expect(this.$elOutOfAncestorOverflowAutoBounds.find('span')).to.be.hidden }) it('is hidden when parent overflow scroll and out of bounds', function () { expect(this.$elOutOfScrollingParentBounds.find('span')).to.be.hidden }) it('is hidden when parent absolutely positioned and overflow hidden and out of bounds', function () { expect(this.$elOutOfPosAbsParentsBounds.find('span')).to.be.hidden }) it('is visible when parent absolutely positioned and overflow hidden and not out of bounds', function () { expect(this.$elInPosAbsParentsBounds.find('span')).to.be.visible }) it('is visible when parent overflow hidden and not out of bounds', function () { expect(this.$elInParentBounds.find('span')).to.be.visible }) it('is visible when ancestor is overflow hidden but more distant ancestor is the offset parent', function () { expect(this.$elIsOutOfBoundsOfAncestorsOverflowButWithinRelativeAncestor.find('span')).to.be.visible }) it('is hidden when relatively positioned outside ancestor with overflow hidden', function () { expect(this.$elIsRelativeAndOutOfBoundsOfAncestorOverflow.find('span')).to.be.hidden }) it('is visible when el is relatively positioned outside ancestor that does not hide overflow', function () { expect(this.$elIsRelativeAndOutOfBoundsOfAncestorButAncestorShowsOverflow.find('span')).to.be.visible }) it('is visible when parent is relatively positioned out of bounds but el is relatively positioned back in bounds', function () { expect(this.$parentOutOfBoundsButElInBounds.find('span')).to.be.visible }) }) describe('css clip-path', () => { // TODO: why is this skipped? it.skip('is hidden when outside of parents clip-path', function () { expect(this.$parentWithClipPathAbsolutePositionElOutsideClipPath.find('span')).to.be.hidden }) it('is visible when inside of parents clip-path', function () { expect(this.$parentWithClipPathAbsolutePositionElInsideClipPath.find('span')).to.be.visible }) }) describe('css transform', () => { const add = (el) => { return $(el).appendTo(cy.$$('body')) } describe('element visibility by css transform', () => { it('is visible when an element is translated a bit', () => { const el = add(`
Translated
`) expect(el).to.be.visible }) it('is visible when an element is only skewed', () => { const el = add(`
Skewed
`) expect(el).to.be.visible }) it('is visible when an element is only rotated', () => { const el = add(`
Rotated
`) expect(el).to.be.visible }) it('is visible when an element is scaled by non-zero', () => { const el = add(`
Scaled
`) expect(el).to.be.visible }) it('is visible when an element is transformed in multiple ways but not scaled to zero', () => { const el = add(`
Multiple transform
`) expect(el).to.be.visible }) it('is visible when an element is rotateZ(90deg)', () => { const el = add(`
rotateZ(90deg)
`) expect(el).to.be.visible }) // https://github.com/cypress-io/cypress/issues/6745 it('is visible even if there is a dangling element in the tree', () => { cy.visit('/fixtures/dangling-element.html') cy.get('.hello') }) it('is hidden when an element is scaled to X axis in 0', () => { const el = add(`
ScaleX(0)
`) expect(el).to.be.hidden }) it('is hidden when an element is scaled to Y axis in 0', () => { const el = add(`
ScaleY(0)
`) expect(el).to.be.hidden }) it('is hidden when an element is scaled to Z axis in 0', () => { const el = add(`
ScaleZ(0)
`) expect(el).to.be.hidden }) it('is hidden when an element is transformed in multiple ways but scaled to 0 in one axis', () => { const el = add(`
Multiple 2
`) expect(el).to.be.hidden }) it('is hidden when an element is rotateX(90deg)', () => { const el = add(`
rotateX(90deg)
`) expect(el).to.be.hidden }) it('is hidden when an element is rotateY(90deg)', () => { const el = add(`
rotateY(90deg)
`) expect(el).to.be.hidden }) it('is hidden when an element is rotateX(90deg) rotateY(90deg)', () => { const el = add(`
rotateX(90deg)
`) expect(el).to.be.hidden }) it('is hidden when an element is transformed in multiple ways but rotated to 90 deg in X or Y axis', () => { const el = add(`
rotateX(90deg)
`) expect(el).to.be.hidden const el2 = add(`
rotateX(90deg)
`) expect(el2).to.be.hidden const el3 = add(`
rotateX(90deg)
`) expect(el3).to.be.hidden }) }) describe('when height/width is set', () => { it('is visible when transform is not 0, but height is 0', () => { const el = add('
Text
') expect(el).to.be.visible }) it('is visible when transform is not 0, but width is 0', () => { const el = add('

Text

') expect(el).to.be.visible }) it('is visible when parent transform is not 0, but height is 0', () => { const el = add('

Text

') expect(el.find('#tr-p-0')).to.be.visible }) it('is visible when parent transform is not 0, but width is 0', () => { const el = add('

Test

') expect(el.find('#tr-p-1')).to.be.visible }) it('is invisible when parent transform is 0, but height is not 0', () => { const el = add('

Test

') expect(el.find('#tr-p-2')).to.be.hidden }) describe('invisible when overflow: hidden', () => { it('height: 0 + overflow', () => { const el = add('

Test

') expect(el.find('#h0th')).to.be.hidden }) it('height: 0 + overflow-x', () => { const el = add('

Test

') expect(el.find('#h0th')).to.be.hidden }) it('height: 0 + overflow-y', () => { const el = add('

Test

') expect(el.find('#h0th')).to.be.hidden }) it('width: 0 + overflow', () => { const el = add('

Test

') expect(el.find('#h0th')).to.be.hidden }) it('width: 0 + overflow-x', () => { const el = add('

Test

') expect(el.find('#h0th')).to.be.hidden }) it('width: 0 + overflow-y', () => { const el = add('

Test

') expect(el.find('#h0th')).to.be.hidden }) }) }) it('is hidden when outside parents transform scale', function () { expect(this.$parentWithTransformScaleElOutsideScale.find('span')).to.be.hidden }) it('is visible when inside of parents transform scale', function () { expect(this.$parentWithTransformScaleElInsideScale.find('span')).to.be.visible }) it('is hidden when out of ancestor\'s bounds due to ancestor\'s transform', function () { expect(this.$ancestorTransformMakesElOutOfBoundsOfAncestor.find('span')).to.be.hidden }) it('is visible when in ancestor\'s bounds due to ancestor\'s transform', function () { expect(this.$ancestorTransformMakesElInBoundsOfAncestor.find('#inbounds')).to.be.visible }) }) describe('#getReasonIsHidden', () => { beforeEach(function () { this.reasonIs = ($el, str) => { expect(dom.getReasonIsHidden($el)).to.eq(str) } }) it('has `display: none`', function () { this.reasonIs(this.$displayNone, 'This element `
`) this.reasonIs(el.find('#needsScroll'), `This element \`\` is not visible because its ancestor has \`position: fixed\` CSS property and it is overflowed by other elements. How about scrolling to the element with \`cy.scrollIntoView()\`?`) }) it('cannot determine why element is not visible', function () { // this element is actually visible // but used here as an example that does not match any of the above this.reasonIs(this.$divVisible, 'This element `
` is not visible.') }) }) }) })