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

An ancestor element with display: contents and overflow: hidden causes visibility check to fail #25199

Open
kevinleedrum opened this issue Dec 16, 2022 · 7 comments
Labels
E2E Issue related to end-to-end testing topic: visibility 👁 Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team.

Comments

@kevinleedrum
Copy link

kevinleedrum commented Dec 16, 2022

Current behavior

If an element has an ancestor with both overflow: hidden and display: contents, Cypress will think that element is not visible because Cypress sees the ancestor element as having zero width and height (and no overflow).

image

Desired behavior

Although it is silly to combine overflow: hidden with display: contents, and I can easily work around this issue in the app being tested, the child elements are technically visible, so ideally this should be fixed in cypress.

Cypress should give elements with display: contents a pass when checking that the element has a width and height since those elements don't really render a box to measure. The visibility check would then fall to the next descendent.

Test code to reproduce

See https://github.com/kevinleedrum/cypress-test-tiny. The markup is in index.html; npm run cypress:run should reproduce the failure.

The relevant bit is that the <section> below will be seen as NOT visible, even though it is.

      <div style="display: contents; overflow: hidden">
        <section>Hello</section>
      </div>

Cypress Version

12.1.0

Node version

v14.17.0

Operating System

macOS 13.0.1

Debug Logs

[1]   cypress:server:run spec results { stats: { suites: 1, tests: 1, passes: 0, pending: 0, skipped: 0, failures: 1, wallClockStartedAt: 2022-12-16T16:22:31.891Z, wallClockEndedAt: 2022-12-16T16:22:37.453Z, wallClockDuration: 5562 }, reporter: 'spec', reporterStats: { suites: 1, tests: 1, passes: 0, pending: 0, failures: 1, start: 2022-12-16T16:22:31.893Z, end: 2022-12-16T16:22:37.459Z, duration: 5566 }, hooks: [], tests: [ { testId: 'r3', title: [Array], state: 'failed', body: '() => {\n' + '    cy.visit("http://localhost:8888");\n' + '    cy.get("section").should("be.visible");\n' + '  }', displayError: "AssertionError: Timed out retrying after 4000ms: expected '<section>' to be 'visible'\n" + '\n' + 'This element `<section>` is not visible because its parent `<div>` has CSS property: `overflow: hidden` and an effective width and height of: `0 x 0` pixels.\n' + '    at Context.eval (webpack:///./cypress/e2e/spec.cy.js:5:22)', attempts: [Array] } ], error: null, video: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/videos/spec.cy.js.mp4', screenshots: [ { screenshotId: 'o2mit', name: null, testId: 'r3', testAttemptIndex: 0, takenAt: '2022-12-16T16:22:37.238Z', path: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/screenshots/spec.cy.js/page -- has a visible section (failed).png', height: 720, width: 1280, pathname: undefined } ], spec: { fileExtension: '.js', baseName: 'spec.cy.js', fileName: 'spec', specFileExtension: '.cy.js', relativeToCommonRoot: 'spec.cy.js', specType: 'integration', name: 'cypress/e2e/spec.cy.js', relative: 'cypress/e2e/spec.cy.js', absolute: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/e2e/spec.cy.js' }, shouldUploadVideo: true } +753ms
[1]   cypress:server:run final results of all runs: { status: 'finished', startedTestsAt: 2022-12-16T16:22:31.891Z, endedTestsAt: 2022-12-16T16:22:37.453Z, totalDuration: 5562, totalSuites: 1, totalTests: 1, totalPassed: 0, totalPending: 0, totalFailed: 1, totalSkipped: 0, runs: [ { stats: [Object], reporter: 'spec', reporterStats: [Object], hooks: [], tests: [Array], error: null, video: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/videos/spec.cy.js.mp4', screenshots: [Array], spec: [Object], shouldUploadVideo: true } ], browserPath: '', browserName: 'electron', browserVersion: '106.0.5249.51', osName: 'darwin', osVersion: '22.1.0', cypressVersion: '12.1.0', runUrl: undefined, config: { setupNodeEvents: '[Function setupNodeEvents]', projectRoot: '/Users/kevin.drum/repos/cypress-test-tiny', projectName: 'cypress-test-tiny', repoRoot: '/Users/kevin.drum/repos/cypress-test-tiny', rawJson: { e2e: [Object], setupNodeEvents: '[Function setupNodeEvents]', envFile: {}, projectRoot: '/Users/kevin.drum/repos/cypress-test-tiny', projectName: 'cypress-test-tiny', repoRoot: '/Users/kevin.drum/repos/cypress-test-tiny' }, configFile: 'cypress.config.js', morgan: false, isTextTerminal: true, socketId: 'nvp18urthh', report: true, animationDistanceThreshold: 5, arch: 'x64', baseUrl: null, blockHosts: null, chromeWebSecurity: true, clientCertificates: [], defaultCommandTimeout: 4000, downloadsFolder: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/downloads', env: {}, execTimeout: 60000, experimentalFetchPolyfill: false, experimentalInteractiveRunEvents: false, experimentalRunAllSpecs: false, experimentalModifyObstructiveThirdPartyCode: false, experimentalOriginDependencies: false, experimentalSourceRewriting: false, experimentalSingleTabRunMode: false, experimentalStudio: false, experimentalWebKitSupport: false, fileServerFolder: '/Users/kevin.drum/repos/cypress-test-tiny', fixturesFolder: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/fixtures', excludeSpecPattern: '*.hot-update.js', includeShadowDom: false, keystrokeDelay: 0, modifyObstructiveCode: true, nodeVersion: undefined, numTestsKeptInMemory: 0, platform: 'darwin', pageLoadTimeout: 60000, port: 58834, projectId: null, redirectionLimit: 20, reporter: 'spec', reporterOptions: null, requestTimeout: 5000, resolvedNodePath: '/Users/kevin.drum/.nvm/versions/node/v14.17.0/bin/node', resolvedNodeVersion: '14.17.0', responseTimeout: 30000, retries: { runMode: 0, openMode: 0 }, screenshotOnRunFailure: true, screenshotsFolder: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/screenshots', slowTestThreshold: 10000, scrollBehavior: 'top', supportFile: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/support/e2e.js', supportFolder: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/support', taskTimeout: 60000, testIsolation: true, trashAssetsBeforeRuns: true, userAgent: null, video: true, videoCompression: 32, videosFolder: '/Users/kevin.drum/repos/cypress-test-tiny/cypress/videos', videoUploadOnPasses: true, viewportHeight: 660, viewportWidth: 1000, waitForAnimations: true, watchForFileChanges: false, specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', additionalIgnorePattern: [], autoOpen: false, browsers: [ [Object], [Object], [Object] ], clientRoute: '/__/', cypressBinaryRoot: '/Users/kevin.drum/Library/Caches/Cypress/12.1.0/Cypress.app/Contents/Resources/app', devServerPublicPathRoute: '/__cypress/src', hosts: null, isInteractive: true, namespace: '__cypress', reporterRoute: '/__cypress/reporter', socketIoCookie: '__socket', socketIoRoute: '/__socket', version: '12.1.0', cypressEnv: 'production', resolved: { animationDistanceThreshold: [Object], arch: [Object], baseUrl: [Object], blockHosts: [Object], chromeWebSecurity: [Object], clientCertificates: [Object], defaultCommandTimeout: [Object], downloadsFolder: [Object], env: {}, execTimeout: [Object], experimentalFetchPolyfill: [Object], experimentalInteractiveRunEvents: [Object], experimentalRunAllSpecs: [Object], experimentalModifyObstructiveThirdPartyCode: [Object], experimentalOriginDependencies: [Object], experimentalSourceRewriting: [Object], experimentalSingleTabRunMode: [Object], experimentalStudio: [Object], experimentalWebKitSupport: [Object], fileServerFolder: [Object], fixturesFolder: [Object], excludeSpecPattern: [Object], includeShadowDom: [Object], keystrokeDelay: [Object], modifyObstructiveCode: [Object], nodeVersion: [Object], numTestsKeptInMemory: [Object], platform: [Object], pageLoadTimeout: [Object], port: [Object], projectId: [Object], redirectionLimit: [Object], reporter: [Object], reporterOptions: [Object], requestTimeout: [Object], resolvedNodePath: [Object], resolvedNodeVersion: [Object], responseTimeout: [Object], retries: [Object], screenshotOnRunFailure: [Object], screenshotsFolder: [Object], slowTestThreshold: [Object], scrollBehavior: [Object], supportFile: [Object], supportFolder: [Object], taskTimeout: [Object], testIsolation: [Object], trashAssetsBeforeRuns: [Object], userAgent: [Object], video: [Object], videoCompression: [Object], videosFolder: [Object], videoUploadOnPasses: [Object], viewportHeight: [Object], viewportWidth: [Object], waitForAnimations: [Object], watchForFileChanges: [Object], specPattern: [Object], browsers: [Object], hosts: [Object], isInteractive: [Object] }, testingType: 'e2e', remote: { auth: undefined, origin: 'http://localhost:58834', strategy: 'file', fileServer: 'http://localhost:58835', domainName: 'localhost', props: null }, browser: null, specs: [], proxyUrl: 'http://localhost:58834', browserUrl: 'http://localhost:58834/__/', reporterUrl: 'http://localhost:58834/__cypress/reporter', proxyServer: 'http://localhost:58834', state: {} } } +1ms

Other

No response

@mike-plummer
Copy link
Contributor

Hi @kevinleedrum , thanks for letting us know about this. Also, thanks so much for the reproduction! Visibility is one of the trickiest things we have to juggle (it's pretty complex for anyone else stumbling across this comment).

I can confirm this is a hole in our logic so I'll get this passed along to the team to look into, but it might be a little while before we have time to work it. If anyone in the community would like to take a stab at improving this logic a good place to start would be packages/driver/src/dom/visibility.ts.

@mirobo
Copy link
Contributor

mirobo commented Dec 19, 2022

@kevinleedrum See also my discussion here #23900 which is also about display: contents. My code samples revolve around the problem on how to make sure that selectors in page objects are pointing to the correct element but I could remove some hacky code if the "display: contents" visibility check would be different (i.e. check child elements for visibility as you suggested as well)..

@roelaenomar
Copy link

roelaenomar commented Mar 14, 2023

I am also experiencing this, the CSS property overflow-x is not found, however, if I will assert that it exists, it passed.
image

@developernarendra
Copy link

hi can you pls guide me how i can start this
means how i can take to this my local machine
i dont know anything
i know how to fork but not able to understand how to start this and go for pull request

@mike-plummer
Copy link
Contributor

Hi @developernarendra , thanks for showing an interest in contributing to Cypress! I would recommend starting with our Contributors Guide. That document includes (or links to) information on how to clone Cypress locally, build it, make changes, and finally open a PR.

@nagash77 nagash77 added E2E Issue related to end-to-end testing Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. and removed routed-to-e2e labels Apr 19, 2023
@bastiansmn
Copy link

Hello, currently working on this since I reproduced locally with latest and started to have a good idea on how to fix.

@senpl
Copy link

senpl commented Jun 17, 2024

Should b fixed in #29680

@jennifer-shehane jennifer-shehane removed the good first issue Good for newcomers label Jul 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E2E Issue related to end-to-end testing topic: visibility 👁 Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants