Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 28187 Include checkVisibility browser API as a reliable tool to check visibility #29741

Open
wants to merge 67 commits into
base: release/14.0.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
266a230
option correct
senpl Jun 18, 2024
06c6185
cleanup
senpl Jun 18, 2024
aa14167
visibility improvements
senpl Jun 19, 2024
cb09746
cleanup
senpl Jun 19, 2024
86a0706
fixes
senpl Jun 19, 2024
9035412
clean code
senpl Jun 19, 2024
b611dcf
first draft version
senpl Jun 24, 2024
16897b3
working version
senpl Jun 24, 2024
d379ed1
method cleanup
senpl Jun 24, 2024
2e29c52
first working all tests
senpl Jun 25, 2024
d1b218f
23852 fix
senpl Jun 25, 2024
455ff94
fix for 28187
senpl Jun 25, 2024
1f7e60e
cleanu that previously was not send
senpl Jun 25, 2024
008823d
fixes for less checks
senpl Jun 25, 2024
9bc9afd
remove 23852 fix
senpl Jun 25, 2024
723d8ab
changelog update
senpl Jun 25, 2024
7f4d723
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jun 25, 2024
0ab0172
Merge branch 'issue-28187-IncludeCheckVisibilityBrowserAPI' of https:…
senpl Jun 25, 2024
ddf7227
changelog fix
senpl Jun 25, 2024
27a73d3
changelog pull
senpl Jun 25, 2024
a85166c
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
jennifer-shehane Jun 25, 2024
4c70ef5
pipeline tests fix
senpl Jun 27, 2024
6bdb8fe
Merge branch 'issue-28187-IncludeCheckVisibilityBrowserAPI' of https:…
senpl Jun 27, 2024
7d121bd
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jun 27, 2024
8149120
requires for new webkit
senpl Jun 28, 2024
23a908b
Merge branch 'issue-28187-IncludeCheckVisibilityBrowserAPI' of https:…
senpl Jun 28, 2024
2f88b48
fix for older webkit versions
senpl Jun 28, 2024
3363c0d
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jun 28, 2024
6f5addf
probably only optimisation for visibility of ancestors
senpl Jul 1, 2024
6e82b87
Merge branch 'issue-28187-IncludeCheckVisibilityBrowserAPI' of https:…
senpl Jul 1, 2024
3919231
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 1, 2024
112ff53
webkit fixes and rework
senpl Jul 2, 2024
9d9da1d
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 2, 2024
917469f
pipeline fix
senpl Jul 2, 2024
2efd8f1
Merge branch 'issue-28187-IncludeCheckVisibilityBrowserAPI' of https:…
senpl Jul 2, 2024
7cdbcf7
another check, probably not needed.
senpl Jul 3, 2024
25ccdc1
better check for browser support
senpl Jul 8, 2024
8315929
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 8, 2024
ea58390
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 9, 2024
9c6de7b
changelog for pipeline fix
senpl Jul 9, 2024
01a7695
Update packages/driver/src/dom/visibility.ts
senpl Jul 10, 2024
c63a04b
Update packages/driver/src/dom/visibility.ts
senpl Jul 10, 2024
1e83807
Update packages/driver/src/dom/visibility.ts
senpl Jul 10, 2024
4beb4ab
Update packages/driver/src/dom/visibility.ts
senpl Jul 10, 2024
fac3bdc
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 10, 2024
a7a4c51
fix misspelled
senpl Jul 10, 2024
6720715
function simplification end test uncomment
senpl Jul 10, 2024
cbbbc67
fix for backward compatibility with webkit
senpl Jul 10, 2024
230dcb2
fix by separation of tests
senpl Jul 10, 2024
2e88040
removed parts related to visibility_css_position
senpl Jul 10, 2024
9fc2b85
cleanup unneded code
senpl Jul 10, 2024
baae2c8
fix for body and html with display none
senpl Jul 11, 2024
b55b2d0
add is not visible test for offset 0
senpl Jul 11, 2024
96cf4f1
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
jennifer-shehane Jul 12, 2024
8398812
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 25, 2024
6cddc81
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 26, 2024
1a933bc
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 29, 2024
7be78d2
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Jul 31, 2024
1ad3ff8
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Aug 7, 2024
cb9cc14
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Aug 8, 2024
0fb8a9f
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Aug 16, 2024
1c5b240
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Aug 30, 2024
f3d4545
Merge branch 'develop' into issue-28187-IncludeCheckVisibilityBrowserAPI
senpl Sep 30, 2024
e705a32
merge changelog
senpl Sep 30, 2024
a458041
remove unnecessery changelog changes.
senpl Sep 30, 2024
2f572c3
Merge branch 'release/14.0.0' into issue-28187-IncludeCheckVisibility…
senpl Oct 1, 2024
31e1294
added breaking changes section and bugfix for pipeline
senpl Oct 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ _Released 12/3/2024 (PENDING)_

