Cypress - Having trouble asserting on requests using cy.intercept. 'cy.its() errored because the property: request does not exist on your subject.'

Viewed 2730

I'm trying to assert on the request body to ensure the correct new test card is passed as part of the order.

it("User clicks confirm & pay button to complete order", () => {
    cy.intercept("/api/checkout/payandcommit").as("placeOrder");
    cy.placeOrderAndPay();
    cy.wait("@placeOrder")
      .its("response.statusCode")
      .should("eq", 200)
      .its("request.body")
      .should("include", "cardNumber", 370000000000002);
  });

All is good upto verfying the status code then it breaks.

This is the error thrown:

Timed out retrying: cy.its() errored because the property: request does not exist on your subject.

cy.its() waited for the specified property request to exist, but it never did.

If you do not expect the property request to exist, then add an assertion such as:

cy.wrap({ foo: 'bar' }).its('quux').should('not.exist')

If i comment out the status code assertion this new error is thrown: object tested must be an array, a map, an object, a set, a string, or a weakset, but object given.

Any help getting this working would be much appreciated!

2 Answers

Chaining the assertions like this doesn't work, because the subject changes inside the chain

cy.wait("@placeOrder")           // yields interception object
  .its("response.statusCode")    // yields number 200
  .should("eq", 200)             // yields it's input (number 200)
  .its("request.body")           // not testing the interception object here
  .should("include", "cardNumber", 370000000000002);

One way that works is to use a callback which gets the interception object

cy.wait('@placeOrder').then(interception => {

  console.log(interception);    // take a look at the properties

  cy.wrap(interception.response.statusCode).should('eq', 404);

  cy.wrap(interception.request.body)
    .should("include", "cardNumber", 370000000000002)  // not sure this should is correct
    .should("have.property", "cardNumber", 370000000000002)  // maybe this is better

 

})

You may also be able to use chained commands if the subject is maintained, which means you have to tweak the should() in the middle

cy.wait("@placeOrder")
  .should('have.property', 'response.statusCode', 200)
  .should('have.property', 'request.body.cardNumber', 370000000000002);

Check out the logged interception object to make sure you have the correct properties and property value types (e.g is cardNumber a number or a string?).

Thank you so much for your help Hiram K! I was able to get it working with:

cy.wait("@placeOrder").then((interception) => {
      console.log(interception);
      cy.wrap(interception.response.statusCode).should("eq", 200);
      cy.wrap(interception.request.body.paymentDetails[0].cardNumber).should(
        "include",
        "370000000000002"
      );
      cy.wrap(
        interception.request.body.paymentDetails[0].defaultPayment
      ).should("eq", false);
    });
Related