0

I have a custom command to get user data from SQL Server, which works fine. But now I cannot find a way to loop through the data returned.

I need something like this:

var users = []

describe('start tests ', () => {
    before(() => {
        cy.getUser(1, 0).then(value => {
            users.push(value)
        });
    })

    users.forEach((u) => {

        it("Test for user " + u['username'], () => {

            // test script here

        });
    });
})

But it doesn't work because JavaScript forEach part is not waiting for the cy.before(). I tried and searched but cannot find a solution. Any ideas? Thanks.

4
  • Not really. I guess before:run will executed at all other tests too. And the detour with writeJson will maybe not work on the destination server because strict seurity settings. Commented Jun 25, 2023 at 7:50
  • 1
    No, before:run is run before the run - I guess it's well named :). So the data is set up, but obviously a test does not have to use it. Commented Jun 25, 2023 at 7:57
  • Yes, but getUser is a custom command that makes request to the SQL server. This slows down any other test even if they don't use the data. And vith the param in the getUser function I select specific user, other testI select different user. Commented Jun 25, 2023 at 8:06
  • 2
    So - you can't do it the way you have it above. If you want you can conditionally run the before:run using an environment variable. Just a suggestion. Commented Jun 25, 2023 at 8:15

2 Answers 2

0

users.push() only adds one item to the array, so no point in forEach() on that anyway.

If you misrepresented the test, and in fact have multiple users, you need to know that you cannot dynamically set the number of tests from code within the spec.

You must add a before:run hook to the setupNodeEvents to do so.

See this question for an alternative way to handle the problem - Pre-scan web page for dynamic tests

Sign up to request clarification or add additional context in comments.

3 Comments

I call this getUser function multiple times to get a few specific users. All I need is a method to wait for the cypress before part to be done before start the loop.
You can't wait for before() to finish - it will not start until the .forEach() has finished.
I know it's not working that way. That's why I'm asking for a solution.
0

You can run your code successfully if you know how many users there will be (not necessarily what their details are).

So you can't put the username in the title.

const users = new Array(2).fill({})  

Cypress.Commands.add('getUser', (num) => {
  if (num === 1) return {username: 'Jack'}
  if (num === 2) return {username: 'Jill'}
})

describe('start tests ', () => {
  before(() => {
    cy.getUser(1, 0).then(value => users[0] = value)   
    cy.getUser(2, 3).then(value => users[1] = value)
  })

  users.forEach((_, index) => {
    it(`Test for user ${index}`, () => {
     cy.log(`Testing user: ${users[index].username}`)  // passing with Jack
                                                       // next it() with Jill
      // ...

    })
  })
})

You should not be concerned about running a query in before:run, the evaluation time will be small compared to the overall run time of the spec. Also, you can mitigate the issue by conditionally querying, but that is outside of the scope of your question.

2 Comments

This will give an error as soon as you try to access values from the users inside the array. I tried that already. The array has a length of 5, but when the forEach starts all 5 will be empty.
I updated - using a .fill({}) to remove the error, and deferring the access to users[index] inside the test.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.