jaredpalmer / cypress-image-snapshot

Catch visual regressions in Cypress
MIT License
888 stars 160 forks source link

Is it possible to add a delay before screenshot happens? #143

Open stuartmilne opened 4 years ago

stuartmilne commented 4 years ago

I have an issue where I have a modal window that I open and then call matchImageSnapShot. When the screen shot happens this causes a resize event. Our app closes the modal on resize and reopens when resize is finished. This means the modal is not visible in snap shot for compare.

Is there a way to add a delay to the matchImageSnapShot function so that the modal has time to appear before snapshot is taken?

k2589 commented 4 years ago

@stuartmilne Maybe cy.wait(time) before snapshot will work for you?

krysalead commented 4 years ago

Hi,

You should use a dom state https://docs.cypress.io/guides/tooling/visual-testing.html#DOM-state use cy.contains() to wait for your modal to be here.

Pieras2 commented 3 years ago

I would also need a delay parameter but I think this is not this plugin fault but Cypress cy.screenshot() as it switches view and does the screenshot which seems in my case made to quickly - page is not in the shape I expect before screen is taken

vasilev-alex commented 3 years ago

I've got the same request here. In my case, the screenshot is taken before the animation has completed thus the taken screenshot doesn't represent the actual state.

pranjalk commented 3 years ago

I've got the same issue. In my case, the charts are in the middle of resizing when the screenshot gets taken. A delay would be really helpful so that the screenshot and the screen actually match

Pieras2 commented 2 years ago

I think that the problem is in cypress, not this plugin. I guess that cy.screenshot called by the plugin is ok but the cypress does window resize and I think we should "complain" to cypress

stuartmilne commented 2 years ago

I managed to get around my issue of resizing by using a cypress command. The workaround is to hide the cypress viewport (test runner) just before the snapshot is taken. Once the snapshot is taken you can then re show the view port. Below is the clearViewPort command code. I did not write this code. I got it from somewhere else but cant find the link to link back to.

`Cypress.Commands.add("clearViewport", () => { const runnerContainer = window.parent.document.getElementsByClassName( "iframes-container" )[0]; runnerContainer.setAttribute( "style", "left: 0; top: 0; width: 100%; height: 100%;" );

const sizeContainer = window.parent.document.getElementsByClassName(
  "size-container"
)[0];
sizeContainer.setAttribute("style", "");

const sidebar = window.parent.document.getElementsByClassName(
  "reporter-wrap"
)[0];
sidebar.setAttribute("style", "opacity: 0");

const header = window.parent.document.querySelector(
  ".runner.container header"
);
header.setAttribute("style", "opacity: 0");

})`

To use simply call cy.clearViewport();

pranjalk commented 2 years ago

After deep-diving into the docs/GitHub issues/code, I found out that cypress restricts the browser to 1280x720 resolution in headless mode. It is mentioned that they have set the defaults due to memory constraints in a CI environment.

So, if you set the viewport to a higher resolution say 1920x1080 in the test case or cypress.json, cypress will start the browser in 1280x720 but resize to the viewport size (1920x1080) while taking a screenshot. This causes the jitter in the screenshot.

To avoid this, I followed this cypress.io blog (it's fairly recent), where they have shared a snippet for a cypress plugin that allows you to set the browser resolution. Finally, I set the viewport size the same as browser resolution.

This completely removed the resize jitter as the viewport is no longer resizing while taking a screenshot.