Cypress: Screenshot "scroll and stitch together" is not correct when `html` and `body` have `height: 100%` css style

Created on 31 Oct 2018  路  11Comments  路  Source: cypress-io/cypress

I'm experiencing an issue with screenshot functionality on a website under test.

It seems Cypress does not approve and when generating a full height screenshot of my page, it includes the sticky header and the "above fold" page content several times, completely ignoring any of the content (and the site footer) which you'd have to scroll to access.

On pages where the header is not sticky, part of the bottom of the page repeats, as below.

I've taken a look at attempting to invoke some of the CSS, but the likelihood is that there are multiple elements on some of the more complex pages which may require this hack.

Has anyone experienced this / found a solution?

existing workaround needs investigating screenshots 馃摳 bug

Most helpful comment

this work around doesn't fix the issue with sticky headers though, it still requires more css injection to make it work. And at the end what you're testing ends up being too different than the actual production code.

@jennifer-shehane

All 11 comments

See below for an example...
screenshot comparison -- match login page against baseline screenshot -- loginpage

We are experiencing the same issue with our React Web-App. This doesn't happen all the time, but only once in a while. Usually we have 5-10 such problems in our 3000 screenshots we are taking during one test run.

survey_ui_rating_matrix_slider_without_titles png___survey_ui_rating_matrix_slider_without_titles png_0 184459

Can anyone provide a way to reproduce this reliably?

I can reproduce it reliably on my employers website with standard screenshot functionality. I can share the URL via a private message as it's super secret at the moment.

My hacky fix has been to take the main div holding the site together and invoke 100% width and absolute (or fixed depending on the page) positioning as below:

cy.get('div[id=app]').invoke('css', 'position', 'absolute').invoke('css', 'width', '100%')

I have the exact same issue. It's a plain page, though.
In my case it breaks because of this css

html, body {
    height: 100%;
}

I thinks it's a part of some old framework or css-reset, not sure.
Here's a workaround:

cy.get('html').invoke('css', 'height', 'initial');
cy.get('body').invoke('css', 'height', 'initial');

@GordonTester You can email any private code / tests directly to [email protected]

Hii @jennifer-shehane
Need your help and advice here plz , how to interact with slider with 2 handle ,
HTML

<div class="horizontal-slider" style="position: relative;">
    <div class="bar bar-0" style="position: absolute; left: 0px; right: 225px; will-change: left, right;"></div>
    <div class="bar bar-1" style="position: absolute; left: 0px; right: 0.0139758px; will-change: left, right;"></div>
    <div class="bar bar-2" style="position: absolute; left: 224.986px; right: 0px; will-change: left, right;"></div>
    <div class="handle handle-0 " tabindex="0" role="slider" aria-valuenow="162.08" aria-valuemin="162.08"
         aria-valuemax="9177.64" style="position: absolute; z-index: 1; left: 0px;"></div>
    <div class="handle handle-1 " tabindex="0" role="slider" aria-valuenow="9177.08" aria-valuemin="162.08"
         aria-valuemax="9177.64" style="position: absolute; z-index: 2; left: 224.986px;"></div>
</div>

cypress step

cy.get('div.handle.handle-0').invoke('attr', 'aria-valuenow', "1000").click() // handle 1
cy.get('div.handle.handle-1').invoke('attr', 'aria-valuenow', "4188").click() // handle 2

I have the exact same issue. It's a plain page, though.
In my case it breaks because of this css

html, body {
    height: 100%;
}

I thinks it's a part of some old framework or css-reset, not sure.
Here's a workaround:

cy.get('html').invoke('css', 'height', 'initial');
cy.get('body').invoke('css', 'height', 'initial');

@neocoder this finally put an end to three straight days of constantly combing the web for a solution. Many, Many, Many thanks.

I can recreate this with the following code:

index.html

<html style="height: 100%;">
<body style="height: 100%; background: linear-gradient(yellow, blue, red);">
</body>
</html>

spec.js

it('screenshot', () => {
  cy.visit('index.html')
  cy.screenshot()
});

Expected screenshot

screenshot

Actual screenshot

screenshot (2)

Workaround

As explained by @neocoder, this workaround fixes the screenshot.

it('screenshot', () => {
  cy.visit('index.html')
  cy.get('html').invoke('css', 'height', 'initial');
  cy.get('body').invoke('css', 'height', 'initial');
  cy.screenshot()
  cy.get('html').invoke('css', 'height', '100%');
  cy.get('body').invoke('css', 'height', '100%');
});

this work around doesn't fix the issue with sticky headers though, it still requires more css injection to make it work. And at the end what you're testing ends up being too different than the actual production code.

@jennifer-shehane

Hi @jennifer-shehane
I am facing an issue when I am taking screenshot of a react Single Page App. Since it is confidential so I cannot share the screenshot here. Basically page has

-> left nav section and bottom left nav section has Feedback option.
-> right nav section and right nav section has chatbot button option.

_So when I am taking the screenshot, since the page is large so it is taking scrolls for 2 times as per the *_height_ I am passing to Cypress but due to this Chatbot & Feedback options coming as redundant and entire screenshot coming as weird._*

Do you suggest how can we overcome this and take screenshot fullPage without scrolls somehow to avoid this issue...

_I have gone through cypress-visual-regression & cypress-image-snapshot npm packages but all of them are underlying calling to cy.screenshot so they are not helping_

Your help is highly appreciated .

Was this page helpful?
0 / 5 - 0 ratings