More fun with Payments

I ran into the issue where we really don’t need to keep adding credit card details if they already exist for a user. To get around this, I did the following.

Add another command file (/support/paymentCommands.js) containing

import { getTestCreditCard } from '../utils/ccUtil'
Cypress.Commands.add('addRandomCard', () => {
    cy.getWithinIframe('[name="cardnumber"]', {
      timeout: 5000,
    }).type(getTestCreditCard(), { force: true }) //Card Number field
    //Card Number field
    cy.get('[name="ccInformation.nameOnCard"]') //Name on Card field
      .focus()
      .clear({ force: true })
      .type('[REDACTED]') //FName
      .type('[REDACTED]') //LName
    cy.get('[class="__PrivateStripeElement"]')
      .eq(1)
      .within(() => {
        cy.getWithinIframe('[name="exp-date"]').type('1232') // EXP Date field
      })
    cy.get('[class="__PrivateStripeElement"]')
      .eq(2)
      .within(() => {
        cy.getWithinIframe('[name="cvc"]').type('9871') // CVV field
      })
    cy.get('[name="ccInformation.zipCode"]')
      .clear({ force: true })
      .type('78701') // ZIP CODE field
    cy.get('[class*="switch MuiSwitch-sizeSmall"]').click() //SAVE CARD
  })

paymentCommands.js was added to the index.js to prevent the need for the following line. If you don’t do that (which makes the commands available globally) then you have to add this somewhere near the top of the script. Note that with the CVV field, if the card is the type that has a three-digit CVV, only three digits will be typed. If four digits are required, the fourth is accepted (the field caps the input based on the card type)

import '../../../../support/paymentCommands' 

(The above import is not required if the appropriate command file is added to index.js. See https://www.mikefettes.com/blog/adding-additional-custom-commands for more info)

Then within the test itself:

cy.get(
  '[class=
   "MuiInputBase-input MuiFilledInput-input 
    MuiInputBase-inputAdornedEnd MuiFilledInput-inputAdornedEnd"
    ]',).click({ force: true })
 cy.get('[class*="MuiFilledInput-inputAdornedEnd"]').click({ force: true })
 cy.get('[class*="__card-field"]')
   .then(($existingCards) => {
      if ($existingCards.text().includes('****')) {
        cy.contains('****').eq(0).click({ force: true })
      } else {
        cy.contains('ADD A NEW CARD').click({ force: true })
          .wait(1500)
        cy.addRandomCard()
        }
})

What the 2nd piece of code does is look for the 1st instance of ‘****’ indicating a saved card. If none exists, the addRandomCard() command is called and one of the CCs from the pool of valid test cards (from ccUtils.js) is used. See also https://www.mikefettes.com/blog/randomizing-stripe-test-credit-cards

Previous
Previous

Dynamically setting the environment under test

Next
Next

Using cy.writeFile and cy.readFile to capture element text