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: #29093 for elements with length in rem #29224

Open
wants to merge 94 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
8b1182f
first working version
senpl Mar 29, 2024
da6825f
clean commented code
senpl Mar 29, 2024
f4278d0
clean
senpl Mar 29, 2024
7d08741
changelog update
senpl Mar 29, 2024
cc86762
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Mar 29, 2024
cf5353a
Merge branch 'issue-29093-fix-Visible-elements-are-"not-visible"-for-…
senpl Mar 29, 2024
c2e4f99
Merge pull request #2 from senpl/#29093-fix
senpl Mar 29, 2024
bd82c5d
fix pipeline bug
senpl Mar 29, 2024
b5c97d7
Merge pull request #3 from senpl/#29093-fix
senpl Mar 29, 2024
bbeb1bb
fix pipeline for line2
senpl Mar 29, 2024
6d48369
Merge pull request #4 from senpl/#29093-fix
senpl Mar 29, 2024
71cdb93
fix pipeline3
senpl Mar 29, 2024
f85f307
Merge pull request #5 from senpl/#29093-fix
senpl Mar 29, 2024
b15254c
error reproduction
senpl Apr 2, 2024
0e52c90
go back to previous commend for tests
senpl Apr 2, 2024
55ac75f
Merge pull request #6 from senpl/#29093-fix
senpl Apr 2, 2024
8ef291b
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 3, 2024
47d2948
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 11, 2024
9d84c25
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 11, 2024
2a4d554
fix changelog
jennifer-shehane Apr 11, 2024
347ca9e
fix for test that catched not correct span
senpl Apr 12, 2024
5d57f92
fix for visibility compatible backward
senpl Apr 14, 2024
4ad8136
tests pass without this check so probably not needed
senpl Apr 14, 2024
f484c50
only cleanup to take less on screen and be more visible
senpl Apr 14, 2024
7912583
Merge pull request #8 from senpl/#29093-fix
senpl Apr 14, 2024
0fcc3ea
fix for 28638
senpl Apr 14, 2024
537176c
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Apr 14, 2024
d13e552
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Apr 16, 2024
044d3ec
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 16, 2024
2d85cb3
adding id to make easier to find searched element
senpl Apr 17, 2024
2842d5e
visibility tests pass
senpl Apr 17, 2024
1d7d9ab
final fix for 29093
senpl Apr 17, 2024
023646b
general cleanup and comments update
senpl Apr 17, 2024
8dc2777
Merge pull request #10 from senpl/#29093-fix
senpl Apr 17, 2024
92629ad
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Apr 18, 2024
89dedb4
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 18, 2024
61749d7
not using jquery for this check
senpl Apr 19, 2024
03f07cb
Merge pull request #11 from senpl/#29093-fix
senpl Apr 19, 2024
ec3f9ab
another potential speed improvement
senpl Apr 19, 2024
1d9a335
Merge pull request #12 from senpl/#29093-fix
senpl Apr 19, 2024
5c57aed
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 19, 2024
5ac6fe5
Update cli/CHANGELOG.md
jennifer-shehane Apr 19, 2024
f8d4b3e
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Apr 19, 2024
ad39a62
speed improvements for ci
senpl Apr 20, 2024
8371a99
Merge pull request #13 from senpl/#29093-fix
senpl Apr 20, 2024
82a4058
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 22, 2024
bc2f850
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Apr 23, 2024
2a423cb
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 23, 2024
9f288ad
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Apr 24, 2024
4612dc1
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Apr 25, 2024
606ca75
Update changelog entry
jennifer-shehane Apr 25, 2024
7aac0f9
add pending to changelog
jennifer-shehane Apr 25, 2024
be84785
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl May 1, 2024
aa659ee
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane May 2, 2024
050ff5f
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane May 2, 2024
35022fc
filerow test fix
senpl May 7, 2024
f3b4081
make width and haight visible in fleaky test
senpl May 7, 2024
c13d19c
Merge pull request #16 from senpl/#29093-fix
senpl May 7, 2024
fc85dd5
mocha added to launchpad package
senpl May 8, 2024
d423dfc
Merge pull request #17 from senpl/#29093-fix
senpl May 8, 2024
6073f20
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl May 8, 2024
8e49f91
Update CHANGELOG.md
senpl May 8, 2024
07b50b5
Update CHANGELOG.md
senpl May 8, 2024
0ada697
Update CHANGELOG.md
senpl May 8, 2024
85dbb8a
Update CHANGELOG.md
senpl May 8, 2024
f94e28e
make pipeline view visible
senpl May 9, 2024
a1133a2
Merge pull request #18 from senpl/#29093-fix
senpl May 9, 2024
47dfcf2
out of bound fix
senpl May 9, 2024
a5ad454
Merge pull request #19 from senpl/#29093-fix
senpl May 9, 2024
b281e84
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane May 10, 2024
461e6e7
Remove old changelog entry
jennifer-shehane May 10, 2024
46f5105
another changelog fix
jennifer-shehane May 10, 2024
c670a8e
fix for existing test
senpl May 13, 2024
03bc284
Merge pull request #20 from senpl/#29093-fix
senpl May 13, 2024
0d0d984
kitchensink fix
senpl May 13, 2024
e791a7b
Merge pull request #21 from senpl/#29093-fix
senpl May 13, 2024
eb598ee
go back to previously working
senpl May 13, 2024
52be351
Merge pull request #22 from senpl/#29093-fix
senpl May 13, 2024
7082a6b
pipeline speed improvement
senpl May 13, 2024
04efcf5
Merge pull request #23 from senpl/#29093-fix
senpl May 13, 2024
5a279d8
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl May 15, 2024
95c624c
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl May 16, 2024
093c8e0
id for precise locator gind
senpl May 22, 2024
98c56de
Merge pull request #24 from senpl/#29093-fix
senpl May 22, 2024
09fe08f
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl May 22, 2024
53c7242
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
jennifer-shehane Jun 3, 2024
3862c48
removed unussed id
senpl Jun 4, 2024
bf76534
display contents fix
senpl Jun 4, 2024
bcea9bd
additional tests
senpl Jun 4, 2024
cad469d
move to correct place in canClip
senpl Jun 4, 2024
58f2e9d
28638 in correct place
senpl Jun 4, 2024
7cf025a
readability and performance improvements
senpl Jun 4, 2024
d6ad12d
Merge pull request #25 from senpl/#29093-fix
senpl Jun 4, 2024
9561099
Merge branch 'develop' into issue-29093-fix-Visible-elements-are-"not…
senpl Jun 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

