javascriptwaitcypress

Cypress-wait-until - wait for element attribute to change


I am testing an app that has a button that causes a value in another element on screen to change, without reloading the page. However, that change in value can be almost instant, or take several seconds. Obviously, I don't want to use some arbitrary wait, and I don't want to use a (hard) assertion - that might cause the test to stop with a fail that isn't a fail.... so I've been looking at cypress-wait-until (https://www.npmjs.com/package/cypress-wait-until). I've written assorted variations along the lines of:

    waitForElemToChange(elem) {
        elem.invoke('attr', val').then((initialVal) => {
        cy.waitUntil(() => elem.invoke('attr', 'value').then((val) => val != initialVal))
    }

But nothing has worked so far - most attempts have resulted in "Timed out retrying: cy.invoke() errored because your subject is: null. You cannot invoke any functions such as attr on a null value."

Yet it's the same subject that just returned a value in the previous line??


Solution

  • This looks over complicated. I would approach it by waiting for initialValue, then waiting for a different value.

    cy.get('input').should('have.value', 'myInitialValue');     // wait for initial value
    cy.get('input').should('not.have.value', 'myInitialValue'); // wait for it to change
    

    .should() will retry the assertion up to 4 seconds.

    If by 'several seconds' you mean more than 4, you can add a timeout option, which is better than an arbitrary wait because it will continue as soon as the assertion passes.

    I'm assuming your element is an input since you are accessing val not text.