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

Elements hidden using clip / clip-path css properties pass as visible #1178

Closed
y2keeper opened this issue Jan 10, 2018 · 7 comments
Closed
Assignees
Labels
pkg/driver This is due to an issue in the packages/driver directory stage: wontfix Cypress does not regard this as an issue or will not implement this feature topic: visibility 👁 type: bug

Comments

@y2keeper
Copy link

y2keeper commented Jan 10, 2018

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

┆Issue is synchronized with this Jira Bug by Unito

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Jan 10, 2018

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

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Jun 11, 2019

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: #4421

jennifer-shehane added a commit that referenced this issue Jun 19, 2019
* Add failing test case for visible element within overflow hidden then position absolute element.

Addresses #4395

* Write failing test case for when parent is flex and overflow hidden with el outside bounds

Addresses #4161

* Wrote failing test for visibility outside of clip-path

Addresses #1178

* Add failing tests for transform scale

Addresses #723

* Add failing test for backfact-visibility hidden example

* cs -> js fixes

* Add more specific error when el is not element

* Always return as visible when checking html or body

* Add comments + rename methods to be more exact

* Add case for isHidden when visibility is collapse

* Add failing test cases for visibility issues

* Add comment about how ensureVisibility works under the hood

* Add checks and tests for opacity: 0 to be hidden

* Simplify if/case statements to be more readable

* Expand check for offset parents to also check children of ancestor for positioning attributes

close #4395
close #755

* Fix issue where els with parents with absolute position inside overflow hidden would be calculated as not visible

* comment out opacity checks for patch release

* Add more tests around new visibility assertions

- Add case to make sure display none is not on the option or optgroup
itself

* Fix failing assertion - where el was undefined when looking for visibiliyt

* remove commented out code involving opacity 😬
@jennifer-shehane
Copy link
Member

This is still incorrectly failing in Cypress 4.9.0.

@jennifer-shehane jennifer-shehane added the pkg/driver This is due to an issue in the packages/driver directory label Jul 7, 2020
@panzarino panzarino self-assigned this Jul 14, 2020
@panzarino
Copy link
Contributor

panzarino commented Jul 14, 2020

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).

@jennifer-shehane jennifer-shehane added stage: wontfix Cypress does not regard this as an issue or will not implement this feature and removed stage: ready for work The issue is reproducible and in scope labels Aug 17, 2020
@vacas5
Copy link

vacas5 commented Jun 28, 2021

using clip-path to visually hide elements but leave them available for screen readers is a commonly used paradigm in front end development. https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/

Is there any way to use a class like this in conjunction with Cypress visibility?

@panzarino
Copy link
Contributor

@vacas5 You could potentially assert on the clip-path css property directly with have.css or assert that the element should have.class. As explained above, for technical reasons, there are no plans to incorporate checking for clip-path directly into the visibility assertion.

@mikkorantalainen
Copy link

As the most common use of these properties is to hide the whole element without removing it from the DOM for accessibility purposes, maybe support only two special cases:

  • clip: rect() with 4 identical lengths as arguments. Though I think supporting only rect(0, 0, 0, 0) should be enough because any other way to clip everything only results in longer strings.
  • clip-path: polygon() for whatever count of zero length pairs as arguments. (Note that you might need to support both polygon(0px 0px, 0px 0px, 0px px) and polygon(0 0, 0 0, 0 0, 0 0) here. Again, I think supporting only verbatim polygon(0 0, 0 0, 0 0) should be enough for all practical purposes.)

And simply document that for all other cases, the clip and clip-path properties will be ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg/driver This is due to an issue in the packages/driver directory stage: wontfix Cypress does not regard this as an issue or will not implement this feature topic: visibility 👁 type: bug
Projects
None yet
Development

No branches or pull requests

6 participants