How can I test stripe elements with Cypress. I am trying to target the Cart Input, Cart Cvc and Cart Expiry. I found two article that I tried to follow - https://medium.com/swinginc/testing-stripe-integration-with-cypress-3f0d665cfef7 and one that comes from stripe - https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress maybe first the markup:
<section className="w-full" data-testid="credit-card">
<span className="relative flex items-center justify-between">
<ChipIcon className="h-9 w-9 text-midnight" strokeWidth={1} />
<RssIcon className="rotate-90 text-midnight" />
</span>
<span className="capitalize font-anonymous text-midnight text-xs">
card number
</span>
<CardNumberElement
onChange={({ complete }) => {
mustCorrectError && setPaymentState({ type: "InitialState" });
handleCardInputStateChange(complete, "cardNumber");
}}
className="border border-white text-white p-2"
options={commonInputStyles}
/>
<div className="flex justify-between items-end mt-2">
<div>
<span className="uppercase font-anonymous text-midnight text-xs">
cvc
</span>
<CardCvcElement
onChange={({ complete }) => {
mustCorrectError && setPaymentState({ type: "InitialState" });
handleCardInputStateChange(complete, "cvc");
}}
className="border border-white text-white p-2 w-12"
options={{ ...commonInputStyles, placeholder: "CVC" }}
/>
</div>
<div>
<span className="capitalize font-anonymous text-midnight text-xs">
valid thru
</span>
<CardExpiryElement
onChange={({ complete }) => {
mustCorrectError && setPaymentState({ type: "InitialState" });
handleCardInputStateChange(complete, "expiration");
}}
className="border border-white text-white p-2 w-20"
options={{
...commonInputStyles,
placeholder: "MM / YY",
}}
/>
</div>
<EuroIcon className="text-midnight" />
</div>
</section>
here I have a component and in this component I have three Stripe Element Components - Card number, Cvc and Expiry and following the above mentioned artcile I have created custom command
Cypress.Commands.add("getStripeElement", (fieldName, index) => {
if (Cypress.config("chromeWebSecurity")) {
throw new Error(
"To get stripe element `chromeWebSecurity` must be disabled"
);
}
const selector = `input[data-elements-stable-field-name="${fieldName}"]`;
cy.get("iframe")
.eq(index)
.its("0.contentDocument")
.should("exist")
.its("body")
.should("not.be.undefined")
.then(cy.wrap)
.find(selector);
});
The only tweak I made is adding index to target the iframe I am after (because cypress finds 5, it should 3 however, when I increment index above 2 it changes the error from not finding nothing within iframes body to not finding body). Even if I look for the div#root which is the most outer wrapper within body it does not find it. This is my test:
it("User can successfully purchase after filling the form correctly",
() => {
cy.getByData("credit-card").getStripeElement("cardNumber", 2);
// AssertionError
// Timed out retrying after 4000ms: Expected to find element: input[data-elements-stable-field-name="cardNumber"], but never found it. Queried from element: <body>
}
);
Thanks