Recommended Free Tools
Navigate with page.goto(), wait for the readiness condition your page actually needs, then call page.screenshot({ fullPage: true }). For a general page capture, Playwright’s load event is a sensible baseline and is already the default for page.goto():
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({ path: 'full-page.png', fullPage: true });
If the page fills in important content asynchronously after load, wait for a locator that represents that content before taking the screenshot.
As an Amazon Associate I earn from qualifying purchases.
Capture a full-page screenshot after navigation
In Playwright’s JavaScript API, fullPage: true captures the full scrollable page rather than only the visible viewport. The path option saves the image to a file. Without path, page.screenshot() returns image data as a buffer, which you can pass to another part of your program.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({ path: 'full-page.png', fullPage: true });
The explicit waitUntil: 'load' documents the point at which this example takes the screenshot. It is not required for the default behavior: page.goto() defaults to waiting for the load event.
#1 Best Overall
When navigation has already happened
If you need to wait after navigating by another method, use page.waitForLoadState('load'). It requires a committed navigation; if the requested state has already occurred, the call resolves immediately.
await page.waitForLoadState('load');
await page.screenshot({ path: 'full-page.png', fullPage: true });
Choose the right readiness condition
“Finished loading” can mean different things. The browser lifecycle event that suits a simple document may not guarantee that an application has finished rendering the specific content you want to capture.
Rank #2
| Condition | What it waits for | Use it when |
|---|---|---|
domcontentloaded |
The HTML has been parsed and the DOMContentLoaded event has fired. |
Your capture needs the parsed document but does not depend on later resources. |
load |
The page’s load event has fired. This is the default for page.goto(). |
You want a general baseline that allows document resources to load. |
| Locator or web assertion | A chosen UI element or application condition is satisfied. | Content appears asynchronously, or a particular section must be present before capture. |
networkidle |
There have been no network connections for at least 500 ms. | Use cautiously: Playwright discourages relying on this for tests, and pages with ongoing background connections may not reach it. |
These conditions are not a universal speed ranking. Choose according to what must be present in the image. The Page API also lists commit, which means the response has been received and document loading has started; it does not mean the page has completed loading.
Wait for asynchronous content explicitly
A page can render or fetch important content after its load event. Wait for a locator that indicates the content you need, then capture. Replace the example locator with one that is meaningful for the target application:
await page.goto('https://example.com');
await page.getByRole('main').waitFor({ state: 'visible' });
await page.screenshot({ path: 'full-page.png', fullPage: true });
Playwright’s Page API documentation discourages using networkidle for tests and says to use web assertions to assess readiness instead: Playwright Page API. A fixed delay such as page.waitForTimeout() is also discouraged in production tests because timer-based tests are inherently flaky. Prefer a visible application condition over guessing how many milliseconds the page needs.
Use a screenshot assertion when visual stability matters
page.screenshot() takes a screenshot when called; it does not promise to wait for two identical renders. Playwright Test’s expect(page).toHaveScreenshot() has different behavior: it takes screenshots until two consecutive screenshots match, then compares the last one with the expected image. See the Playwright visual comparisons documentation.
Rank #4
Visual comparisons can vary with the host operating system, browser version, settings, hardware, power source, and headless mode. Keep the baseline-generation and comparison environments consistent when visual diffs matter.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsHandle common capture problems
- The screenshot is only the viewport: Set
fullPage: truein the screenshot options. - Content is missing even though navigation completed: The page may render it asynchronously after the lifecycle event. Wait for a locator or web assertion tied to the content you need.
waitForLoadState()resolves immediately: This is expected if the requested state has already occurred. If there has been no committed navigation, use a navigation method first or wait for the appropriate navigation.networkidlenever arrives: Ongoing network activity can prevent the quiet period. For a test, replace it with a meaningful locator or assertion that represents readiness.- Visual diffs vary between runs or machines: Check whether browser, operating system, rendering settings, hardware, or headless mode differ, and use a consistent comparison environment.
- A timer-based wait is intermittent: A fixed delay can be too short on a slow run and unnecessarily long on a fast one. Wait for an application-specific condition instead.
Or skip the browser setup
If you need an image or PDF without managing a Playwright browser, ScreenshotNeo provides a website screenshot API and MCP server. Its one-call GET endpoint can return a screenshot or PDF:
Quick Recap
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo removes supported cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Its MCP server lets AI agents use screenshot tools. The Free plan includes 1,000 shots per month with no card, and paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free plan.
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.




