Reputation: 163
I'm using Cypress to test my spa. Sometimes the page displays quickly and sometimes it is very slow. I need to be able to check for a button or text that will display once the page is loaded, but do not want to wait for eternity.
I've been using excessively long wait periods but would like the test to run faster.
let targeturl = 'http:\\something.com'
let longwait = 2500
describe('Update Case', () => {
it('Create Case', () => {
cy.visit(targeturl)
cy.wait(longwait)
cy.get('button').contains('Create').click()
I want to be able to set a wait that waits until the button 'Create' is displayed.
Upvotes: 15
Views: 57580
Reputation: 1062
For any newcomers to this question/problem:
The Cypress docs explicitly discourage arbitrary wait()
usage, while thankfully now supplying solutions using intercept()
and an aliased route.
Here's how it'd work per the docs. Say you want to wait for the /users
page/endpoint to load and then you want to check that a DOM element like a table is present, here's how you'd do it.
cy.intercept('GET', '/users').as('getUsers')
cy.get('[data-testid="fetch-users"]').click()
cy.wait('@getUsers') // <--- wait explicitly for this route to finish
cy.get('table tr').should('have.length', 2)
And if after that you still have issues, like XHR request still completing after page load and therefore halting your element from appearing, then you can pass the timeout
prop to cy.get()
like this
cy.get('table tr', { timeout: 20000 }).should('have.length', 2)
Cypress wont wait for that whole length of time if it's already loaded and doesnt need it, thanks to your previous intercept/aliased route usage (unlike wait
which stalls your tests no matter what.) But that'll give you extra padding if you need it.
Upvotes: 1
Reputation: 431
What about writing some assertion like .should() :
let targeturl = 'http:\\something.com'
let longwait = 2500
describe('Update Case', () => {
it('Create Case', () => {
cy.visit(targeturl)
cy.url().should('include',targeturl)
cy.get('button').contains('Create').click()
That worked for me in some cases I needed to have page load complete before selecting any content from page.
Upvotes: 1
Reputation: 5864
I think you might want to use timeout
option of visit
:
cy.visit(targeturl, { timeout: 30000 })
I remember I was having similar issue in the past, this Github issue provided me some useful information back then.
Upvotes: -3
Reputation: 5881
By default, Cypress will wait for your page to load all resources before continuing the test. Your cy.wait()
shouldn't be necessary. The default timeout for cy.visit()
is 60 seconds.
Also, cy.get()
will retry finding your element until the element exists. The default timeout is 4 seconds, but you can increase it.
Something like this is generally all you need:
describe('Update Case', () => {
it('Create Case', () => {
cy.visit(targeturl)
cy.get('button').contains('Create').click()
If you find that this isn't working, perhaps because your page takes more than 4 seconds to render after it loads all resources, then you can do something like this:
describe('Update Case', () => {
it('Create Case', () => {
cy.visit(targeturl)
// wait up to 30 seconds for some element to exist before continuing the test
cy.get('.some-element-in-your-app-that-only-exists-once-page-has-loaded', { timeout: 30000 })
cy.get('button').contains('Create').click()
In general, you shouldn't ever need to use cy.wait()
to delay your tests by a certain number of milliseconds. Doing so is almost always a bad practice.
Upvotes: 20