Free tools Windows power users keep installed
One-click scans. No signup required.
To capture an element inside an iframe, use Playwright’s frameLocator() to enter the frame, locate the element, and call screenshot() on that locator. For example:
await page
.frameLocator('#my-iframe')
.getByRole('button', { name: 'Submit' })
.screenshot({ path: 'submit-button.png' });
This saves an image of the button, not the entire iframe document. Choose the screenshot API based on the scope you need: an element inside the frame, the iframe’s box, the page viewport, or the full page.
Capture an element inside an iframe
Playwright’s frameLocator() scopes subsequent locators to an iframe. Use a selector that identifies the frame, then locate the desired content within it. Prefer accessible locators such as getByRole() when the page exposes a useful role and name.
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
try {
await page.goto('https://example.com');
await page
.frameLocator('#my-iframe')
.getByRole('button', { name: 'Submit' })
.screenshot({ path: 'submit-button.png' });
} finally {
await browser.close();
}
Replace https://example.com, #my-iframe, and the button locator with values that match your page. The frame selector must identify one iframe for this operation; Playwright frame locators are strict. The screenshot is clipped to the target element’s bounds.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
Use a CSS selector inside the frame
If the target has no convenient accessible role or name, use a CSS locator within the frame:
await page
.frameLocator('iframe[name="embedded"]')
.locator('.receipt-total')
.screenshot({ path: 'receipt-total.png' });
The selector passed to frameLocator() identifies the iframe in the parent page. The following locator is evaluated inside that iframe’s document. This distinction matters: a selector for an embedded element does not select it from the top-level page.
Convert an iframe locator to a frame locator
If you already have an iframe locator, call contentFrame() to get a frame locator and continue from there:
const iframe = page.locator('iframe[name="embedded"]');
const target = iframe.contentFrame().getByRole('button', { name: 'Submit' });
await target.screenshot({ path: 'submit-button.png' });
This is useful when you want to define or reuse the iframe locator separately from the target locator. See Playwright’s FrameLocator API for the frame-locator methods.
Recommended Free Tools
Choose the screenshot scope
These methods produce different images. Select one according to what you need to inspect or save.
Rank #2
| What to capture | Playwright call | What the image contains |
|---|---|---|
| An element inside an iframe | frameLocator(...).locator(...).screenshot() |
The matched embedded element’s bounds. |
| The iframe element’s box | page.locator('iframe...').screenshot() |
The iframe owner element’s box in the parent page, not a separate full-document rendering of its contents. |
| The page viewport | page.screenshot() |
The page screenshot using the page screenshot API’s default scope. |
| The full scrollable page | page.screenshot({ fullPage: true }) |
A full-page screenshot rather than only the viewport. |
Locator screenshots are clipped to the matched element’s size and position. If the target is inside a scrollable container, the screenshot reflects the content visible at that container’s current scroll position. Covered portions do not become visible merely because you take a screenshot. Page-level screenshots use a separate API; consult the Page API and Screenshots guide for page and full-page capture behavior.
Capture the iframe box
To screenshot the iframe owner element rather than a particular embedded element, select the iframe from the parent page:
await page
.locator('iframe[name="embedded"]')
.screenshot({ path: 'iframe-box.png' });
This captures the iframe element’s box. It is not a request to render the embedded document as a separate full-page image. For a specific embedded control or region, use a frame locator and screenshot the target inside the frame.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCapture the page viewport or full page
Use page.screenshot() when the scope is the page rather than an individual embedded element:
await page.screenshot({ path: 'viewport.png' });
await page.screenshot({ path: 'full-page.png', fullPage: true });
A page screenshot may show the iframe as it appears in the page, but it does not replace frame-aware targeting when you need to locate a particular control inside the iframe.
Save an image and keep captures repeatable
A locator’s screenshot() method returns image data as a buffer; supplying path also writes the image to a file. Locator screenshot options include image type, quality, scaling, animation handling, masking, and a stylesheet to apply during capture. The exact options supported can depend on the installed Playwright version, so check the Locator API for that version before relying on a particular option.
For example, where supported by your installed version, you can use screenshot options to reduce animation-driven differences or mask a changing region. An illustrative call is:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →await page
.frameLocator('#my-iframe')
.getByRole('button', { name: 'Submit' })
.screenshot({
path: 'submit-button.png',
animations: 'disabled',
caret: 'hide'
});
Check the installed version’s API documentation for option names and accepted values. If an option is not recognized, update the code to match that version rather than assuming every release supports the same configuration.
Use a visual assertion when you are testing for changes
Saving a screenshot and checking visual stability are different tasks. If you are writing a Playwright Test visual regression check, use expect(locator).toHaveScreenshot() rather than treating an image file alone as an assertion:
import { test, expect } from '@playwright/test';
test('embedded submit button matches its expected appearance', async ({ page }) => {
const submit = page
.frameLocator('#my-iframe')
.getByRole('button', { name: 'Submit' });
await expect(submit).toHaveScreenshot('submit-button.png');
});
The screenshot assertion waits for two consecutive locator screenshots to match before comparing the final capture with the expectation. Playwright documents this assertion for the Playwright Test runner; it is not a general replacement for saving a screenshot in a script using only the browser API. Details are in the LocatorAssertions API.
Rank #4
Troubleshoot iframe screenshot failures
The frame selector matches more than one iframe
Frame locators are strict. If the selector resolves to multiple frames, an operation such as screenshot() throws rather than silently choosing one. Narrow the selector using a distinguishing attribute, or explicitly select the intended match.
// Prefer a selector that uniquely identifies the iframe.
const target = page
.frameLocator('iframe[name="payment-widget"]')
.getByRole('button', { name: 'Pay now' });
await target.screenshot({ path: 'pay-button.png' });
Do not make a broad selector appear unique by accident. Confirm the attribute corresponds to the frame you intend to capture.
The target is not ready, or detaches before capture
Locator screenshots perform actionability checks and scroll the target into view. A locator can still fail if the element detaches from the DOM before capture. Use a stable locator and allow Playwright’s locator behavior to resolve the element at action time instead of retaining a fragile element reference. If the page updates asynchronously, wait for a meaningful ready condition before taking the screenshot, such as the appearance of the target element.
The image is cropped or a portion is missing
An element screenshot captures the matched element’s bounds; it does not expand to include surrounding content. A scrollable target shows only its current visible content, and an overlay can obscure the target. Decide whether you need the iframe box, an embedded element, or the whole page, then use the corresponding API. If the target is covered, address the page state or overlay rather than expecting screenshot clipping to reveal what is underneath.
The output differs between runs
Dynamic content, animation, a blinking caret, or changing regions can make images vary. Where the installed Playwright version supports them, locator screenshot options for disabling animations, hiding the caret, masking elements, or applying a stylesheet can help make a capture more repeatable. For automated visual checks, use the screenshot assertion workflow and follow its documented expectation behavior.
An example uses ElementHandle screenshot
Older code may call ElementHandle.screenshot(). Playwright marks that API as discouraged and recommends locator-based locator.screenshot() instead. See the ElementHandle API and prefer locators for new code.
Or skip the browser setup
If you need a screenshot from a URL without writing and maintaining a local Playwright capture flow, ScreenshotNeo provides a website screenshot API and MCP server for developers. A GET request returns a PNG, JPEG, WebP, or PDF. For example, save a WebP screenshot with cURL:
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 documentation for API parameters and output options. The API captures a web page from a URL; it is not a substitute for Playwright when you need to run browser-side test logic or target an element inside an iframe with a frame-aware locator.
- Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each of these cleanup steps can be turned off.
- Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Responses report the page verdict and billing status in headers.
- An MCP server exposes
take_screenshot,get_page_info, andcapture_pdftools for AI agents and MCP clients. - The Free plan includes 1,000 screenshots per month with no card required; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesFrequently Asked Questions
Can Playwright take a screenshot of an iframe’s entire document?
The documented locator workflow captures a matched element’s bounds, while page screenshots capture the page or full page. The cited APIs do not establish a separate full-document screenshot method for an iframe.
Can I use `toHaveScreenshot()` in a plain Playwright script?
Playwright documents `toHaveScreenshot()` as an assertion for the Playwright Test runner. Use `locator.screenshot()` to save an image in a browser script.
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.

