-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
base: develop
Are you sure you want to change the base?
The head ref may contain hidden characters: "issue-29093-fix-Visible-elements-are-\"not-visible\"-for-Cypress"
Changes from 18 commits
8b1182f
da6825f
f4278d0
7d08741
cc86762
cf5353a
c2e4f99
bd82c5d
b5c97d7
bbeb1bb
6d48369
71cdb93
f85f307
b15254c
0e52c90
55ac75f
8ef291b
47d2948
9d84c25
2a4d554
347ca9e
5d57f92
4ad8136
f484c50
7912583
0fcc3ea
537176c
d13e552
044d3ec
2d85cb3
2842d5e
1d7d9ab
023646b
8dc2777
92629ad
89dedb4
61749d7
03f07cb
ec3f9ab
1d9a335
5c57aed
5ac6fe5
f8d4b3e
ad39a62
8371a99
82a4058
bc2f850
2a423cb
9f288ad
4612dc1
606ca75
7aac0f9
be84785
aa659ee
050ff5f
35022fc
f3b4081
c13d19c
fc85dd5
d423dfc
6073f20
8e49f91
07b50b5
0ada697
85dbb8a
f94e28e
a1133a2
47dfcf2
a5ad454
b281e84
461e6e7
46f5105
c670a8e
03bc284
0d0d984
e791a7b
eb598ee
52be351
7082a6b
04efcf5
5a279d8
95c624c
093c8e0
98c56de
09fe08f
53c7242
3862c48
bf76534
bcea9bd
cad469d
58f2e9d
7cf025a
d6ad12d
9561099
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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() | ||
}) | ||
}) |
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 | ||
} | ||
|
||
.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> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) => { | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Each call to There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) => { | ||
|
@@ -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) => { | ||
|
@@ -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) { | ||
|
@@ -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 | ||
} | ||
} | ||
} | ||
|
||
|
@@ -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 | ||
|
||
|
@@ -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.` | ||
} | ||
|
||
|
@@ -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.` | ||
} | ||
|
There was a problem hiding this comment.
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.There was a problem hiding this comment.
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.