What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Wait for the page’s used fonts and the layout work that follows them before capturing a screenshot. In Playwright, the direct fix is await page.evaluate(() => document.fonts.ready). If differences remain, check the actual font files and keep the browser, operating system, viewport, and device scale factor consistent between baseline creation and comparison.
Wait for fonts before taking the screenshot
The browser exposes the document’s font-loading state through document.fonts. Its ready promise resolves after fonts used by the document have loaded, associated layout operations have completed, and no further font loads are needed. Await it after navigation and before capturing:
As an Amazon Associate I earn from qualifying purchases.
import { test, expect } from '@playwright/test';
test('page screenshot uses loaded fonts', async ({ page }) => {
await page.goto('https://example.com');
// Wait for used fonts and the layout work associated with them.
await page.evaluate(() => document.fonts.ready);
await expect(page).toHaveScreenshot();
});
This is a readiness wait, not a guarantee that every font declared in CSS loaded. Unused faces may remain unloaded, and optional faces that did not load in time may not be used. The browser’s font-loading behavior is documented by MDN’s FontFaceSet.ready reference.
Wait again after a state change that reveals new text
If a click navigates to another route, opens a panel, or reveals content that uses a different font face, wait after that change too. The font state relevant to the initial page is not necessarily sufficient for newly revealed content.
#1 Best Overall
await page.getByRole('button', { name: 'Open details' }).click();
await page.getByText('Additional details').waitFor();
await page.evaluate(() => document.fonts.ready);
await page.screenshot({ path: 'details.png' });
For a raw page.screenshot(), use the same wait immediately before capture. For Playwright Test’s toHaveScreenshot(), put the wait before the assertion.
Understand what Playwright’s screenshot retry does
toHaveScreenshot() waits until two consecutive screenshots of the page match, then compares the final screenshot with the expected baseline. That retry can help with unstable rendering, but it does not prove that the intended web font loaded. When fonts are the suspected cause, wait for document.fonts.ready explicitly. See Playwright’s visual comparisons guidance.
Rank #2
Diagnose differences that remain
| Symptom | Likely cause | First check |
|---|---|---|
| Text first appears in a fallback face, then shifts | A web font loaded after the initial render | Await document.fonts.ready after navigation and after UI changes that reveal text. |
| Many glyph shapes differ even after the font wait | Different font file or version, fallback availability, or browser/OS rendering | Compare loaded font resources and use the same browser and CI environment. |
| Text wraps differently and moves nearby elements | Different glyph metrics, viewport, or device scale factor | Hold the viewport, scale factor, browser, and font files constant. |
| Only small edge or antialiasing differences remain | Rendering-stack or hardware variation | Compare in the baseline’s environment before considering a tolerance change. |
Check the actual font, not just readiness
document.fonts.ready tells you when the document’s current font-loading and layout work has settled. It does not establish that a particular named font exists or that it supplied every glyph. Inspect the element’s computed font styling and the browser’s font resource loading when the typeface itself is in question.
Use document.fonts.check() cautiously. MDN explains that it is not designed to prove that a specific font style can be rendered or that a particular font exists. It asks whether rendering the supplied text would require an unloaded face in the document’s font set; a missing or nonexistent requested face can still yield true. See MDN’s FontFaceSet.check reference.
Rank #3
Control the rendering environment
A font wait cannot make separate operating systems or browser builds render identically. Playwright identifies the host operating system, browser version, settings, hardware, power source, and headless mode as possible sources of screenshot variation. Generate and compare baselines in the same environment; in CI, pin the browser and image, keep viewport and device scale factor consistent, and make the same font files available. Playwright’s recommendation is to use the same environment where the baseline was generated: Visual comparisons.
Do not use tolerance to hide a font problem
Playwright’s screenshot assertion uses a default perceived-color threshold of 0.2 unless configured otherwise. It also supports options for animation handling and whether capture scale is measured in CSS or device pixels. Adjust tolerance only if a small perceptual variance is acceptable; it will not load the correct font or fix a font-loading race. The relevant assertion options are documented in Playwright’s test assertion documentation.
Troubleshoot common font-related screenshot failures
- The screenshot still captures fallback text: place the readiness wait after navigation and immediately before capture. If the relevant text appears only after interaction, wait again after that interaction.
- The readiness promise resolves, but the wrong typeface appears: inspect computed font styles and loaded font resources. The wait does not confirm that a named font exists or that all declared faces were used.
- Text wraps differently in CI: compare viewport dimensions, device scale factor, browser build, operating system image, and available font files with the baseline environment.
- Only fine pixel-edge differences remain: first compare in the baseline’s rendering environment. If the remaining variance is genuinely acceptable, configure the assertion’s tolerance or capture options deliberately rather than treating that as a font fix.
Or skip the browser setup
If your goal is a screenshot of a live URL rather than a Playwright visual test, ScreenshotNeo provides a one-call screenshot API. For example, using cURL:
Free tools Windows power users keep installed
One-click scans. No signup required.
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 details. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. Its MCP server lets AI agents take screenshots, and the free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for free.
Frequently Asked Questions
Does `document.fonts.ready` wait for every font declared in a stylesheet?
No. It resolves after the document’s used fonts and related layout work are ready; declared but unused faces can remain unloaded.
Best Value
Will waiting for fonts eliminate all screenshot differences between my computer and CI?
No. Browser and operating-system versions, hardware, settings, and other rendering conditions can still change the image.
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.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →




