Dhamo
Dhamo

Reputation: 1251

How to wait for particular response data that is intercepted in cypress tests

I have a complex calculation service on a page that gets triggered on the click of a 'CALCULATE' button. This will trigger the service which will take between 10-30 seconds, so a GET request will be made for every 2 seconds unless the response contains "calculatedRoute" data in the JSON response. I then have to validate the UI against the calculatedRoute data

So far, I have the following test in Cypress

  cy.intercept("GET", "/v1/calculations/*").as("route-calculations")
  cy.get('#calc').click();
  cy.waitForCalculationRequest('@route-calculations', 30)

And in Commands,

Cypress.Commands.add("waitForCalculationRequest", (aliasName, retries) => {
  cy.wait(aliasName).its('response.body').then(json => {
    cy.log(typeof json)
    cy.log(json);
    cy.log(json.calculatedRoute);
    if (json.calculatedRoute == "") {
      return
    } 
    else if (retries > 0) {
      cy.waitForCalculationRequest(aliasName, retries - 1);
    } 
  });
});

But I am not able to make the command working as it throws

enter image description here

Any help would be appreciated.

GET Response data when the calculation is in progress (all requests except last one):

{
  "id": 8,
  "createdAt": "2021-07-13T11:39:11.756095Z",
  "updatedAt": "2021-07-13T11:39:11.756095Z",
  "status": "pending",
}

GET Response data when the calculation is completed (Last request):

{
  "id": 8,
  "createdAt": "2021-07-13T11:39:11.756095Z",
  "updatedAt": "2021-07-13T11:39:41.394267Z",
  "status": "complete",
   "calculatedRoute": {
    "route": "bla bla bla",
    "subscriptions": [
      x,y,z
    ],
    }
}

Upvotes: 1

Views: 846

Answers (2)

Ackroydd
Ackroydd

Reputation: 1610

It looks like you are almost there, but json.calculatedRoute is empty on request #33 and has an object on request #34, so is it just the if() statement, sort of what @ocyoplus says in comments but a bit stronger

if (typeof json.calculatedRoute === 'object') {    // found
  return json.calculatedRoute.route
} 
else if (retries > 0) {
  cy.waitForCalculationRequest(aliasName, retries - 1);
} 

Alternatively

if (json.status === 'complete') {    // found
  return json.calculatedRoute.route
} 
else if (retries > 0) {
  cy.waitForCalculationRequest(aliasName, retries - 1);
} else {
  // fail the test
  throw 'Status "complete" never occurred'  
}

Upvotes: 2

octoplus
octoplus

Reputation: 76

I don't know if this reccurency could work but it looks like you forget about cy. before waitForCalculationRequest(aliasName, retries - 1); So it should look like this:

Cypress.Commands.add("waitForCalculationRequest", (aliasName, retries) => {
  cy.wait(aliasName).its('response.body').then(json => {
    if (json.calculatedRoute == "") {
      return
    } 
    else if (retries > 0) {
      cy.waitForCalculationRequest(aliasName, retries - 1);
    } 
  });
});

Upvotes: 1

Related Questions