Commands after cy.visit are executed before page is fully loaded (before page loaded event is fired)
cy.visit should wait on page load event or timeout set before proceeding to any commands after it has been invoked.
https://github.com/janusqa/cypress-test-tiny
Run test and view console (spec.js).
chrome: Version 72.0.3626.121 (Official Build) (64-bit)
linux: Ubuntu 18.04.2 LTS
Cypress package version: 3.1.5
Cypress binary version: 3.1.5
Maybe "should" should wait instead but that fails to find the element as well because page was not fully loaded and/or "should" did not wait and/or default timeout for "should" was too short?
from the docs
When you load your application using cy.visit(), Cypress will wait for the load event
to fire. It is really this easy. The cy.visit() command loads a remote page and does
not resolve until all of the external resources complete their loading phase.
This seems to describe what is in "### Desired Behavior" but what I get is "### Current Behavior"
Are you judging the order of operations by the console log calls from this test?
describe('page', () => {
it('does not work', () => {
cy.visit('https://google.com', {
onLoad: () => console.log('*** PAGE IS LOADED ***')
});
console.log('Should be printed AFTER *** PAGE LOADED ***');
});
});
What do you see? What do you expect to see? Here is what the test prints I believe
Should be printed AFTER *** PAGE LOADED ***
*** PAGE IS LOADED ***
Please read how commands are queued in Cypress in https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous
when you do
cy.visit()
console.log('BEFORE visit')
cy.visit just adds a command to visit the page to the Cypress' internal chain of commands, but nothing is running yet. console.log on the other hand runs IMMEDIATELY, thus printing BEFORE visit _before_ visit.
In your code replace console.log('Should be printed AFTER *** PAGE LOADED ***'); with cy.log('Should be printed AFTER *** PAGE LOADED ***');. and you will see what you expect to see: first the visit (which finishes for real, not just in our imagination or future plans), and then cy.log prints a message.
If you application has a lot of actions going on AFTER page loads and you would like to wait for them to complete, just add an assertion to wait for something: DOM element to be visible, text to be found, some flag to be set, etc. See
@bahmutov
Aha! I was thinking all commands enqueued! Thanks.
I will try increasing the timeout on the "should" i use for the slow loading element and then try some technique you mentioned above.
I updated the cy.get().should() timeout to get to 20000ms arbitrarily and that seems to have "solved" the issue. The elements in questions are glyphicons calendar pickers.
However its still flaky. sometimes the timeout will work sometimes not.
you may use cy.server().route() (the last xhr of cy.visit) before cy.visit and use cy.wait(@alias) after
Also, there's this useful plugin: https://github.com/NoriSte/cypress-wait-until. Might be helpful!