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.
$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.
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.
$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.
// 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.