diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 06bad21ac65d..e17d325415bb 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -5,6 +5,11 @@ _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). Fixes [#28187](https://github.com/cypress-io/cypress/issues/28187). - Removed support for Node.js 16 and Node.js 21. Addresses [#29930](https://github.com/cypress-io/cypress/issues/29930). - Prebuilt binaries for Linux are no longer compatible with Linux distributions based on glibc <2.28, for example: Ubuntu 14-18, RHEL 7, CentOS 7, Amazon Linux 2. Addresses [#29601](https://github.com/cypress-io/cypress/issues/29601). - Cypress now only officially supports the latest 3 major versions of Chrome, Firefox, and Edge - older browser versions may still work, but we recommend keeping your browsers up to date to ensure compatibility with Cypress. A warning will no longer be displayed on browser selection in the Launchpad for any 'unsupported' browser versions. Additionally, the undocumented `minSupportedVersion` property has been removed from `Cypress.browser`. Addressed in [#30462](https://github.com/cypress-io/cypress/pull/30462). @@ -1184,4 +1189,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). \ No newline at end of file diff --git a/packages/driver/cypress/e2e/dom/visibility.cy.ts b/packages/driver/cypress/e2e/dom/visibility.cy.ts index fe82cfb0bd02..2c72fa2095f3 100644 --- a/packages/driver/cypress/e2e/dom/visibility.cy.ts +++ b/packages/driver/cypress/e2e/dom/visibility.cy.ts @@ -170,18 +170,18 @@ describe('src/cypress/dom/visibility', () => { // ensure all tests run against a scrollable window const scrollThisIntoView = add('
Should be in view
') - this.$visHidden = add('') + this.$visHidden = add('') this.$parentVisHidden = add('') this.$displayNone = add('') this.$inputHidden = add('') - this.$divNoWidth = add('
width: 0
') + this.$divNoWidth = add('
width: 0
') this.$divNoHeight = add('
height: 0
') this.$divDetached = $('
foo
') this.$divVisible = add(`
visible
`) this.$optionInSelect = add(`\ \ `) @@ -244,19 +244,19 @@ describe('src/cypress/dom/visibility', () => { \ `) - this.$parentNoWidth = add(`\ + this.$parentNoWidthOnly = add(`\
parent width: 0
`) this.$parentNoHeight = add(`\
- parent height: 0 + parent height: 0
`) this.$parentNoWidthHeightOverflowAuto = add(`\
- parent no size, overflow: auto + parent no size, overflow: auto
`) this.$parentWithWidthHeightNoOverflow = add(`\ @@ -335,30 +335,10 @@ describe('src/cypress/dom/visibility', () => {
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(`\ @@ -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 () { @@ -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') @@ -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 () { @@ -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 () { @@ -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 () { @@ -1144,7 +1062,7 @@ describe('src/cypress/dom/visibility', () => { }) it('has `visibility: hidden`', function () { - this.reasonIs(this.$visHidden, 'This element `