https://cypress.io logo
How to chain custom commands in for loop?
# i-need-help
b
I have a custom commands created:
cy.createUser()
which implementation looks like this:
Copy code
Cypress.Commands.add('createUser', (user: User, userNumber: number) => {
    user.name = `User ${userNumber}`
    cy.request({
        method: 'POST',
        url: '/createUserEndpoint',
        body: user,
        headers: {
            authorization: 'token'
        }
    }).then(response => {
        return response.body;
    });
});
Copy code
declare global {
    namespace Cypress {
        interface Chainable {
            createUser(user: User, userNumber: number): Chainable<void>;
        }
    }
}
And in the test to create let's say 3 users one after another I have to do this:
Copy code
import { userData } from '../../fixtures'
let user: User = JSON.parse(JSON.stringify(userData));

it('test', () => {
    cy.createUser(user, 1)
      .createUser(user, 2)
      .createUser(user, 3);
)};
But is it possible to create a custom command which would chain these commands inside it? Something like:
Copy code
Cypress.Commands.add('createUsers', (user: User, usersNumber: number) => {
    for (let i = 1; i < usersNumber+1: i++) {
        user.name = `User ${userNumber}`
        cy.request({
            method: 'POST',
            url: '/createUserEndpoint',
            body: user,
            headers: {
                authorization: 'token'
            }
        }).then(response => {
            return response.body;
        });
    }
});
And in the test I would like to have:
Copy code
import { userData } from '../../fixtures'
let user: User = JSON.parse(JSON.stringify(userData));

it('test', () => {
    cy.createUsers(user, 3);
)};
But this code doesn't work the way I would expect it to. Cypress sends a request with the same data of the last iteration so with Body: {...,"name":"User 3",...} Is it possible to implement one cystom command which would chain multiple commands on each other for a given number? How to do it?
b
Does it work if you try this?
Copy code
cy.request({
            method: 'POST',
            url: '/createUserEndpoint',
            body: { ...user, name: `User ${userNumber}`},
            headers: {
                authorization: 'token'
            }
I'm guessing setting
body
to
user
is passing by ref, and due to Cypress's command queueing system, all of them are going to read
user
to whatever value you set last. Instead you should try to clone
user
and pass it into
body
, so that each request is reading from its own unique
user
object instance.
b
Thanks for the answer. This is what I assumed but do you know how to properly clone such an object?
b
in the example I gave, it does a shallow clone of all the first-level properties in user, does it not work?
b
Great, it worked! Many thanks for quick help!
b
no worries 🙂
great to hear!
4 Views