diff --git a/packages/driver/cypress/e2e/dom/visibility.cy.ts b/packages/driver/cypress/e2e/dom/visibility.cy.ts index 5dc7495afc30..2144c3f6aaa8 100644 --- a/packages/driver/cypress/e2e/dom/visibility.cy.ts +++ b/packages/driver/cypress/e2e/dom/visibility.cy.ts @@ -258,7 +258,7 @@ describe('src/cypress/dom/visibility', () => { this.$parentNoWidthHeightOverflowAuto = add(`\
- parent no size, overflow: auto + parent no size, overflow: auto
`) this.$parentWithWidthHeightNoOverflow = add(`\ @@ -733,8 +733,8 @@ describe('src/cypress/dom/visibility', () => { }) 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.$parentNoWidth.find('#parentNoWidth')).to.be.hidden + expect(this.$parentNoWidth.find('#parentNoWidth')).to.not.be.visible }) it('is hidden if parent has overflow: hidden and no height', function () { diff --git a/packages/driver/src/dom/visibility.ts b/packages/driver/src/dom/visibility.ts index 45e2f86248cb..1464f4284d8c 100644 --- a/packages/driver/src/dom/visibility.ts +++ b/packages/driver/src/dom/visibility.ts @@ -133,8 +133,8 @@ const elHasNoEffectiveWidthOrHeight = ($el) => { const el = $el[0] const style = getComputedStyle(el) const transform = style.getPropertyValue('transform') - const width = elClientWidth($el) - const height = elClientHeight($el) + const width = elOffsetWidth($el) + const height = elOffsetHeight($el) const overflowHidden = elHasOverflowHidden($el) return isZeroLengthAndTransformNone(width, height, transform) || @@ -157,16 +157,24 @@ const isZeroLengthAndOverflowHidden = (width, height, overflowHidden) => { (height <= 0 && overflowHidden) } +const elHasNoClientWidthOrHeight = ($el) => { + return (elClientWidth($el) <= 0) || (elClientHeight($el) <= 0) +} + +const elOffsetWidth = ($el) => { + return $el[0].offsetWidth +} + const elClientWidth = ($el) => { return $el[0].getBoundingClientRect().width } -const elClientHeight = ($el) => { - return $el[0].getBoundingClientRect().height +const elOffsetHeight = ($el) => { + return $el[0].offsetHeight } -const elHasNoClientWidthOrHeight = ($el) => { - return (elClientWidth($el) <= 0) || (elClientHeight($el) <= 0) +const elClientHeight = ($el) => { + return $el[0].getBoundingClientRect().height } const elHasVisibilityHiddenOrCollapse = ($el) => { @@ -185,6 +193,10 @@ const elHasOpacityZero = ($el) => { return $el.css('opacity') === '0' } +const elHasBlockStyle = ($el) => { + return $el.css('display') === 'block' || $el.css('display') === 'inline-block' +} + const elHasDisplayNone = ($el) => { return $el.css('display') === 'none' } @@ -327,30 +339,28 @@ const elIsOutOfBoundsOfAncestorsOverflow = function ($el, $ancestor = getParent( } if (canClipContent($el, $ancestor)) { - if ($el[0] instanceof DOMRect && $ancestor[0] instanceof DOMRect) { - const elProp = $el.getBoundingClientRect() - const ancestorProp = $ancestor[0].getBoundingClientRect() + const el: HTMLElement = $jquery.isJquery($el) ? $el[0] : $el + const elProps = el.getBoundingClientRect() + const ancestorProps = $jquery.isJquery($ancestor) ? $ancestor[0].getBoundingClientRect() : $ancestor.get(0).getBoundingClientRect() - if (elHasPositionAbsolute($el) && (ancestorProp.width === 0 || ancestorProp.height === 0)) { - return elIsOutOfBoundsOfAncestorsOverflow($el, getParent($ancestor)) - } + if ((elHasPositionAbsolute($el) || elHasBlockStyle($el)) && (ancestorProps.width === 0 || ancestorProps.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 - (elProp.left >= (ancestorProp.width + ancestorProp.left)) || + if ( + // target el is to the right of the ancestor's visible area + (elProps.left >= (ancestorProps.width + ancestorProps.left)) || - // target el is to the left of the ancestor's visible area - ((elProp.left + elProp.width) <= ancestorProp.left) || + // target el is to the left of the ancestor's visible area + ((elProps.left + elProps.width) <= ancestorProps.left) || - // target el is under the ancestor's visible area - (elProp.top >= (ancestorProp.height + ancestorProp.top)) || + // target el is under the ancestor's visible area + (elProps.top >= (ancestorProps.height + ancestorProps.top)) || - // target el is above the ancestor's visible area - ((elProp.top + elProp.height) <= ancestorProp.top) - ) { - return true - } + // target el is above the ancestor's visible area + ((elProps.top + elProps.height) <= ancestorProps.top) + ) { + return true } } @@ -541,8 +551,8 @@ export const getReasonIsHidden = function ($el, options = { checkOpacity: true } if ($parent = parentHasNoOffsetWidthOrHeightAndOverflowHidden(getParent($el))) { parentNode = stringifyElement($parent, 'short') - width = elClientWidth($parent) - height = elClientHeight($parent) + width = elOffsetWidth($parent) + height = elOffsetHeight($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.` }