**Breaking Changes:**

- Visibility checks are no longer inverse of element 'is.hidden' checks. Element now can be visible, but still not interactable. Use 'is.hidden' to make sure element can be used.

**Bugfixes:**

- Change visibility check to use checkVisibility browser API. Fixed in [#29741](https://github.com/cypress-io/cypress/pull/29741).

## 13.15.1

_Released 10/1/2024 (PENDING)_
Expand Down Expand Up @@ -1127,4 +1133,4 @@ _Released 1/24/2023_

- Video output link in `cypress run` mode has been added to it's own line to
make the video output link more easily clickable in the terminal. Addresses
[#23913](https://github.com/cypress-io/cypress/issues/23913).
[#23913](https://github.com/cypress-io/cypress/issues/23913).
136 changes: 27 additions & 109 deletions packages/driver/cypress/e2e/dom/visibility.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,18 @@ describe('src/cypress/dom/visibility', () => {
// ensure all tests run against a scrollable window
const scrollThisIntoView = add('<div style=`height: 1000px;` /><div>Should be in view</div>')

this.$visHidden = add('<ul style="visibility: hidden;"></ul>')
this.$visHidden = add('<ul id="ulHidden" style="visibility: hidden;">UL HIDDEN</ul>')
this.$parentVisHidden = add('<div class="invis" style="visibility: hidden;"><button>parent visibility: hidden</button></div>')
this.$displayNone = add('<button style="display: none">display: none</button>')
this.$inputHidden = add('<input type="hidden" value="abcdef">')
this.$divNoWidth = add('<div style="width: 0; height: 100px;">width: 0</div>')
this.$divNoWidth = add('<div id="divNoWidth" style="width: 0; height: 100px;">width: 0</div>')
this.$divNoHeight = add('<div style="width: 50px; height: 0px;">height: 0</div>')
this.$divDetached = $('<div>foo</div>')
this.$divVisible = add(`<div>visible</div>`)

this.$optionInSelect = add(`\
<select>
<option>Naruto</option>
<option id='optionInSelect' >Naruto</option>
</select>\
`)

Expand Down Expand Up @@ -244,19 +244,19 @@ describe('src/cypress/dom/visibility', () => {
</table>\
`)

this.$parentNoWidth = add(`\
this.$parentNoWidthOnly = add(`\
<div style='width: 0; height: 100px; overflow: hidden;'>
<span>parent width: 0</span>
</div>`)

this.$parentNoHeight = add(`\
<div style='width: 100px; height: 0px; overflow: hidden;'>
<span>parent height: 0</span>
<span id='parentNoHeight'>parent height: 0</span>
</div>`)

this.$parentNoWidthHeightOverflowAuto = add(`\
<div style='width: 0; height: 0px; overflow: auto;'>
<span>parent no size, overflow: auto</span>
<span id='parentNoWidthHeightOverflowAuto'>parent no size, overflow: auto</span>
</div>`)

this.$parentWithWidthHeightNoOverflow = add(`\
Expand Down Expand Up @@ -335,30 +335,10 @@ describe('src/cypress/dom/visibility', () => {
<div id="offScreenPosFixed" style="position: fixed; bottom: 0; left: -100px;">off screen</div>\
`)

this.$parentPosAbs = add(`\
<div style='width: 0; height: 100px; overflow: hidden; position: absolute;'>
<div style='height: 500px; width: 500px;'>
<span>parent position: absolute</span>
</div>
</div>`)

this.$parentDisplayNone = add(`\
<div id="none" style='display: none;'>
<span>parent display: none</span>
</div>\
`)

this.$parentPointerEventsNone = add(`\
<div style="pointer-events: none">
<span style="position: fixed; left: 0; top: 50%;">parent pointer-events: none</span>
</div>\
`)

this.$parentPointerEventsNoneCovered = add(`\
<div style="pointer-events: none;">
<span style="position: fixed; top: 40px;">parent pointer-events: none</span>
</div>
<span style="position: fixed; top: 40px; background: red;">covering the element with pointer-events: none</span>\
`)

this.$parentDisplayInlineChildDisplayBlock = add(`\
Expand Down Expand Up @@ -644,14 +624,14 @@ describe('src/cypress/dom/visibility', () => {

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#optionInSelect').is(':hidden')).to.be.false
expect(this.$optionInSelect.find('option#optionInSelect').is(':visible')).to.be.true

expect(this.$optionInSelect.find('option')).not.to.be.hidden
expect(this.$optionInSelect.find('option')).to.be.visible
expect(this.$optionInSelect.find('option#optionInSelect')).not.to.be.hidden
expect(this.$optionInSelect.find('option#optionInSelect')).to.be.visible

cy.wrap(this.$optionInSelect.find('option')).should('not.be.hidden')
cy.wrap(this.$optionInSelect.find('option')).should('be.visible')
cy.wrap(this.$optionInSelect.find('option#optionInSelect')).should('not.be.hidden')
cy.wrap(this.$optionInSelect.find('option#optionInSelect')).should('be.visible')
})

it('is visible if optgroup in visible select', function () {
Expand Down Expand Up @@ -687,8 +667,7 @@ describe('src/cypress/dom/visibility', () => {
cy.wrap(this.$optionHiddenInSelect.find('#hidden-opt')).should('not.be.visible')
})

// TODO(webkit): fix+unskip
it('follows regular visibility logic if option outside of select', { browser: '!webkit' }, function () {
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')
Expand Down Expand Up @@ -738,23 +717,24 @@ describe('src/cypress/dom/visibility', () => {
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')
})

it('is not visible if offsetWidth is 0', function () {
expect(this.$divNoWidth.is(':visible')).to.be.false
expect(this.$divNoWidth).to.not.be.visible
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
expect(this.$parentNoWidthOnly.find('span#parentNoWidthOnly')).to.be.hidden
expect(this.$parentNoWidthOnly.find('span#parentNoWidthOnly')).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
expect(this.$parentNoHeight.find('span#parentNoHeight')).to.be.hidden
expect(this.$parentNoHeight.find('span#parentNoHeight')).to.not.be.visible
})

it('is hidden if ancestor has overflow:hidden and no width', function () {
Expand All @@ -778,68 +758,6 @@ describe('src/cypress/dom/visibility', () => {
})
})

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 () {
Expand All @@ -850,8 +768,8 @@ describe('src/cypress/dom/visibility', () => {

describe('css overflow', () => {
it('is hidden when parent overflow auto and no width/height', function () {
expect(this.$parentNoWidthHeightOverflowAuto.find('span')).to.not.be.visible
expect(this.$parentNoWidthHeightOverflowAuto.find('span')).to.be.hidden
expect(this.$parentNoWidthHeightOverflowAuto.find('span#parentNoWidthHeightOverflowAuto')).to.not.be.visible
expect(this.$parentNoWidthHeightOverflowAuto.find('span#parentNoWidthHeightOverflowAuto')).to.be.hidden
})

it('is hidden when parent overflow hidden and out of bounds to left', function () {
Expand Down Expand Up @@ -1144,7 +1062,7 @@ describe('src/cypress/dom/visibility', () => {
})

it('has `visibility: hidden`', function () {
this.reasonIs(this.$visHidden, 'This element `<ul>` is not visible because it has CSS property: `visibility: hidden`')
this.reasonIs(this.$visHidden, 'This element `<ul#ulHidden>` is not visible because it has CSS property: `visibility: hidden`')
})

it('has parent with `visibility: hidden`', function () {
Expand Down Expand Up @@ -1172,15 +1090,15 @@ describe('src/cypress/dom/visibility', () => {
})

it('has effective zero width', function () {
this.reasonIs(this.$divNoWidth, 'This element `<div>` is not visible because it has an effective width and height of: `0 x 100` pixels.')
this.reasonIs(this.$divNoWidth, 'This element `<div#divNoWidth>` is not visible because it has an effective width and height of: `0 x 100` pixels.')
})

it('has effective zero height', function () {
this.reasonIs(this.$divNoHeight, 'This element `<div>` is not visible because it has an effective width and height of: `50 x 0` pixels.')
})

it('has a parent with an effective zero width and overflow: hidden', function () {
this.reasonIs(this.$parentNoHeight.find('span'), 'This element `<span>` is not visible because its parent `<div>` has CSS property: `overflow: hidden` and an effective width and height of: `100 x 0` pixels.')
this.reasonIs(this.$parentNoHeight.find('span#parentNoHeight'), 'This element `<span#parentNoHeight>` is not visible because its parent `<div>` has CSS property: `overflow: hidden` and an effective width and height of: `100 x 0` pixels.')
})

it('element sits outside boundaries of parent with overflow clipping', function () {
Expand Down
Loading