Interact inside an iframe

Scope a locator to a frame with frameLocator, then act and assert inside it.

An iframe is a separate document embedded in the page. A page-level locator searches the host document, so it never sees the elements inside the frame. Scope your locators to the frame first with frameLocator(), then act and assert as usual.

Scope a locator to the frame

Call frameLocator() with a selector that matches the <iframe> element. It returns a frame locator whose locator(), getByRole(), and other getBy* methods resolve inside that frame.

php
$context = Playwright::chromium();
$page = $context->newPage();
$page->goto('https://app.example.test/checkout');

$frame = $page->frameLocator('iframe[name="card"]');

$frame->getByLabel('Card number')->fill('4242424242424242');
$frame->getByRole('button', ['name' => 'Pay'])->click();

frameLocator() takes a single string selector. Options go in an array on the getBy* calls, as everywhere else in the API.

Assert inside the frame

Assertions on a frame locator poll the same way page assertions do. Build the locator from the frame, not the page.

php
expect($frame->getByText('Payment approved'))->toBeVisible();

Nest frame locators for a frame in a frame

When the target frame is itself inside another frame, chain the calls. Each frameLocator() step enters one more level.

php
$inner = $page
    ->frameLocator('iframe[name="outer"]')
    ->frameLocator('iframe[name="inner"]');

$inner->getByRole('textbox', ['name' => 'Coupon'])->fill('SAVE10');

The page-level locator trap

A locator built from $page searches the host document only. If the element lives in the frame, the locator matches nothing and the action times out.

php
// Wrong: the field is inside the iframe, so this never resolves.
$page->getByLabel('Card number')->fill('4242424242424242');

// Right: scope to the frame first.
$page->frameLocator('iframe[name="card"]')->getByLabel('Card number')->fill('4242424242424242');

Expected result

The action and assertion run inside the frame document, not the host page. A successful payment, embedded form confirmation, or iframe-local message should be asserted through the frame locator.

Go next

← All recipes