How to ensure all react components are loaded before cy.screenshot()
See original GitHub issueCurrent behavior:
When trying to get screenshots of pages, even after waiting for all xhr requests and checking elements exist, cy.screenshot()
will capture the page in an intermediate loading state where some things haven’t rendered yet.
I do not want to use cy.wait(1000)
as it is hacky and has caused my problems further down the test chain, such as random timeouts on screenshots.
Desired behavior:
Is there any way to check a component has rendered and is visible before taking the screenshot?
Steps to reproduce: (app code and test code)
Here is an example where it works when I add a wait but not without:
cy.fixture(QA_FIXTURE).as('fixture');
cy.server();
cy.route('POST', '/v1.0/blobs/sign-url/').as('signUrl');
cy.selectLatestActivity('/activity/');
cy.get('@fixture').then(fixture => {
if (fixture.BUILD_PREFIX === 'blah') {
cy.log(fixture.BUILD_PREFIX);
cy.wait('@signUrl').then(xhrs => {
cy.wrap(xhrs.status).should('eq', 200);
});
}
});
cy.wait(2000);
cy.screenshot();
cy.get('[data-cy="close_btn"]').click();
the signurl fucntion is the last request to occur, and even if use something like:
cy.get('[data-cy="close_btn"]').then(() => {cy.screenshot();});
To ensure the button is there after the request, it will still be a race to whether the component has rendered and the screenshot saved.
Versions
3.4.1
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (2 by maintainers)
@webnexusmobile’s solution is similar to what I’ve had to implement in some of the slower areas of our application. We’ll do things like:
cy.get('element we know loads "late"').should('not.be.empty');
orcy.get('element that will get focus when loading is done').should('have.focus')
In the rare case where that’s still not quite enough time (for transitions to finish firing or something like that) you could always increase the timeout of those checks instead of using
.wait()
. That way you can increase how long Cypress will wait for the thing to appear or exist without forcing it to wait the full amount of time.cy.get('#dialogClose').should('have.focus', { timeout: 5000 });
Did you ever try something like
or
? cy.get() alone doesn’t care for the visibility of an element.