Cypress: Chaining multiple API calls results in async/sync mix error

Created on 14 Feb 2019  Â·  8Comments  Â·  Source: cypress-io/cypress

When chaining API calls in a cypress custom command, I am getting an error that says async/sync code is being mixed:

Desired behavior

This example only shows 2 API calls, but the end solution is going to require 3. I need to make 1 API call to return a token, another to get a user id, and then use both those returned values in a POST:

Steps to reproduce: (app code and test code)

I want to return the authID from the response, and then use it in then(authToken=>)

Cypress.Commands.add("ResetPwd", () => {
    return cy.request({
        method: 'POST',
        url: "https://example//token",
        headers: {
            'Content-Type': 'application/json',
        },
        body: {
            client_id: '1234',
            client_secret: '4321',
            audience: 'https://example.com/api/v2/',
            grant_type: 'credentials'
        }
    }).then(response => {
        const rbody = (response.body);
        var tokenPattern = "(?i)\"access_token\":\\s*\"([^\"]*)\"";
        const authToken = rbody.access_token;
        cy.log(authToken);
        return authToken
    }).then(authToken =>{
        cy.request({
            method: 'PATCH',
            url: "https://example.com/api/v2/users/33",
            headers: {
                'Content-Type': 'application/json',
                'authorization': 'Bearer '+authToken
            },
            body: {
                password: 'Test4321',
                connection: 'UserDB'
            },
        })
    })
});

When running this command, I get an error that says

CypressError: cy.then() failed because you are mixing up async and sync code.

In your callback function you invoked 1 or more cy commands but then returned a synchronous value.

pkdriver ready for work user experience

Most helpful comment

I also encountered a similar issue recently as well. I had to remove the cy.log() call from the chain to resolve it.

Edit: I've replaced my cy.log with Cypress.log() instead. This is working well for me.

All 8 comments

@chrisbreiding do we need to add a description for this error to http://on.cypress.io/error-messages and put the link into the error message?

@bahmutov The description is already on that page, we just need to link to it in the error.

nice, I was searching for "mixing up async and sync code" on the page ;)

On Fri, Feb 15, 2019 at 9:30 AM Chris Breiding notifications@github.com
wrote:

@bahmutov https://github.com/bahmutov The description is already on
that page
https://docs.cypress.io/guides/references/error-messages.html#Cypress-detected-that-you-returned-a-promise-in-a-test-but-also-invoked-one-or-more-cy-commands-inside-of-that-promise,
we just need to link to it in the error.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/cypress-io/cypress/issues/3472#issuecomment-464069512,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACHApk8lpvLxwe8VdAHd8wSwHnI2jtRpks5vNsR5gaJpZM4a8VSr
.

--
Dr. Gleb Bahmutov, PhD

Schedule video chat / phone call / meeting with me via
https://calendly.com/bahmutov
gleb.[email protected] @bahmutov https://twitter.com/@bahmutov
https://glebbahmutov.com/ https://glebbahmutov.com/blog
https://github.com/bahmutov

I have the same issue with this. Has this been addressed ?

What i mean is what are my other options for doing this

I also encountered a similar issue recently as well. I had to remove the cy.log() call from the chain to resolve it.

Edit: I've replaced my cy.log with Cypress.log() instead. This is working well for me.

Cypress is using a command queue, so regardless of what you are returning the last command result will be handed over to the next then call. Therefore if you want to return like a token and a userId you need to wrap your synchronous result in a cy.wrap({authToken, userId}).
If you also want to make Typescript happy you need to change the return type of the then method to be
as unknown as Chainable<{authToken: string, userId: number}>

I ran into similar issue and found if you remove cy.log(authToken); or any other cy commands within then from your code it will work.

Was this page helpful?
0 / 5 - 0 ratings