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().
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.
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:
-
Start recording the workflow in Play.
-
Interact with the target element normally in the browser.
-
Play identifies the element in the appropriate iframe context.
-
Continue recording the user journey.
-
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:
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:
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 |
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.
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.