Recommended Free Tools
Before taking a direct Playwright screenshot, wait for the page’s used fonts and resulting layout to finish: await page.evaluate(() => document.fonts.ready). If the screenshot still shows a fallback font, waiting is not enough: check whether the font request failed or whether the page’s CSS actually applies the expected family, weight, and style.
Wait for fonts before a direct screenshot
Playwright’s page-load state and the browser’s font-readiness signal are separate. A page can reach its load event while a web font is still loading. For a direct page.screenshot(), wait on the page’s document.fonts.ready promise immediately before capture:
As an Amazon Associate I earn from qualifying purchases.
await page.goto(url);
// Wait for fonts used by the current document and the resulting layout.
await page.evaluate(() => document.fonts.ready);
await page.screenshot({ path: 'documentation.png' });
MDN’s documentation for FontFaceSet.ready explains that the promise resolves after the document has loaded the fonts it needs and layout operations are complete. It does not promise that every font declared in CSS has loaded: a face that has not been used may not be part of the readiness wait.
Free tools Windows power users keep installed
One-click scans. No signup required.
Check why the intended font is missing
If the screenshot still looks wrong after the readiness wait, inspect the page rather than adding an arbitrary delay. The cause is specific to the page and cannot be determined from the screenshot code alone.
#1 Best Overall
- Capture the intended page state. Navigate to the exact documentation URL and make sure the relevant text is present and rendered. Conditional or lazy content may not have used its font face yet.
- Inspect font requests and browser errors. Look for failed font-file requests or browser-reported loading errors. Confirm that the
@font-faceURL resolves and that its declared format is supported by the browser environment. - Check the CSS rule applied to the target text. Verify the actual
font-family, weight, and style. A face can load successfully yet not be selected if the requested family or weight does not match the rule used by the text. - Check the relevant face’s loading status and rendered typography. The CSS Font Loading API exposes font-set and face information useful for diagnosis; confirm what the browser has loaded and what the target text actually renders in.
Do not treat document.fonts.check() as proof
document.fonts.check() has limited semantics: it answers whether rendering the specified text would require an unloaded face that could cause a font swap. It is not designed to prove that a particular named face exists or is the face actually rendered. Use it as one diagnostic signal, not as a substitute for checking font status, CSS, and the rendered result. See MDN’s FontFaceSet reference.
Use screenshot assertions for visual comparisons
When the goal is to compare a screenshot with a stored baseline, Playwright Test’s toHaveScreenshot() is different from a direct screenshot: it captures repeatedly until two consecutive images match, then compares the last capture with the baseline. An explicit font-readiness wait still makes the dependency clear, but stable captures do not prove that the intended web font loaded.
Rank #2
await page.goto(url);
await page.evaluate(() => document.fonts.ready);
await expect(page).toHaveScreenshot('documentation.png');
Keep the baseline and comparison environment consistent. Playwright notes that rendered output can vary with the host operating system, browser version, settings, hardware, power source, and headless mode. Review visual changes in that context rather than assuming every pixel difference is a font-loading race. See Playwright’s visual comparisons guide and PageAssertions documentation.
Avoid timing guesses
Do not use waitForTimeout() as the production fix for a missing font. A fixed pause may be too short on a slow run and unnecessarily long on a fast one; Playwright warns against waiting for timeouts in production. networkidle is also discouraged for testing when a condition tied to the work under test is available. Waiting for document.fonts.ready targets font readiness directly; if the font request fails, diagnose and correct that failure instead of extending the wait. See the Playwright Page API.
Or skip the browser setup
ScreenshotNeo offers a screenshot API and MCP server. For an API capture, one GET request can return an image or PDF; for this example, request a screenshot of the documentation page:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/docs -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; 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.
Frequently Asked Questions
Why does my Playwright screenshot use a fallback font?
The font may not have finished loading, its request may have failed, or the CSS applied to the text may request a different family, weight, or style. Wait for document.fonts.ready, then inspect requests, errors, CSS, and the rendered face.
Does document.fonts.ready load every font declared in CSS?
No. It concerns fonts used by the document and completion of layout operations; unused declared faces are not necessarily loaded.
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.




