From 61e8cfe86f3da68d50069b9175db9f05cc321d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Fri, 14 Jun 2024 11:15:11 +0200 Subject: [PATCH 01/14] forst working version --- cli/CHANGELOG.md | 1 + .../driver/cypress/e2e/issues/29605.cy.js | 13 +++ .../driver/cypress/fixtures/issue-29605.html | 33 ++++++ packages/driver/src/dom/visibility.ts | 109 ++++++++++++------ 4 files changed, 118 insertions(+), 38 deletions(-) create mode 100644 packages/driver/cypress/e2e/issues/29605.cy.js create mode 100644 packages/driver/cypress/fixtures/issue-29605.html diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 39b6e6ed6c2c..531bda028ec1 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -13,6 +13,7 @@ _Released 6/18/2024 (PENDING)_ - Fixed an issue where `inlineSourceMaps` was still being used when `sourceMaps` was provided in a users typescript config for typescript version 5. Fixes [#26203](https://github.com/cypress-io/cypress/issues/26203). - When capture protocol script fails verification, an appropriate error is now displayed. Previously, an error regarding Test Replay archive location was shown. Addressed in [#29603](https://github.com/cypress-io/cypress/pull/29603). - Fixed an issue where receiving HTTP responses with invalid headers raised an error. Now cypress removes the invalid headers and gives a warning in the console with debug mode on. Fixes [#28865](https://github.com/cypress-io/cypress/issues/28865). +- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). **Misc:** diff --git a/packages/driver/cypress/e2e/issues/29605.cy.js b/packages/driver/cypress/e2e/issues/29605.cy.js new file mode 100644 index 000000000000..c61439ea738b --- /dev/null +++ b/packages/driver/cypress/e2e/issues/29605.cy.js @@ -0,0 +1,13 @@ +// https://github.com/cypress-io/cypress/issues/29093 +describe('issue #29605', () => { + before(() => { + cy + .viewport('macbook-16') + .visit('/fixtures/issue-29605.html') + }) + + it('can click selection when display: contents width used', () => { + // cy. + cy.get('#child').should('be.visible') + }) +}) diff --git a/packages/driver/cypress/fixtures/issue-29605.html b/packages/driver/cypress/fixtures/issue-29605.html new file mode 100644 index 000000000000..b633c79e4bf1 --- /dev/null +++ b/packages/driver/cypress/fixtures/issue-29605.html @@ -0,0 +1,33 @@ + + + + + + 29093 repro + + + + +
+
+
+ + \ No newline at end of file diff --git a/packages/driver/src/dom/visibility.ts b/packages/driver/src/dom/visibility.ts index 2a92fae2b963..7f4a9d775524 100644 --- a/packages/driver/src/dom/visibility.ts +++ b/packages/driver/src/dom/visibility.ts @@ -65,7 +65,7 @@ const isStrictlyHidden = (el, methodName = 'isStrictlyHidden()', options = { che } // in Cypress-land we consider the element hidden if - // either its offsetHeight or offsetWidth is 0 because + // either its clientHeight or clientWidth is 0 because // it is impossible for the user to interact with this element if (elHasNoEffectiveWidthOrHeight($el)) { // https://github.com/cypress-io/cypress/issues/6183 @@ -121,7 +121,7 @@ const elHasNoEffectiveWidthOrHeight = ($el) => { // Is the element's CSS width OR height, including any borders, // padding, and vertical scrollbars (if rendered) less than 0? // - // elOffsetWidth: + // elClientWidth: // If the element is hidden (for example, by setting style.display // on the element or one of its ancestors to "none"), then 0 is returned. @@ -129,16 +129,22 @@ const elHasNoEffectiveWidthOrHeight = ($el) => { // For HTML elements, SVG elements that do not render anything themselves, // display:none elements, and generally any elements that are not directly rendered, // an empty list is returned. - const el = $el[0] - const style = getComputedStyle(el) - const transform = style.getPropertyValue('transform') - const width = elOffsetWidth($el) - const height = elOffsetHeight($el) - const overflowHidden = elHasOverflowHidden($el) + let transform + + if ($el[0].style.transform) { + const style = getComputedStyle(el) + + transform = style.getPropertyValue('transform') + } else { + transform = 'none' + } + + const width = elClientWidth($el) + const height = elClientHeight($el) return isZeroLengthAndTransformNone(width, height, transform) || - isZeroLengthAndOverflowHidden(width, height, overflowHidden) || + isZeroLengthAndOverflowHidden(width, height, elHasOverflowHidden($el)) || (el.getClientRects().length <= 0) } @@ -146,7 +152,7 @@ const isZeroLengthAndTransformNone = (width, height, transform) => { // From https://github.com/cypress-io/cypress/issues/5974, // we learned that when an element has non-'none' transform style value like "translate(0, 0)", // it is visible even with `height: 0` or `width: 0`. - // That's why we're checking `transform === 'none'` together with elOffsetWidth/Height. + // That's why we're checking `transform === 'none'` together with elClientWidth/Height. return (width <= 0 && transform === 'none') || (height <= 0 && transform === 'none') @@ -157,22 +163,24 @@ const isZeroLengthAndOverflowHidden = (width, height, overflowHidden) => { (height <= 0 && overflowHidden) } -const elHasNoOffsetWidthOrHeight = ($el) => { - return (elOffsetWidth($el) <= 0) || (elOffsetHeight($el) <= 0) +const elHasNoClientWidthOrHeight = ($el) => { + return (elClientWidth($el) <= 0) || (elClientHeight($el) <= 0) } -const elOffsetWidth = ($el) => { - return $el[0].offsetWidth -} +const elementBoundingRect = ($el) => $el[0].getBoundingClientRect() -const elOffsetHeight = ($el) => { - return $el[0].offsetHeight -} +const elClientHeight = ($el) => elementBoundingRect($el).height + +const elClientWidth = ($el) => elementBoundingRect($el).width const elHasVisibilityHiddenOrCollapse = ($el) => { return elHasVisibilityHidden($el) || elHasVisibilityCollapse($el) } +const elHasVisibilityVisible = ($el) => { + return $el.css('visibility') === 'visible' +} + const elHasVisibilityHidden = ($el) => { return $el.css('visibility') === 'hidden' } @@ -185,6 +193,10 @@ const elHasOpacityZero = ($el) => { return $el.css('opacity') === '0' } +const elHasDisplayContents = ($el) => { + return $el.css('display') === 'contents' +} + const elHasDisplayNone = ($el) => { return $el.css('display') === 'none' } @@ -219,6 +231,11 @@ const canClipContent = function ($el, $ancestor) { return false } + // fix for 29605 - display: contents + if (elHasDisplayContents($ancestor)) { + return false + } + // the closest parent with position relative, absolute, or fixed const $offsetParent = $el.offsetParent() @@ -308,7 +325,7 @@ const elIsNotElementFromPoint = function ($el) { return true } -const elIsOutOfBoundsOfAncestorsOverflow = function ($el, $ancestor = getParent($el)) { +const elIsOutOfBoundsOfAncestorsOverflow = function ($el: JQuery, $ancestor = getParent($el)) { // no ancestor, not out of bounds! // if we've reached the top parent, which is not a normal DOM el // then we're in bounds all the way up, return false @@ -316,27 +333,33 @@ const elIsOutOfBoundsOfAncestorsOverflow = function ($el, $ancestor = getParent( return false } + // fix for 29605 - display: contents + if (elHasDisplayContents($el)) { + return false + } + if (canClipContent($el, $ancestor)) { - const elProps = $coordinates.getElementPositioning($el) - const ancestorProps = $coordinates.getElementPositioning($ancestor) + const ancestorProps = $ancestor.get(0).getBoundingClientRect() if (elHasPositionAbsolute($el) && (ancestorProps.width === 0 || ancestorProps.height === 0)) { return elIsOutOfBoundsOfAncestorsOverflow($el, getParent($ancestor)) } + const elProps = $el.get(0).getBoundingClientRect() + // target el is out of bounds if ( // target el is to the right of the ancestor's visible area - (elProps.fromElWindow.left >= (ancestorProps.width + ancestorProps.fromElWindow.left)) || + (elProps.left >= (ancestorProps.width + ancestorProps.left)) || // target el is to the left of the ancestor's visible area - ((elProps.fromElWindow.left + elProps.width) <= ancestorProps.fromElWindow.left) || + ((elProps.left + elProps.width) <= ancestorProps.left) || // target el is under the ancestor's visible area - (elProps.fromElWindow.top >= (ancestorProps.height + ancestorProps.fromElWindow.top)) || + (elProps.top >= (ancestorProps.height + ancestorProps.top)) || // target el is above the ancestor's visible area - ((elProps.fromElWindow.top + elProps.height) <= ancestorProps.fromElWindow.top) + ((elProps.top + elProps.height) <= ancestorProps.top) ) { return true } @@ -348,7 +371,7 @@ const elIsOutOfBoundsOfAncestorsOverflow = function ($el, $ancestor = getParent( const elIsHiddenByAncestors = function ($el, checkOpacity, $origEl = $el) { // walk up to each parent until we reach the body // if any parent has opacity: 0 - // or has an effective offsetHeight of 0 + // or has an effective clientHeight of 0 // and its set overflow: hidden then our child element // is effectively hidden // -----UNLESS------ @@ -363,6 +386,12 @@ const elIsHiddenByAncestors = function ($el, checkOpacity, $origEl = $el) { return false } + if (elHasDisplayContents($el)) { + let $parent = getParent($el) + + return elIsHiddenByAncestors($parent, checkOpacity, $parent) + } + // a child can never have a computed opacity // greater than that of its parent // so if the parent has an opacity of 0, so does the child @@ -370,17 +399,21 @@ const elIsHiddenByAncestors = function ($el, checkOpacity, $origEl = $el) { return true } - if (elHasOverflowHidden($parent) && elHasNoEffectiveWidthOrHeight($parent)) { + if (elHasOverflowHidden($parent) && !elHasDisplayContents($parent) && elHasNoEffectiveWidthOrHeight($parent)) { // if any of the elements between the parent and origEl // have fixed or position absolute return !elDescendentsHavePositionFixedOrAbsolute($parent, $origEl) } + if (elHasVisibilityVisible($parent)) { + return false + } + // continue to recursively walk up the chain until we reach body or html return elIsHiddenByAncestors($parent, checkOpacity, $origEl) } -const parentHasNoOffsetWidthOrHeightAndOverflowHidden = function ($el) { +const parentHasNoClientWidthOrHeightAndOverflowHidden = function ($el: JQuery) { // if we've walked all the way up to body or html then return false if (isUndefinedOrHTMLBodyDoc($el)) { return false @@ -392,7 +425,7 @@ const parentHasNoOffsetWidthOrHeightAndOverflowHidden = function ($el) { } // continue walking - return parentHasNoOffsetWidthOrHeightAndOverflowHidden(getParent($el)) + return parentHasNoClientWidthOrHeightAndOverflowHidden(getParent($el)) } const parentHasDisplayNone = function ($el) { @@ -463,8 +496,8 @@ export const getReasonIsHidden = function ($el, options = { checkOpacity: true } // either being covered or there is no el const node = stringifyElement($el, 'short') - let width = elOffsetWidth($el) - let height = elOffsetHeight($el) + let width = elClientWidth($el) + let height = elClientHeight($el) let $parent let parentNode @@ -513,24 +546,24 @@ export const getReasonIsHidden = function ($el, options = { checkOpacity: true } return `This element \`${node}\` is not visible because its parent \`${parentNode}\` has CSS property: \`opacity: 0\`` } - if (elHasNoOffsetWidthOrHeight($el)) { - return `This element \`${node}\` is not visible because it has an effective width and height of: \`${width} x ${height}\` pixels.` - } - const transformResult = $transform.detectVisibility($el) if (transformResult === 'transformed') { return `This element \`${node}\` is not visible because it is hidden by transform.` } + if (elHasNoClientWidthOrHeight($el)) { + return `This element \`${node}\` is not visible because it has an effective width and height of: \`${width} x ${height}\` pixels.` + } + if (transformResult === 'backface') { return `This element \`${node}\` is not visible because it is rotated and its backface is hidden.` } - if ($parent = parentHasNoOffsetWidthOrHeightAndOverflowHidden(getParent($el))) { + if ($parent = parentHasNoClientWidthOrHeightAndOverflowHidden(getParent($el))) { parentNode = stringifyElement($parent, 'short') - width = elOffsetWidth($parent) - height = elOffsetHeight($parent) + let width = elClientWidth($parent) + let height = elClientHeight($parent) return `This element \`${node}\` is not visible because its parent \`${parentNode}\` has CSS property: \`overflow: hidden\` and an effective width and height of: \`${width} x ${height}\` pixels.` } From 0ce64cb4c7f59de702fa3fcdff3a2862c08e0ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Fri, 14 Jun 2024 11:54:35 +0200 Subject: [PATCH 02/14] remove visibilityVisible as non essencial --- packages/driver/src/dom/visibility.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/driver/src/dom/visibility.ts b/packages/driver/src/dom/visibility.ts index 7f4a9d775524..895016f3c1de 100644 --- a/packages/driver/src/dom/visibility.ts +++ b/packages/driver/src/dom/visibility.ts @@ -177,10 +177,6 @@ const elHasVisibilityHiddenOrCollapse = ($el) => { return elHasVisibilityHidden($el) || elHasVisibilityCollapse($el) } -const elHasVisibilityVisible = ($el) => { - return $el.css('visibility') === 'visible' -} - const elHasVisibilityHidden = ($el) => { return $el.css('visibility') === 'hidden' } @@ -405,10 +401,6 @@ const elIsHiddenByAncestors = function ($el, checkOpacity, $origEl = $el) { return !elDescendentsHavePositionFixedOrAbsolute($parent, $origEl) } - if (elHasVisibilityVisible($parent)) { - return false - } - // continue to recursively walk up the chain until we reach body or html return elIsHiddenByAncestors($parent, checkOpacity, $origEl) } From eb2a3f96db0014631d130cb0e5b0ebec5c1e36d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Thu, 27 Jun 2024 10:57:42 +0200 Subject: [PATCH 03/14] changelog for pipeline fix --- cli/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 62d2ba6255bd..af8821815706 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -11,6 +11,7 @@ _Released 7/02/2024 (PENDING)_ - Fixed an issue where Chrome launch instances would not recreate the browser CRI client correctly after recovering from an unexpected browser closure. Fixes [#27657](https://github.com/cypress-io/cypress/issues/27657). Fixed in [#29663](https://github.com/cypress-io/cypress/pull/29663). - Fixed an issue where Firefox 129 (Firefox Nightly) would not launch with Cypress. Fixes [#29713](https://github.com/cypress-io/cypress/issues/29713). Fixed in [#29720](https://github.com/cypress-io/cypress/pull/29720). +- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). **Dependency Updates:** @@ -33,7 +34,6 @@ _Released 6/18/2024_ - Fixed an issue where `inlineSourceMaps` was still being used when `sourceMaps` was provided in a users typescript config for typescript version 5. Fixes [#26203](https://github.com/cypress-io/cypress/issues/26203). - When capture protocol script fails verification, an appropriate error is now displayed. Previously, an error regarding Test Replay archive location was shown. Addressed in [#29603](https://github.com/cypress-io/cypress/pull/29603). - Fixed an issue where receiving HTTP responses with invalid headers raised an error. Now cypress removes the invalid headers and gives a warning in the console with debug mode on. Fixes [#28865](https://github.com/cypress-io/cypress/issues/28865). -- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). **Misc:** From 3dec565260267e879ed04258f90816fd1ada440d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Fri, 28 Jun 2024 11:23:47 +0200 Subject: [PATCH 04/14] fix only for firefox. It works in other browsers without this change --- packages/driver/cypress/e2e/dom/visibility.cy.ts | 11 ++++------- packages/driver/src/dom/visibility.ts | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/driver/cypress/e2e/dom/visibility.cy.ts b/packages/driver/cypress/e2e/dom/visibility.cy.ts index 5dc7495afc30..41f0b3d4f936 100644 --- a/packages/driver/cypress/e2e/dom/visibility.cy.ts +++ b/packages/driver/cypress/e2e/dom/visibility.cy.ts @@ -367,8 +367,8 @@ describe('src/cypress/dom/visibility', () => { `) this.$elOutOfParentBoundsAbove = add(`\ -
- position: absolute, out of bounds above +
+ position: absolute, out of bounds above
\ `) @@ -833,7 +833,7 @@ describe('src/cypress/dom/visibility', () => { }) it('is hidden when parent overflow hidden and out of bounds above', function () { - expect(this.$elOutOfParentBoundsAbove.find('span')).to.be.hidden + expect(this.$elOutOfParentBoundsAbove.find('span#elOutOfParentBoundsAbove')).to.be.hidden }) it('is hidden when parent overflow hidden and out of bounds below', function () { @@ -1170,10 +1170,7 @@ describe('src/cypress/dom/visibility', () => { }) it('element is fixed and being covered', function () { - this.reasonIs(this.$coveredUpPosFixed.find('#coveredUpPosFixed'), `\ -This element \`\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element: - -\`
on top
\``) + this.reasonIs(this.$coveredUpPosFixed.find('#coveredUpPosFixed'), `\This element \`\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element:\`
on top
\``) }) it('needs scroll', function () { diff --git a/packages/driver/src/dom/visibility.ts b/packages/driver/src/dom/visibility.ts index 895016f3c1de..baacbcff138f 100644 --- a/packages/driver/src/dom/visibility.ts +++ b/packages/driver/src/dom/visibility.ts @@ -567,7 +567,7 @@ export const getReasonIsHidden = function ($el, options = { checkOpacity: true } const covered = stringifyElement(elAtCenterPoint($el)) if (covered) { - return `This element \`${node}\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element:\n\n\`${covered}\`` + return `This element \`${node}\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element:\`${covered}\`` } return `This element \`${node}\` 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()\`?` From a8abbb1dec404ca5ffc86695f0b31c105c54fed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Wed, 3 Jul 2024 08:32:49 +0200 Subject: [PATCH 05/14] changelog update for pipeline --- cli/CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 3b357fcf1fe0..72ccff7fd71b 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,4 +1,12 @@ +## 13.13.1 + +_Released 7/14/2024 (PENDING)_ + +**Bugfixes:** + +- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). + ## 13.13.0 _Released 7/01/2024_ @@ -15,7 +23,6 @@ _Released 7/01/2024_ - Fixed an issue where Chrome launch instances would not recreate the browser CRI client correctly after recovering from an unexpected browser closure. Fixes [#27657](https://github.com/cypress-io/cypress/issues/27657). Fixed in [#29663](https://github.com/cypress-io/cypress/pull/29663). - Fixed an issue where Firefox 129 (Firefox Nightly) would not launch with Cypress. Fixes [#29713](https://github.com/cypress-io/cypress/issues/29713). Fixed in [#29720](https://github.com/cypress-io/cypress/pull/29720). -- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). **Dependency Updates:** From 2f6e02e5d2db6e0f493e1faa1bf697427c6b0454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Wed, 3 Jul 2024 08:40:00 +0200 Subject: [PATCH 06/14] pipeline fix --- cli/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 72ccff7fd71b..a699e77d8bc4 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,7 +1,7 @@ ## 13.13.1 -_Released 7/14/2024 (PENDING)_ +_Released 07/14/2024 (PENDING)_ **Bugfixes:** From 65ace77866163c0987d312c3aaa1b071b1ff30d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Tue, 9 Jul 2024 10:27:36 +0200 Subject: [PATCH 07/14] return of previous spacing --- packages/driver/cypress/e2e/dom/visibility.cy.ts | 2 +- packages/driver/src/dom/visibility.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/driver/cypress/e2e/dom/visibility.cy.ts b/packages/driver/cypress/e2e/dom/visibility.cy.ts index 41f0b3d4f936..011e4cc0635e 100644 --- a/packages/driver/cypress/e2e/dom/visibility.cy.ts +++ b/packages/driver/cypress/e2e/dom/visibility.cy.ts @@ -1170,7 +1170,7 @@ describe('src/cypress/dom/visibility', () => { }) it('element is fixed and being covered', function () { - this.reasonIs(this.$coveredUpPosFixed.find('#coveredUpPosFixed'), `\This element \`\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element:\`
on top
\``) + this.reasonIs(this.$coveredUpPosFixed.find('#coveredUpPosFixed'), `\This element \`\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element:\n\n\`
on top
\``) }) it('needs scroll', function () { diff --git a/packages/driver/src/dom/visibility.ts b/packages/driver/src/dom/visibility.ts index baacbcff138f..895016f3c1de 100644 --- a/packages/driver/src/dom/visibility.ts +++ b/packages/driver/src/dom/visibility.ts @@ -567,7 +567,7 @@ export const getReasonIsHidden = function ($el, options = { checkOpacity: true } const covered = stringifyElement(elAtCenterPoint($el)) if (covered) { - return `This element \`${node}\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element:\`${covered}\`` + return `This element \`${node}\` is not visible because it has CSS property: \`position: fixed\` and it's being covered by another element:\n\n\`${covered}\`` } return `This element \`${node}\` 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()\`?` From 26493c369c525b9335806738722744607cec8058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Thu, 25 Jul 2024 08:10:04 +0200 Subject: [PATCH 08/14] Update CHANGELOG.md --- cli/CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index f26eeca65865..29dc2f1116b7 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,15 +1,21 @@ +## 13.14.0 + +_Released 07/16/2024 (PENDING)_ + +**Bugfixes:** + +- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). + ## 13.13.1 _Released 7/16/2024_ -**Bugfixes:** - Fixed an issue where unhandled `WebSocket connection closed` exceptions would be thrown when CDP connections rapidly connect, disconnect, and connect again while there are pending commands. Fixes [#29572](https://github.com/cypress-io/cypress/issues/29572). - CLI output properly displays non-JSON response bodies when a Test Replay upload attempt returns a non-JSON response body for a non-200 status code. Addressed in [#29801](https://github.com/cypress-io/cypress/pull/29801). - Fixed an issue where the ReadStream used to upload a Test Replay recording could erroneously be re-used when retrying in cases of retryable upload failures. Fixes [#29227](https://github.com/cypress-io/cypress/issues/29227). - Fixed an issue where command snapshots were not being captured within the `cy.origin()` command within Test Replay. Addressed in [#29828](https://github.com/cypress-io/cypress/pull/29828). -- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). **Dependency Updates:** From 47720631d4e71115e6a5ca4b28e4d5f3ae6fc709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Mon, 30 Sep 2024 12:06:25 +0200 Subject: [PATCH 09/14] changelog without unnecessery changes --- cli/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 86dece3eb342..c934fa6832da 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -122,6 +122,7 @@ _Released 7/31/2024_ _Released 7/16/2024_ +**Bugfixes:** - Fixed an issue where unhandled `WebSocket connection closed` exceptions would be thrown when CDP connections rapidly connect, disconnect, and connect again while there are pending commands. Fixes [#29572](https://github.com/cypress-io/cypress/issues/29572). - CLI output properly displays non-JSON response bodies when a Test Replay upload attempt returns a non-JSON response body for a non-200 status code. Addressed in [#29801](https://github.com/cypress-io/cypress/pull/29801). From 229bdced9e697a548d77eceae837a86a8c63bdc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Urbanek?= Date: Wed, 30 Oct 2024 11:49:54 +0100 Subject: [PATCH 10/14] changelog fix --- cli/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 6e3a458d8c4d..34d89b2ccb03 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -7,7 +7,7 @@ _Released 12/3/2024 (PENDING)_ **Bugfixes:** -- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). +- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixed in [#29680](https://github.com/cypress-io/cypress/pull/29680).Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). - 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). - The `experimentalFetchPolyfill` configuration option was removed. This option was deprecated in Cypress 6.0.0. We recommend using `cy.intercept()` for handling fetch requests. Addressed in [#30466](https://github.com/cypress-io/cypress/pull/30466). From d2046e6294edfe3c5fd951b48e08377892871311 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 1 Nov 2024 12:36:35 -0400 Subject: [PATCH 11/14] fix changelog entry --- cli/CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 9fc3f3db68d1..8c2c06bdef72 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -5,9 +5,6 @@ _Released 12/3/2024 (PENDING)_ **Breaking Changes:** -**Bugfixes:** - -- Fixed an issue where Cypress incorrectly uses the box model of elements that have display:contents when determining visibility of child elements. Fixed in [#29680](https://github.com/cypress-io/cypress/pull/29680).Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). - 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). @@ -22,6 +19,7 @@ _Released 12/3/2024 (PENDING)_ **Bugfixes:** +- Elements with `display: contents` will no longer use box model calculations for visibility, and correctly show as visible when it is visible. Fixed in [#29680](https://github.com/cypress-io/cypress/pull/29680). Fixes [#29605](https://github.com/cypress-io/cypress/issues/29605). - The CSS pseudo-class `:dir()` is now supported when testing in Electron. Addresses [#29766](https://github.com/cypress-io/cypress/issues/29766). **Dependency Updates:** From 40ae66f01b8777de159904d190bf55ecb91ba7bb Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 1 Nov 2024 12:51:00 -0400 Subject: [PATCH 12/14] update test to properly have a test for the issue --- .../driver/cypress/e2e/issues/29605.cy.js | 9 +++---- .../driver/cypress/fixtures/issue-29605.html | 25 +++---------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/packages/driver/cypress/e2e/issues/29605.cy.js b/packages/driver/cypress/e2e/issues/29605.cy.js index c61439ea738b..c16c400fcb30 100644 --- a/packages/driver/cypress/e2e/issues/29605.cy.js +++ b/packages/driver/cypress/e2e/issues/29605.cy.js @@ -1,13 +1,10 @@ -// https://github.com/cypress-io/cypress/issues/29093 +// https://github.com/cypress-io/cypress/issues/29605 describe('issue #29605', () => { before(() => { - cy - .viewport('macbook-16') - .visit('/fixtures/issue-29605.html') + cy.visit('/fixtures/issue-29605.html') }) - it('can click selection when display: contents width used', () => { - // cy. + it('evaluates element with display: contents width as visible', () => { cy.get('#child').should('be.visible') }) }) diff --git a/packages/driver/cypress/fixtures/issue-29605.html b/packages/driver/cypress/fixtures/issue-29605.html index b633c79e4bf1..2c520ead870b 100644 --- a/packages/driver/cypress/fixtures/issue-29605.html +++ b/packages/driver/cypress/fixtures/issue-29605.html @@ -1,32 +1,13 @@ - + - 29093 repro - + 29605 repro -
+
From 7b48a6c004b68dd8bb8c0bed225a0922335ced79 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 1 Nov 2024 13:20:43 -0400 Subject: [PATCH 13/14] add test for other elements to not be visible --- packages/driver/cypress/e2e/issues/29605.cy.js | 13 ++++++++++--- packages/driver/cypress/fixtures/issue-29605.html | 6 ++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/driver/cypress/e2e/issues/29605.cy.js b/packages/driver/cypress/e2e/issues/29605.cy.js index c16c400fcb30..bab93b3aa42c 100644 --- a/packages/driver/cypress/e2e/issues/29605.cy.js +++ b/packages/driver/cypress/e2e/issues/29605.cy.js @@ -1,10 +1,17 @@ // https://github.com/cypress-io/cypress/issues/29605 -describe('issue #29605', () => { - before(() => { +describe('issue #29605 - els with display: contents', () => { + beforeEach(() => { cy.visit('/fixtures/issue-29605.html') }) - it('evaluates element with display: contents width as visible', () => { + it('children of parent with no width/height are visible', () => { + cy.get('#parent').should('not.be.visible') cy.get('#child').should('be.visible') }) + + // https://drafts.csswg.org/css-display/#unbox + it('not rendered by CSS box concept are not visible', () => { + cy.get('#input').should('not.be.visible') + cy.get('#select').should('not.be.visible') + }) }) diff --git a/packages/driver/cypress/fixtures/issue-29605.html b/packages/driver/cypress/fixtures/issue-29605.html index 2c520ead870b..9b79d0173ab4 100644 --- a/packages/driver/cypress/fixtures/issue-29605.html +++ b/packages/driver/cypress/fixtures/issue-29605.html @@ -10,5 +10,11 @@
+ + \ No newline at end of file From fe6d1e442b9a80c6ece8a665212313694b07c090 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 1 Nov 2024 14:17:50 -0400 Subject: [PATCH 14/14] bump cache --- .circleci/cache-version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/cache-version.txt b/.circleci/cache-version.txt index 566df802ad66..5551685a4f4a 100644 --- a/.circleci/cache-version.txt +++ b/.circleci/cache-version.txt @@ -1,3 +1,3 @@ # Bump this version to force CI to re-create the cache from scratch. -10-30-24-wds-3-removal +11-1-24