In GitHub issue #9378 the user submitted a reproducible example of a failing test. Cypress fails the test when the clearly visible "Cypress is amazing!" element is deemed NOT to be visible.
In the video below I show how to debug the visibility problem. This is a general approach anyone can take when encountering such error. Or you can continue reading this blog post.
Pause and debug
Cypress v6 uses the function Cypress.dom.isVisible to determine if an element is visible during the test. In order to hit this function so we can step through it we need to pause the test using cy.pause, open the DevTools, and tell the browser to break when the function is executed.
cy.wait(5000); // Just to make sure everything is loaded.
Then open the DevTools console and enter
Click the "Resume" button in Cypress and see how the debugger automatically breaks on
Now you can use the DevTools debugger to step through the Cypress internal code to see where the visibility logic goes wrong (or not).
Tip: to stop debugging the visibility function execute
undebug(Cypress.dom.isVisible) in the DevTools console.
Use any element
Another alternative is to let the test finish (and fail), then open the DevTools Elements panel, and find the element you want to check visibility for. In our case, it is this element, highlighted by the DevTools
Notice that right above that element is the
<video> element that Cypress says covers our "Cypress is amazing!" element. When you hover over that
<video> element it kind of looks like it does cover the entire viewport.
We can pick an element and call
Cypress.dom.isVisible(el) ourselves, right from the DevTools, outside the test. When you select an element in the Elements panel, the DevTools points at it using a special variable
$0. Just call the visibility function and pass
$0 as shown below.
Now click on the
<video> element and inspect its properties. Maybe you can modify one of them and then run
isVisible($0) again to see if it changes to
true? For example, the
display: none on the element itself is ignored by the browser because the more general CSS style has
display: block !important set.
Is this intentional? Seems weird. Let's add the
!important to the element itself to make sure its own display property is respected.
As you can see, after we change the
display property on the element itself, the text is now considered visible.
Tip: while we are changing the
<video> element's properties it gets
$0 variable. The previously selected element with "Cypress is amazing!" automatically gets the special
$1 variable which we used above.
Finally, let's see if this is really the video element when it is visible that covers our text - even if the video is not playing. Let's change its height from 100% to 80% and check the visibility again.
So it seems the
<video> element is really considered to cover everything - but of course you need to actually step through the
Cypress.dom.isVisible code to figure out the precise details.