0

Our company is switching to Cybersource & tokenized credit cards. The token is new each time.

I'm trying to find a way to store the token from the request and reference it to assert it's correct.

Example of the request:

request:
body:
accountRegistrationPreferences: {email: ''}
paymentDetails: Array(1)
0:
billingAddress: {address: {…}, contactInfo: {…}, personalInfo: {…}}
cardId: "eusercc42210010"
tokenDetails:
referenceId: "bcc8c381-79d6-4a83-a10a-d67e2d585268"
token: 

"eyJraWQiOiIwOFJORkptMWFIVlhhZUhRaUJrNHZNRFF1MGt3WW9kNCIsImFsZyI6IlJTMjU2In0.eyJkYXRhIjp7ImV4cGlyYXRpb25ZZWFyIjoiMjAzMCIsImV4cGlyYXRpb25Nb250aCI6IjAzIn0sImlzcyI6IkZsZXgvMDgiLCJleHAiOjE2NDQ0MzE2ODQsInR5cGUiOiJtZi0wLjExLjAiLCJpYXQiOjE2NDQ0MzA3ODQsImp0aSI6IjFFNVpSSEQzTFBaUzM0NUdIVVVUUjJQRjdFNzBZSDlKN1dTQjRTWEhTVEJEN08xTFRFUzg2MjA0MDk0NEFBNjIiLCJjb250ZW50Ijp7InBheW1lbnRJbmZvcm1hdGlvbiI6eyJjYXJkIjp7ImV4cGlyYXRpb25ZZWFyIjp7InZhbHVlIjoiMjAzMCJ9LCJzZWN1cml0eUNvZGUiOnt9LCJleHBpcmF0aW9uTW9udGgiOnsidmFsdWUiOiIwMyJ9fX19fQ.bCR73pMD9eXILtZHQRrmqgzcLqI_QCTEVtnQXNPJLOk-RxMUar8LbC1BS59G6FpynCI2rvJVMPixjtes2WRcnM77cjOlTarNM4-VnAJnqKluXy2jx5Hgtn_OrT7aSaS8NOoSyYzwPFlbkqsBMV5oT5kmiHZ8Qn4qBnga8sEYmPFgzoAUUnQ6uWLN1ZkZnKCO8uizZ_HaKUjdUQCyRzgWbtKfTctD9aAi5AcSNgAVbWTV_gt155jFa11v8mLF4iaqA3bLdJfEh4lu9HxB17sOShZBoZvxEQ3fN8gDkk4f56VlswB-aN3J5QFI7me36pgwY5khAhYrFma1o79V-b2KYw"

type: "tokenizedCreditCard"

Here's the Cypress test

  it("User clicks confirm & pay button to complete order", () => {
cy.intercept("/api/checkout/payandcommit?*").as("placeOrder");
cy.placeOrderAndPay();
cy.wait("@placeOrder").then((interception) => {
  console.log(interception);
  // Order status should equal 200
  cy.wrap(interception.response.statusCode).should("eq", 200);
  // Check payment details card type
  cy.wrap(interception.request.body.paymentDetails[0].type).should(
    "include",
    "tokenizedCreditCard"
  );
  cy.wrap(
    interception.request.body.paymentDetails[0].tokenDetails.token
  ).should("include", token);
  // Check request to ensure delivery charge is passed at £0 due to Unlimited membership.
  cy.wrap(
    interception.response.body.response.order.orderPriceInfo.shipping
  ).should("eq", 0);
  // Ensure standard delivery is returned in the order response.
  cy.wrap(
    interception.response.body.response.order.shippingDetails[0]
      .shippingMethod.type
  ).should("include", "standard");
});

});

This is the part I'm struggling with:

cy.wrap(
interception.request.body.paymentDetails[0].tokenDetails.token).should("include", token);

How can I store the token value that's changed each time so I can assert on it?

Is this possible? Any help would be amazing, I'm a bit of a doob and learning.

Billy Bailey
  • 53
  • 1
  • 10
  • 1
    Just a suggestion, you may want to split your request and response assertions into separate `.then()` to make it more readable. You can also lose all the `cy` commands inside your `.then()` block(s) since they are only assertions and use BDD assertions. – jjhelguero Feb 09 '22 at 22:05

1 Answers1

3

To test that the response has a token property,

cy.wrap(interception.request.body.paymentDetails[0].tokenDetails)
  .should('have.property', 'token')
//or
cy.wrap(interception.request.body.paymentDetails[0])
  .should('have.deep.property', 'token')  // this assertion searches the object

To store the token an alias might be used

cy.wrap(interception.request.body.paymentDetails[0].tokenDetails.token)
  .as('token')

// Later in test
cy.get('@token').then(token => {
  expect(token).to.eq(expectedToken)
})

The token alias gets a new value every time you use .as('token'), so there's no problem with the changing token value.

Fody
  • 23,754
  • 3
  • 20
  • 37
  • 1
    Hey, thanks for the quick answer! This did the trick: cy.wrap(interception.request.body.paymentDetails[0].tokenDetails.token) .as("token") .then((token) => { expect(token).to.eq(token); }); – Billy Bailey Feb 09 '22 at 18:51
  • 1
    A bit too quick - I didn't look at your response structure close enough. Need to update. – Fody Feb 09 '22 at 18:53
  • No problem, thanks for your help! It's been a long day. I edited the above comment to say this is now resolved. – Billy Bailey Feb 09 '22 at 18:58
  • 1
    In your snippet above, you don't need the `.as("token")` if you are doing all your assertions in the `.then()`. You only need an alias if you want to keep the value for later in the test. – Fody Feb 09 '22 at 19:01
  • So this `expect(token).to.eq(token)` is not really testing anything - both expected value and actual value are the same, so it will always pass. – Fody Feb 09 '22 at 19:03
  • if Fody's answer responded to your question, you should mark it as accepted. It helps others also. – HienPham Apr 07 '22 at 09:20