Back to All Questions
Question 86 of 100
Interactions
Intermediate
How does Playwright support iframe interactions?
The Answer
Use `page.frameLocator('selector')` to scope locators inside an iframe. This creates a persistent tunnel to the frame and supports all standard Playwright locators within that scope.
Deep Dive Explanation
The `frameLocator` approach is superior to the old `page.frames()` API because it's lazy (re-queries on each action) and works with Playwright's auto-waiting. The old `frame.waitForSelector()` approach is legacy. Always prefer `frameLocator` for new tests.
example.spec.ts
// Basic iframe interaction
const frame = page.frameLocator('iframe#payment-frame');
await frame.getByLabel('Card Number').fill('4111111111111111');
await frame.getByLabel('Expiry').fill('12/26');
await frame.getByLabel('CVC').fill('123');
await frame.getByRole('button', { name: 'Pay' }).click();
// Nested iframes
const innerFrame = page
.frameLocator('iframe#outer')
.frameLocator('iframe#inner');
await innerFrame.getByRole('textbox').fill('test');
// Access frame by URL
const frame2 = page.frame({ url: /payment-gateway/ });
if (frame2) {
await frame2.fill('#card', '4111111111111111');
}