How to Test Iframes and Embedded Stripe Payment Elements in Playwright

Elements inside an iframe live in a separate browsing context, so when writing Playwright directly, you typically need to target the iframe and then locate the element inside it using frameLocator().

JavaScript
const paymentFrame = page.frameLocator(
  'iframe[title="Payment form"]'
);

await paymentFrame
  .getByLabel('Card number')
  .fill('4242 4242 4242 4242');

This pattern also applies to payment integrations such as Stripe when the payment UI is hosted inside an iframe.

Leapwork Play handles the iframe context as part of the recording workflow, so you do not need to manually write the iframe-specific locator handling. Record the interaction in Play and work with the generated Playwright test.

Try Leapwork Play →

How do you test an iframe in Leapwork Play?

With direct Playwright, you need to identify the iframe, establish the correct frame context, and then locate the target element inside it.

With Leapwork Play, iframe handling is built into the recording workflow.

In the Engineering example, Play records interactions across ServiceNow's iframe-based interface:

  1. Start recording the workflow in Play.

  2. Interact with the target element normally in the browser.

  3. Play identifies the element in the appropriate iframe context.

  4. Continue recording the user journey.

  5. Run the resulting test in Play.

You do not need to manually add frameLocator() handling for the recorded interaction.

The generated Playwright shown in the demo contains normal Playwright interactions such as:

await page
  .getByRole('link', {
    name: 'Open record: INC0011068'
  })
  .click();

and:

await page
  .getByLabel('State', {
    exact: true
  })
  .selectOption({
    label: 'Resolved'
  });

Play handles the iframe context required for these recorded interactions as part of the workflow.

How does iframe handling work in Playwright?

When working directly in Playwright, the basic pattern is:

Find the iframe → establish its locator context → locate the element → interact

For example, this searches the main page:

await page
  .getByLabel('Card number')
  .fill('4242 4242 4242 4242');

If the field is inside an iframe, establish the frame context first:

JavaScript
const paymentFrame = page.frameLocator(
  'iframe[title="Payment form"]'
);

await paymentFrame
  .getByLabel('Card number')
  .fill('4242 4242 4242 4242');

You generally do not need to click the iframe itself before interacting with its contents.

What about embedded Stripe payment elements?

Stripe payment integrations can render payment UI inside provider-controlled iframes. In those cases, payment fields are not ordinary inputs in your application's top-level DOM.

That means this may not find the payment field:

page.getByLabel('Card number');

Instead, when writing the test directly in Playwright, locate the appropriate frame first:

JavaScript
const paymentFrame = page.frameLocator(
  'iframe[title*="payment"]'
);

Then locate the field inside that frame.

The exact iframe structure and accessible labels depend on the Stripe integration being tested, so use the structure exposed by your application rather than copying a frame selector from another implementation.

How Play simplifies the Playwright iframe workflow

With direct Playwright

With Leapwork Play

Identify the iframe and establish its locator context

Play handles iframe context as part of the recorded workflow

Write frameLocator() handling when required

Record the interaction normally in Play

Write the locator for the element inside the frame

Play generates the underlying Playwright interaction

Maintain the surrounding test workflow

Work with the recorded interaction as a Play test step

Play still uses Playwright underneath and does not remove the browser's iframe boundary. It removes the need for the test author to manually build the iframe-handling logic for the recorded workflow.

How should you test Stripe payment flows?

Use Stripe's test environment and approved test payment details for automated payment tests. Never use real card or payment information.

Focus the test on the outcome the user expects after payment rather than only checking whether values can be entered into the payment fields.

For example:

await page
  .getByRole('button', { name: 'Pay' })
  .click();

await expect(
  page.getByRole('heading', {
    name: 'Payment successful'
  })
).toBeVisible();

A successful payment test should prove that your application responds correctly to the payment outcome, such as showing a confirmation page, updating the order status, or handling a failed payment message.

Because payment journeys can include iframe fields, redirects, 3D Secure authentication, or provider-hosted pages, build your automated test around the real checkout path your users follow. This makes the test easier to understand, more reliable, and more useful for validating the end-user payment experience.

Best practices

  • Use Play's recording workflow for iframe-based interfaces so the iframe context is handled as part of the recorded interaction rather than manually writing frame-handling logic.

  • Use frameLocator() when writing iframe interactions directly in Playwright.

  • Use stable iframe attributes when you need to identify a frame directly.

  • Use Stripe's test environment and approved test payment details.

  • Never put real payment information into automated tests.

  • Validate the application's final business outcome, not only the iframe interaction.

  • Avoid fixed waits while waiting for iframe content to become available.

Troubleshooting

Problem

What to do

Playwright cannot find an element you can see

Check whether the element is inside an iframe.

The iframe exists but the element is not found

Verify that you are using the correct frame and the correct locator inside it.

Several iframes exist

Identify the intended frame using a stable attribute rather than its position.

The payment succeeds but the expected page does not appear

Check whether the payment flow introduces a redirect or authentication step.

A Stripe example works elsewhere but not in your application

Inspect your actual integration; iframe structure and accessible labels can differ.

Frequently asked questions

How do I test an iframe in Playwright?

Use frameLocator() to establish the iframe context and then use normal Playwright locators inside it.

JavaScript
const frame = page.frameLocator(
  'iframe[name="payment"]'
);

await frame
  .getByRole('textbox')
  .fill('test');

How does Leapwork Play handle iframe interactions?

Play handles the iframe context as part of the recording workflow. In the Engineering demonstration, interactions across ServiceNow's iframe-based UI are recorded without the author manually writing frameLocator() handling, while Play generates the underlying Playwright interactions.

How do I test Stripe Elements in Playwright?

When the payment UI is hosted inside an iframe, locate the appropriate Stripe iframe first and then locate the payment field inside it. The exact frame structure depends on your Stripe integration.

Does Leapwork Play bypass iframe or Stripe security?

No. The iframe and payment-provider boundaries still exist. Play complements Playwright by handling the iframe context as part of the recorded authoring workflow.

Can I use real card details in automated Stripe tests?

No. Use Stripe's test environment and approved test payment details.