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

Element (position: fixed) should not be considered hidden if covered up by a non-hidden element #21164

Open
ryancrunchi opened this issue Apr 21, 2022 · 7 comments

Comments

@ryancrunchi
Copy link

ryancrunchi commented Apr 21, 2022

Current behavior

Given that we have an element, identified by menu, that is position: fixed
And there is a modal container element, identified by modal, covering entire screen (position: absolute; width: 100vw; height: 100vh) but currently closed (or hidden, either opacity: 0 or visibility: hidden or display: none)
Then running test cy.get('menu').should('be.visible') throws an error

This element <div#menu> is not visible because it has CSS property: position: fixed and it's being covered by another element:

<div id="modal" style="opacity: 0">

This is ok according to the cypress spec and doc saying :

An element is considered hidden if its CSS property is position: fixed and it's offscreen or covered up

Desired behavior

I find this spec misses an important check, that should be :

An element is considered hidden if its CSS property is position: fixed and it's offscreen or covered up by a non-hidden element

In my case the modal is not opened (hidden). The browser itself let me interact with the menu, so cypress should "see" the same and say that this menu is visible.

Test code to reproduce

Here is a codesandbox link to small react app showing this case : https://codesandbox.io/s/bold-darwin-5rgt6f
I was not able to make cypress run on it, but the idea is there.

Cypress Version

9.5.0

Other

Actually, in production we use Material UI with a Modal component having keepMounted: true for custom animation reason: https://mui.com/material-ui/api/modal/

We have this left side menu with position: fixed in the main content of the page, and a right side content scrolling, as shown in codesandbox.

So, the modal is always in DOM, even when it's closed (due to keepMounted: true), on top of anything and detached from the main content (position: absolute, z-index: 1000, fullscreen etc...). The only thing that makes it hidden is opacity: 0 and/or visibility: hidden

Due to this current cypress specification, we are unable to write a test to assert that the side menu is visible. Cypress believes that the modal covers everything. No matter if it's open or closed (visible or hidden).

Related : #19204

@davidmunechika davidmunechika changed the title Visibility check Element (position: fixed) should not be considered hidden if covered up by a non-hidden element Apr 21, 2022
@scorpyto
Copy link

scorpyto commented Mar 8, 2023

any solution?

@scorpyto
Copy link

It is from April 21 2022, come on...not a solution yet????

@lmiller1990
Copy link
Contributor

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jun 30, 2023

This seems correct though - see my example. Sure, the is visible - but it cannot be interacted with. If you cover the menu with an element with opacity: 0 - it looks like you can click the element, but you cannot.

Seems the real fix is to update the documentation to clarify that if an element is covered by another one, even a transparent one, it won't be considered visible? Definitely the word "visible" is misleading, it implies "I can see and do stuff with it.

I suspect implementing the requested check is not the most practical thing to do, either -- I think we should just document this caveat in the Cypress docs, update the error Cypress shows, and move on. Thoughts?

@scorpyto
Copy link

This seems correct though - see my example. Sure, the is visible - but it cannot be interacted with. If you cover the menu with an element with opacity: 0 - it looks like you can click the element, but you cannot.

Seems the real fix is to update the documentation to clarify that if an element is covered by another one, even a transparent one, it won't be considered visible? Definitely the word "visible" is misleading, it implies "I can see and do stuff with it.

I suspect implementing the requested check is not the most practical thing to do, either -- I think we should just document this caveat in the Cypress docs, update the error Cypress shows, and move on. Thoughts?

Well, sometimes I just want to verify as a user that I can see a certain element/text/column etc. I don't really care if I can interact with it (there are the so called "real events" for that purpose). So when the covering element is transparent you can see still the element below which means it is visible and I would like that to be the expected behaviour....

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jul 4, 2023

Right now 'is.visible' this uses the 'visible' assertion from chai-dom. It works okay, but as pointed out here, it's not full proof. It does:

Assert that the HTMLElement is visible (that visibility is not equal to “hidden” or “collapse”). If the element is attached to the body, it will call getComputedStyle; otherwise it will look at the inline visibility attribute.

Users looking for a true isVisible in the sense described here could try the new checkVisibility() API. It works in recent versions of Chrome and Firefox.

I tried this using a custom command:

Cypress.Commands.add('shouldBeVisible', { prevSubject: true },  function (element) {
  expect(element[0].checkVisibility()).to.be.true
})

It doesn't seem to do what you'd expect. I also can't find any documentation on MDN. I could be doing it wrong, or misunderstanding this API. It only works in newer versions, so we can't adopt it in Cypress core at this point, since we support as far back as Chrome 64.

I did some research on this problem. I cannot find any reliable way to determine if something is visible using JavaScript that covers all edge cases.

If someone has a bullet proof, reliable solution, please share it, but I suspect this is a non trivial problem. Right now, I'd recommend using a visual regression test, either using a screenshot to doing a comparison (eg cy.screenshot(), there are a number of plugins to facilitate this) or a service like Percy.

@senpl
Copy link

senpl commented Jul 1, 2024

Partially fixed in #29741 . Still fixing it for parents would require many test rewrite and is not easy to implement. Anyway without simple to run reproduction it will not be fixed fast.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants