Cypress: Elements hidden using clip / clip-path css properties pass as visible

Created on 10 Jan 2018  路  4Comments  路  Source: cypress-io/cypress

Current behavior:

Elements hidden using the CSS clip / clip-path properties pass visibility check.

Desired behavior:

Visibility checks should fail as the element isn't visible.

How to reproduce:

Hide any element using CSS clip / clip-path properties and define a test to check if it's visible. Test passes.

Test code:

<div style="position: absolute;clip: rect(1px,1px,1px,1px);">
    <a href="#test">clip</a>
</div>

<div style="position: absolute;clip-path: polygon(0px 0px, 0px 0px, 0px 0px, 0px 0px);">
    <a href="#test">clip-path</a>
</div>
describe('Clipped links', function () {
  it('should not be visible', function () {
    cy.visit('127.0.0.1')

    cy.get('a').should('be', 'vivible')
  })
})

Additional Info (images, stack traces, etc)

While clip is deprecated clip-path is not. Unfortunately however clip is still used and supported so for the time being at least I think it should make visibility checks fail.

  • Operating System: Windows 10 Enterprise
  • Cypress Version: 1.4.1
  • Browser Version: Chrome Version 63.0.3239.132

鈹咺ssue is synchronized with this Jira Bug by Unito

pkdriver wontfix visibility 馃憗 bug

All 4 comments

Our calculations for visibility can be found here if anyone wants to contribute: https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/dom/visibility.js

The original test chainers were written incorrectly in the original comment, but nonetheless this is an error demonstrated below. You can clearly not see the elements on the page, but Cypress passes saying they are visible and fails when asserting they are not visible.

index.html

<html>
<body>
  <div style="position: absolute; clip: rect(1px, 1px, 1px, 1px);">
    <span id="clip">clip</span>
  </div>
  <div style="position: absolute; clip-path: polygon(0 0, 0 0, 0 0, 0 0);">
    <span id="clip-path">clip-path</span>
  </div>
</body>
</html>

spec file

it('should not be visible', () => {
  cy.visit('index.html')
  cy.get('#clip').should('not.be.visible')  // fails but should pass
})

it('should not be visible', () => {
  cy.visit('index.html')
  cy.get('#clip-path').should('not.be.visible') // fails but should pass
})

Screen Shot 2020-07-07 at 2 11 02 PM

clip DEPRECATED

The clip CSS property defines what portion of an element is visible. The clip property applies only to absolutely positioned elements, that is elements with position:absolute or position:fixed.

clip-path

The clip-path CSS property creates a clipping region that sets what part of an element should be shown. Parts that are inside the region are shown, while those outside are hidden.

Honestly, I cannot guarantee that we will support testing of clip, as adding support for deprecated properties is not something we generally do - especially since just at a cursory glance, I think supporting this will take a good amount of effort to calculate correctly.

~I've added a failing test for clip-path to this PR: https://github.com/cypress-io/cypress/pull/4421~

This is still incorrectly failing in Cypress 4.9.0.

After investigating this issue for quite a while, I recommend that we either de-prioritize it or close as won't fix. This issue has been open for around a year and a half now, and has no upvotes (compared to other more-requested fixes, which all have at least a couple).

In addition, the fix is quite difficult technically. For starters, there's no way to easily get the dimensions of the clipping. The process would have to entail converting the clip-path to an svg, for which there is currently no standard library, so we would have to parse the value ourselves and convert that into a svg element. Next, we would have to see if that svg actually overlaps the underlying content, which we could do through checkIntersection or getIntersectionList, but neither are supported in Firefox.

A different potential solution would be assigning an on click handler, which would only be executed when the underlying element was actually clicked on. However, there is no guarantee of what part of the element would be exposed. For efficiency, we could test the center, then each of the corners, and then just each pixel linearly, but there is still the case that we might have to click on every single possible pixel. Plus, all those clicks could change the state of the underlying application. With that said, I can't see a solution that is efficient, viable, and flake free and this issue should be de-prioritized.

(Selenium does visibility checking in a similar way to us, and does not handle clip-path at all, nor has had any issues created about it).

Was this page helpful?
0 / 5 - 0 ratings