1

I am writing a program to check the health endpoint of one of our APIs. So, before starting execution, I try to hit the health endpoint 5 times. If I get the desired response code during the 5 attempts, I break the loop and start test execution else give a message saying API is not healthy and stop the execution.

When below function is executed, it results in an error saying unsyntactic break Can someone suggest a better way to address this? I am using cypress.

  const maxRetry = Cypress.env('maxWarmUpRetries');
  const sleepTimeMs = 200;
  console.log(chalk.yellow('Checking API health before test execution...'));
  let healthCheckResponse;
  let healthStatusCode;
  for (let i = 0; i < maxRetry; i++) {
    console.log('Value of i is: ',i)
    apiHelper.requestHealth.then(response=>{
      healthCheckResponse=response;
      console.log('healthCheckStatusCode: ',healthCheckResponse.status)
      if (healthCheckResponse) {
        healthStatusCode = healthCheckResponse.status;
        if (healthStatusCode === 200) {
          console.log(chalk.green('API is healthy, moving forward with execution >>'));
          break;
        } else {
          console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
          if (i === maxRetry - 1) {
            console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
            break;
          }
        }
      } else {
        console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
        if (i === maxRetry - 1) {
          console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
          break;
        }
      }
    })
    
  }
});
7
  • 1
    That break is inside a callback function, not the same scope the loop is in. Your loop doesn't even wait for the request before iterating. Can you use async/await instead? – jonrsharpe Jan 27 at 12:12
  • Well. Cypress is not liking async/await. I was using supertest earlier and this one worked flawlessly with async/await. But not with Cypress. – Aalok Jan 27 at 12:14
  • 1
    Looks like they recommend recursion: docs.cypress.io/faq/questions/…. – jonrsharpe Jan 27 at 13:06
  • I would say this question should be closed because it's about JS coding, it should be reposted on Stack Overflow. – João Farias Jan 27 at 17:48
  • 1
    This is fundamentally flawed JavaScript.IMHO Its not about Cypress or super test libraries, its about JavaScript. – Vishal Aggarwal Feb 1 at 0:55
2

For loops are problematic in Cypress because they run run faster than the Cypress command queue.

You don't show the Cypress commands above, but I assume they are following the warmup loop and are only called when healthStatusCode === 200.

You might find Test Retries will work better for you.

Individual Test(s)

If you want to configure retry attempts on a specific test, you can set this by using the test’s configuration.

There is good logging out of the box, so you could drop your additional logs.

const maxRetry = Cypress.env('maxWarmUpRetries');

it('allows user to login', {
  retries: { runMode: maxRetry, openMode: maxRetry }
}, () => {

  apiHelper.requestHealth.then(response=>{

    // force test retry by throwing an error
    if (!response || response.status !== 200) {
      throw new Error("test fails here")
    }

    // All good
    // run tests here

  })
})
})
0

Break should be inside a loop, you are calling break inside a callback function , this is why you are getting unsyntactic break

if you want to break from call back replace break with return but this won't break the outside for loop.

you should use await :

  for (let i = 0; i < maxRetry; i++) {
    console.log('Value of i is: ',i)
    healthCheckResponse= await apiHelper.requestHealth()
    healthStatusCode = healthCheckResponse.code 
          if (healthCheckResponse) {
        healthStatusCode = healthCheckResponse.status;
        if (healthStatusCode === 200) {
          console.log(chalk.green('API is healthy, moving forward with execution >>'));
          break;
        } else {
          console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
          if (i === maxRetry - 1) {
            console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
            break;
          }
        }
      } else {
        console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
        if (i === maxRetry - 1) {
          console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
          break;
        }
      }

Note: To use await the IT block or function inside which you are calloing this code should be declared as asyn

eg:

it('should edit a new item', async () => {
        for (let i = 0; i < maxRetry; i++) {
        console.log('Value of i is: ',i)
        healthCheckResponse= await apiHelper.requestHealth
        healthStatusCode = healthCheckResponse.code 
              if (healthCheckResponse) {
            healthStatusCode = healthCheckResponse.status;
            if (healthStatusCode === 200) {
              console.log(chalk.green('API is healthy, moving forward with execution >>'));
              break;
            } else {
              console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
              if (i === maxRetry - 1) {
                console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
                break;
              }
            }
          } else {
            console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
            if (i === maxRetry - 1) {
              console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
              break;
            }
          }
}
10
  • Please add a sensible command when downvoting – PDHide Feb 1 at 1:04
  • Why do you need a loop here at all? – Vishal Aggarwal Feb 1 at 1:21
  • 1
    why would I run a test again and again until I get an expected result ?If it fails, it fails. Are we warming up the API by multiple calls? 🙂 – Vishal Aggarwal Feb 1 at 2:22
  • 1
    That api is not in the focus of test 😊 author needs it to return 200 within max try and do something with it . There is no assertions , so it's out of scope of this answer . This answer is about how to run the loop till 200 is returned . – PDHide Feb 1 at 2:33
  • 1
    @VishalAggarwal, please read. Warm up concept is used while automating API endpoints as well. Ensuring that API is warm before starting test execution. support.smartbear.com/readyapi/docs/performance/configure/… – Aalok Apr 30 at 6:14
0

Well, here is how this was finally fixed. Using await was one step closer to the solution. However, it was cypress-promise that helped in fixing the issue. Click here to read more about cypress-promise. Now the code looks like this:

const sleepTimeMs = 500;
console.log(chalk.yellow('Checking API health before test execution...'));
let healthCheckResponse;
let healthStatusCode;
for (let i = 0; i < maxRetry; i++) {
  healthCheckResponse = await promisify(apiHelper.requestApiHealth());
  if (healthCheckResponse) {
    healthStatusCode = healthCheckResponse.status;
    if (healthStatusCode === 200) {
      console.log(chalk.green('API is healthy, moving forward with execution >>'));
      break;
    } else {
      console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
      if (i === maxRetry - 1) {
        console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
        break;
      }
      cy.wait(sleepTimeMs);
    }
  } else {
    console.log(chalk.yellow('Warm up - Checking API /health before test execution...'));
    if (i === maxRetry - 1) {
      console.log(chalk.red('Warm up - API /health is down!!! Suspending test execution.'));
      break;
    }
    cy.wait(sleepTimeMs);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.