Recommended Free Tools
Get the iframe’s Puppeteer Frame object, then create and use the locator from that frame: frame.locator(selector). A locator created from the page’s main frame will not automatically search inside an iframe.
Find the iframe’s Frame object
Puppeteer represents each frame as its own Frame context. Use page.frames() to inspect the current page’s frames, or walk the frame tree with page.mainFrame() and childFrames(). The Puppeteer Frame API also shows how to inspect a frame’s associated iframe element and its attributes.
If the iframe URL contains a distinctive path, you can use it to find the frame:
const frame = page.frames().find(candidate => candidate.url().includes('/embedded-form'));
if (!frame) throw new Error('Form iframe not found');
Choose a property that identifies the intended frame on the page you automate; a URL fragment is only reliable if it is distinctive and stable for that page. If frames are nested, identify the correct parent frame and inspect its childFrames() instead of assuming the target is a direct child of the main frame.
#1 Best Overall
Create and use a locator in the frame
Call locator() on the frame you found. For example, this fills an email field and clicks the submit button inside that frame:
const frame = page.frames().find(candidate => candidate.url().includes('/embedded-form'));
if (!frame) throw new Error('Form iframe not found');
await frame.locator('input[name="email"]').fill('reader@example.com');
await frame.locator('button[type="submit"]').click();
Use frame.locator(selector) for the element-selection context. Puppeteer recommends locators for selecting elements and interacting with them. As described in its Page interactions guide, locators wait for elements and relevant action preconditions. For a click, those checks include being in the viewport, visibility, enabled state, and a stable bounding box across consecutive animation frames.
Rank #2
The interaction guide documents fill() for inputs, textareas, selects, and contenteditable elements. It also supports boolean values for checkboxes, radio buttons, and switches, for example:
await frame.locator('input[type="checkbox"]').fill(true);
Choose a selector that fits the page
Frame.locator() accepts CSS selectors and Puppeteer’s supported selector syntax, including text, accessibility role and name, XPath, and supported combinations involving shadow roots. See the interaction guide for locator syntax.
- Use stable attributes such as a form control’s
namewhen available. - Use an accessible role and name when they clearly identify the control.
- Use text or XPath when those are a better fit for the page structure.
These are practical selector choices, not a guarantee that a site will keep its markup unchanged. Selectors should match the actual iframe content, not the parent page.
Use lower-level frame queries when needed
If a locator does not cover the operation you need, Puppeteer also provides lower-level frame APIs such as waitForSelector() and ElementHandle. The Frame API documents frame.$(), which returns a handle for the first match or null.
Rank #4
| Method | Useful when | Readiness behavior or result |
|---|---|---|
frame.locator(selector) |
You want to select and interact with an element using Puppeteer’s recommended locator API. | Waits for the element and relevant action checks; a locator is not itself an ElementHandle. |
frame.$(selector) |
You need the first matching element as a handle or need to check whether a match exists. | Returns an ElementHandle or null. |
frame.waitForSelector(selector) |
You need to wait for a selector using the lower-level API. | Use the resulting handle when the next operation requires one; consult the API for its behavior and options. |
For API details and supported options, consult the Frame reference and interaction guide.
Handle frames that change
Frames can attach, navigate, or detach. On pages that replace or navigate an iframe dynamically, a previously found frame may no longer be the frame containing the target element. Find the intended frame after the relevant page change, check that it exists, and then create the locator from that frame.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
Troubleshoot iframe locators
- The frame lookup returns no result: The iframe may not have loaded yet, or the identifying URL fragment may not match. Inspect
page.frames()and verify the frame’s URL or associated iframe element before selecting it. - The locator cannot find the element: Confirm that you created the locator from the target
Frame, not the page or a different frame. Check the selector against the iframe’s current content. - The frame is found but the element is missing after navigation: The iframe may have navigated or been replaced. Locate the current frame again after the change.
- A nested iframe is involved: Walk from the correct parent using
childFrames(), then create the locator in the child frame that contains the element. - An action does not proceed: A locator waits for its action’s readiness conditions. Check that the element is visible, enabled, in the viewport, and not continually moving when clicking.
- You need an element handle: Use a lower-level frame query such as
frame.$()orwaitForSelector()for operations that require anElementHandle.
Or skip the browser setup
If you need a rendered screenshot rather than browser automation, ScreenshotNeo can return an image or PDF with one GET request. Its clean-shot flow accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, with the page verdict and billed status reported in response headers. ScreenshotNeo also offers an MCP server for AI agents, with tools including take_screenshot, get_page_info, and capture_pdf.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Learn more at ScreenshotNeo, or sign up free for 1,000 screenshots a month, no card required.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

