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

Sticky elements within a fixed container are not properly taken into account when scrolling to an element #4233

Closed
johanneslumpe opened this issue May 17, 2019 · 19 comments · Fixed by #18441

Comments

@johanneslumpe
Copy link

johanneslumpe commented May 17, 2019

Current behavior:

This bug is related to #565 / #571

A typical use case for fixed containers are modals which fully overlay an application. In our case the fixed container is used to dim the application while displaying a modal or side panel within said container. The content within the dimmed overlay container is scrollable, but the container itself is not. I was able to break the test for #565 by making minimal adjustments to the fixture, which is included in the test repo.

As soon as a sticky element is nested within a fixed container, Cypress scrolls the element too far, so it ends up below the sticky header.

sticky elements -- additional example with side panel -- can click the first tr (failed)
sticky elements -- issue 565571 with updated fixture -- can click the first tr (failed)

Desired behavior:

Cypress should take sticky headers into account when scrolling, even when they are within a fixed element and clicking on an element should succeed.

Steps to reproduce: (app code and test code)

A repo (based on https://github.com/cypress-io/cypress-test-tiny) containing two failing test cases can be found at https://github.com/johanneslumpe/cypress-sticky-header-bug

Versions

Cypress 3.3.0
Chrome 74
Mac OS

@cypress-bot cypress-bot bot added the stage: needs investigating Someone from Cypress needs to look at this label May 20, 2019
@ShonP

This comment has been minimized.

@asam139
Copy link

asam139 commented Dec 16, 2019

I have the same problem with a sticky element. Please, I need to resolve this and any help all be helpful.

@Moke96

This comment has been minimized.

@tnrich
Copy link
Contributor

tnrich commented Jan 23, 2020

I'm definitely still seeing issues with cypress scrolling elements under a sticky header.

@KatieMFritz
Copy link

Related to #871 . Lots of people (including me) having trouble with elements getting scrolled under a sticky header and thus not visible.

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Apr 8, 2020

The first example provided here is actually not a bug. The container is not scrollable - there's no way to click on the 'a' element in the example outside of Cypress.

index.html: https://raw.githubusercontent.com/johanneslumpe/cypress-sticky-header-bug/5fd91e18000604c632556754b8c8a8f366ab79af/cypress/fixtures/issue-565-updated.html

it('can click the first tr', () => {
  cy.viewport(400, 400)
  cy.visit("index.html")
  cy.get("td:first").click()
})

No scrollbar available - the 'a' td is unclickable normally.

Screen Shot 2020-04-08 at 12 35 25 PM

The second example is the bug - you can scroll to the a td element normally and click the element.

Simplest code to reproduce

index.html

<!DOCTYPE html>
<html>
<body>
  <div class="overlay-background" style="position: fixed; width: 300px">
    <div class="sidepanel" style="position: absolute; height: 300px; overflow: auto;">
      <header class="sticky-header" style="position: sticky; top: 0; left: 0; height: 40px; background-color: blue;">
        sticky header
      </header>
      <div style="height: 500px">
        <p>content to scroll to</p>
      </div>
    </div>
  </div>
</body>
</html>
it('can click the p behind sticky header', () => {
  cy.viewport(400, 400)
  cy.visit('index.html')
  cy.get('p').click()
})

@cypress-bot cypress-bot bot added stage: ready for work The issue is reproducible and in scope and removed stage: needs investigating Someone from Cypress needs to look at this labels Apr 8, 2020
@jennifer-shehane jennifer-shehane added topic: cy.click 🖱 pkg/driver This is due to an issue in the packages/driver directory type: bug labels Apr 8, 2020
@pedroAVS
Copy link

pedroAVS commented Jun 22, 2020

Hi, is there any news regarding this issue?
I think I'm having some related issue aswell. My front end is under react and the dev team is using a dropdown list that pops up from the top, once the dropdown menu is clicked. This list is a fixed element and it doesn't appear anywhere within the viewport. after some debugging i've found that the list is actually spawning outside the browser window, below or above the test runner.

2020-06-22_14h06_19
here it is found below

2020-06-22_14h21_45
here it is on top

those screenshots is after clicking the dropdown button, that should trigger the list to appear.

In both cases the element is not found by cypress, even though that after clicking on the dropdown menu, the list appears in the html document.

@iozzyi
Copy link

iozzyi commented Jul 2, 2020

I have the same issue, but the frustrating thing is that the element is already visible in the page so scrolling was not necessary. Couldn't there be an option to turn off the auto-scrolling option? Or otherwise to set the fixed-height at the top when typing so that it doesn't scroll so much?

Also worth noting, in my case the scrollbar wouldn't have allowed the page to scroll as much as Cypress has scrolled it for the input box to be at 0px from the top.

image
image

@getulionm
Copy link

getulionm commented Aug 12, 2020

Looking for updates or workarounds on this please 🙏
Any other tips for handling sticking elements?

@kennyg1989
Copy link

Still a problem in 5.2.0

@BernieCr
Copy link

BernieCr commented Mar 8, 2021

I ran into the same issue with a sticky header. As a workaround I set the default scroll behavior for the test to 'center'.
Another option would be to set scrollBehavior to false for the test and do all scrolling manually.

it('should test something', { scrollBehavior: 'center' }, () => {
     cy.get('#myelemtent').click();
});

@jennifer-shehane
Copy link
Member

Workaround

Since 6.1.0, you can pass the scrollBehavior option to .click() to prevent Cypress from scrolling on click or to scroll in a different position. This is a workaround for this issue.

it('can click the p behind sticky header', () => {
  cy.viewport(400, 400)
  cy.visit('index.html')
  cy.get('p').click({ scrollBehavior: false })
})
<html>
<body>
  <div class="overlay-background" style="position: fixed; width: 300px">
    <div class="sidepanel" style="position: absolute; height: 300px; overflow: auto;">
      <header class="sticky-header" style="position: sticky; top: 0; left: 0; height: 40px; background-color: blue;">
        sticky header
      </header>
      <div style="height: 500px">
        <p>content to scroll to</p>
      </div>
    </div>
  </div>
</body>
</html>

Screen Shot 2021-03-18 at 2 58 47 PM

@ilovett
Copy link

ilovett commented Jun 30, 2021

I would suggest a new ScreenShotOption

hideFixedElements: ['#appbar']
  1. First screen shot takes full screenshot (before hiding)
  2. Scroll to new position
  3. Hide all elements by selector in hideFixedElements
  4. Take Screenshot
  5. Scroll Down
  6. Repeat 4-5 until at bottom
  7. Restore hidden elements

@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review stage: work in progress and removed stage: needs review The PR code is done & tested, needs review stage: work in progress labels Oct 13, 2021
@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review stage: work in progress and removed stage: product review stage: needs review The PR code is done & tested, needs review labels Oct 26, 2021
@gkatsanos
Copy link

hey @jennifer-shehane , unfortunately The workaround does not work - we've been getting false negatives for months because of our sticky header, we're so desperate we're thinking of abandoning cypress at all.
Tried all the scrollBehavior options, the element keeps getting hidden behind the sticky header.

test:

describe('Modal Dialogs', () => {
  describe('Contact form', () => {
    it('should succesfully be submitted if fields completed', () => {
      cy.visit('https://www.wlw.de/de/firma/qa-testing-sa-1927745')
      cy.get('[data-test=contact-button]').each(($el) => {
        cy.wrap($el).click({ scrollBehavior: 'bottom' }) // tried 'nearest', 'false', 'center' 
        cy.get('.modal__dialog').within(() => {
          cy.get('.pell-content').type('Test message') // Click on button
          cy.get('#full-name').type('Max Mustermann')
          cy.get('#email').focus().type('max.mustermann@musterfirma.de')
          cy.get('.form-terms').within(() => {
            cy.get('.checkbox').click()
          })
          cy.get('.contact-form__submit-button').click()
        })
        cy.get('.contact-form__feedback').should('be.visible')
        cy.get('.modal__close').click()
      })
    })
  })
})

(there are random fails on this test depending on the animation speed maybe)

@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review and removed stage: product review labels Nov 1, 2021
@davidmunechika
Copy link
Contributor

Hi @gkatsanos , thanks for bringing this up. I was able to reproduce your issue and it doesn't appear to be a problem with scrollBehavior at all. When running the tests, it appears the Cookies modal is covering up the form, which is preventing some of the commands from successfully executing. In fact, when the modal is present, it appears you cannot scroll the page in any direction, so changing the scrollBehavior option is not going to resolve this. If you look at the screenshots below, the test fails when the modal is present and the test succeeds if I specifically close the modal, allowing the form to be visible. I hope this helps you resolve this issue.

Screenshot 2021-11-01 at 11 01 38 AM

Screenshot 2021-11-01 at 11 02 15 AM

@gkatsanos
Copy link

@davidmunechika thank you for checking this - I forgot to mention that we by-pass the cookie warning by hard-saving the value in our support/index.js file:

before(() => {
  cy.setCookie(
    'CookieConsent',
    // eslint-disable-next-line max-len
    '{stamp:%27vjpVJCpe9QeDb7Ba7mmn6GE5TtAmzBnDEVA8csu2OzT/ZGu6jV7YGw==%27%2Cnecessary:true%2Cpreferences:true%2Cstatistics:true%2Cmarketing:true%2Cver:4%2Cutc:1620824505756%2Cregion:%27gr%27}'
  )
})

so our fail is a different one. Thank you in advance for checking it!

@gkatsanos
Copy link

@chrisbreiding I guess it's about to be fixed/released in the next minor version upgrade?

@davidmunechika
Copy link
Contributor

@gkatsanos I tested your issue after adding the support file to bypass the cookie warning and it should be fixed by this PR (#18441) which will go out in the next release. The test consistently passes for me now, but feel free to reach out again if you continue to have issues.

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Nov 10, 2021

Released in 9.0.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v9.0.0, please open a new issue.

@cypress-bot cypress-bot bot removed the stage: needs review The PR code is done & tested, needs review label Nov 10, 2021
@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Nov 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.