_Released 4/16/2024 (PENDING)_

**Bugfixes:**

- Fixed an issue where Cypress not detect visible elements with width or height in rem as visible [#29172](https://github.com/cypress-io/cypress/issues/29093). Fixed in [#29224](https://github.com/cypress-io/cypress/pull/29224).

**Misc:**

- Updated the Chrome flags to not show the "Enhanced Ad Privacy" dialog. Addresses [#29199](https://github.com/cypress-io/cypress/issues/29199).
Expand Down
12 changes: 12 additions & 0 deletions packages/driver/cypress/e2e/issues/29093.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// https://github.com/cypress-io/cypress/issues/29093
describe('issue 29093', () => {
before(() => {
cy
.viewport('macbook-16')
.visit('/fixtures/issue-29093.html')
})

it('can click selection when rem width used', () => {
cy.get('#sidebar-left > section').click()
})
})
37 changes: 37 additions & 0 deletions packages/driver/cypress/fixtures/issue-29093.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en" class="dark">

<head>
<meta charset="utf-8" />
<title>29093 repro</title>
<style id="compiled-css" type="text/css">
.big {
font-size: 128px;
}

.contents {
display: contents
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what is causing Cypress to not properly determine that #sidebar-left is not hidden in the fixture. display: contents causes the element to not generate its own box, which prevents overflow:hidden from being applied as expected - the element is effectively replaced by its children, and its box model (and overflow settings) should be disregarded. See: https://drafts.csswg.org/css-display/#valdef-display-contents.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true. Check moved to canClip.

}

.overflow-hidden {
overflow: hidden
}

@media (min-width: 1024px) {
.lg\:grid {
display: grid
}
}
</style>
</head>

<body>
<div class="overflow-hidden contents">
<aside id="sidebar-left" class="lg:w-auto">
<section class="b-4">
<p class="big">IN SECTION</p>
</section>
</aside>
</div>
</body>
</html>
90 changes: 51 additions & 39 deletions packages/driver/src/dom/visibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ const elHasNoEffectiveWidthOrHeight = ($el) => {
const el = $el[0]
const style = getComputedStyle(el)
const transform = style.getPropertyValue('transform')
const width = elOffsetWidth($el)
const height = elOffsetHeight($el)
const width = elClientWidth($el)
const height = elClientHeight($el)
const overflowHidden = elHasOverflowHidden($el)

return isZeroLengthAndTransformNone(width, height, transform) ||
isZeroLengthAndOverflowHidden(width, height, overflowHidden) ||
(el.getClientRects().length <= 0)
isZeroLengthAndOverflowHidden(width, height, overflowHidden) ||
(el.getClientRects().length <= 0)
}

const isZeroLengthAndTransformNone = (width, height, transform) => {
Expand All @@ -149,24 +149,24 @@ const isZeroLengthAndTransformNone = (width, height, transform) => {
// That's why we're checking `transform === 'none'` together with elOffsetWidth/Height.

return (width <= 0 && transform === 'none') ||
(height <= 0 && transform === 'none')
(height <= 0 && transform === 'none')
}

const isZeroLengthAndOverflowHidden = (width, height, overflowHidden) => {
return (width <= 0 && overflowHidden) ||
(height <= 0 && overflowHidden)
(height <= 0 && overflowHidden)
}

const elHasNoOffsetWidthOrHeight = ($el) => {
return (elOffsetWidth($el) <= 0) || (elOffsetHeight($el) <= 0)
const elClientWidth = ($el) => {
return $el[0].getBoundingClientRect().width
}

const elOffsetWidth = ($el) => {
return $el[0].offsetWidth
const elClientHeight = ($el) => {
return $el[0].getBoundingClientRect().height
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each call to .getBoundingClientRect() forces a layout/reflow of the browser. Calling this many times for each element/ancestor comparison in a complicated DOM may cause performance issues.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed into function. So result could be stored.

}

const elOffsetHeight = ($el) => {
return $el[0].offsetHeight
const elHasNoClientWidthOrHeight = ($el) => {
return (elClientWidth($el) <= 0) || (elClientHeight($el) <= 0)
}

const elHasVisibilityHiddenOrCollapse = ($el) => {
Expand All @@ -193,10 +193,20 @@ const elHasDisplayInline = ($el) => {
return $el.css('display') === 'inline'
}

const elHasOverflowHidden = function ($el) {
const cssOverflow = [$el.css('overflow'), $el.css('overflow-y'), $el.css('overflow-x')]
const elHasOverflowHidden = function ($el: JQuery<HTMLElement>) {
let styles = getComputedStyle($el[0])

return cssOverflow.includes('hidden')
if (styles.getPropertyValue('grid')) { //we ignore hidden when grid used
return false
}

if (styles.getPropertyValue('overflow') === 'hidden'
|| styles.getPropertyValue('overflow-y') === 'hidden'
|| styles.getPropertyValue('overflow-x') === 'hidden') {
return true
}

return false
}

const elHasPositionRelative = ($el) => {
Expand All @@ -209,8 +219,8 @@ const elHasPositionAbsolute = ($el) => {

const elHasClippableOverflow = function ($el) {
return OVERFLOW_PROPS.includes($el.css('overflow')) ||
OVERFLOW_PROPS.includes($el.css('overflow-y')) ||
OVERFLOW_PROPS.includes($el.css('overflow-x'))
OVERFLOW_PROPS.includes($el.css('overflow-y')) ||
OVERFLOW_PROPS.includes($el.css('overflow-x'))
}

const canClipContent = function ($el, $ancestor) {
Expand Down Expand Up @@ -317,28 +327,30 @@ const elIsOutOfBoundsOfAncestorsOverflow = function ($el, $ancestor = getParent(
}

if (canClipContent($el, $ancestor)) {
const elProps = $coordinates.getElementPositioning($el)
const ancestorProps = $coordinates.getElementPositioning($ancestor)
if ($el[0] instanceof DOMRect && $ancestor[0] instanceof DOMRect) {
const elProp = $el.getBoundingClientRect()
const ancestorProp = $ancestor[0].getBoundingClientRect()

if (elHasPositionAbsolute($el) && (ancestorProps.width === 0 || ancestorProps.height === 0)) {
return elIsOutOfBoundsOfAncestorsOverflow($el, getParent($ancestor))
}
if (elHasPositionAbsolute($el) && (ancestorProp.width === 0 || ancestorProp.height === 0)) {
return elIsOutOfBoundsOfAncestorsOverflow($el, getParent($ancestor))
}

// 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)) ||
// target el is out of bounds
if (
// target el is to the right of the ancestor's visible area
(elProp.left >= (ancestorProp.width + ancestorProp.left)) ||

// target el is to the left of the ancestor's visible area
((elProps.fromElWindow.left + elProps.width) <= ancestorProps.fromElWindow.left) ||
// target el is to the left of the ancestor's visible area
((elProp.left + elProp.width) <= ancestorProp.left) ||

// target el is under the ancestor's visible area
(elProps.fromElWindow.top >= (ancestorProps.height + ancestorProps.fromElWindow.top)) ||
// target el is under the ancestor's visible area
(elProp.top >= (ancestorProp.height + ancestorProp.top)) ||

// target el is above the ancestor's visible area
((elProps.fromElWindow.top + elProps.height) <= ancestorProps.fromElWindow.top)
) {
return true
// target el is above the ancestor's visible area
((elProp.top + elProp.height) <= ancestorProp.top)
) {
return true
}
}
}

Expand Down Expand Up @@ -463,8 +475,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

Expand Down Expand Up @@ -513,7 +525,7 @@ 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)) {
if (elHasNoClientWidthOrHeight($el)) {
return `This element \`${node}\` is not visible because it has an effective width and height of: \`${width} x ${height}\` pixels.`
}

Expand All @@ -529,8 +541,8 @@ export const getReasonIsHidden = function ($el, options = { checkOpacity: true }

if ($parent = parentHasNoOffsetWidthOrHeightAndOverflowHidden(getParent($el))) {
parentNode = stringifyElement($parent, 'short')
width = elOffsetWidth($parent)
height = elOffsetHeight($parent)
width = elClientWidth($parent)
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.`
}
Expand Down