Search code examples
reactjslaravelstripe-paymentscypress

Cypress testing Stripe elements


I have a problem testing stripe elements with cypress. Stripe elements are setup in React, like this:

import {loadStripe} from '@stripe/stripe-js';
import {
    PaymentElement,
    Elements,
    useStripe,
    useElements,
    ExpressCheckoutElement,
    PaymentMethodMessagingElement,
} from '@stripe/react-stripe-js';

...

<Elements stripe={stripePromise} options={options}>
    <Payments user={props.customer ? props.customer : props.auth.user} data={props} formData={formData} setStep={(e)=>setStep(e)} setCheckoutError={(e) => setCheckoutError(e)}/>
</Elements>

When I run my server in localhost, stripe elements are displayed without any errors, end everything work.

Problem occurs when I run my e2e tests in Cypress. I'm using Cypress "cypress": "12.17.4"and "cypress-plugin-stripe-elements": "^1.0.2" plugin to easier interact with elements. I'm running tests in Chrome v120 browser. Everything loads up, and as soon as Stripe elements should be displayed, I get a blank page:

blank elements page

Upon inspecting my console, I notice these errors:

network errors

Specifically I see this error:

Uncaught TypeError: Cannot read properties of undefined (reading 'queuedMessages')

I'm wondering what is the cause of this error, and how to bypass this, so my stripe elements load on the page.

For reference, here's my cyprees test that is running:

it.only("User can create a supplement order with valid data", () => {
    cy.visit("http://127.0.0.1:8000/login");
    cy.regularLogin(); //login user to the account
    cy.addSupplementToBasketFromShop(); //add item to basket and go to checkout page, where elements should be loaded
    cy.get('#supplement_terms').click({force: true});
    cy.get('button[type="submit"]._button.secondary').click();
});

The test is running successfully, and elements are loaded for a brief moment. Then, these requests appear, and stripe elements are invisible:

stripe requests

If you need any additional info, please let me know in the comments.


Solution

  • Stripe's doc about automated testing indicates you should mock this instead of loading Elements, and that:

    Frontend interfaces, like Stripe Checkout or the Payment Element, have security measures in place that prevent automated testing

    I would say you might want to consider skipping loading elements in these test sequences by detecting the environment, for example.