Inside Playwright: How Playwright Uses Pixelmatch
When to Use
Use this when tuning Playwright VR thresholds — critical for understanding why explicitly setting
threshold: 0.1in Playwright is stricter than the Playwright default.
Decision
| Goal | Tune |
|---|---|
| Pixel-level forgiveness (anti-aliasing tolerance) | threshold |
| Tolerate small noise pockets in an otherwise stable test | maxDiffPixels — including on full-page shots, where a ratio's budget would scale with page height |
| Both | All three; they compose |
Pattern: layered thresholds
expect: {
toHaveScreenshot: {
threshold: 0.15, // per-pixel YIQ tolerance
maxDiffPixels: 500, // absolute; same meaning at every image size
},
}
This says: individual pixels can shift up to YIQ delta 0.15; up to 500 pixels can be flagged before failing.
Reach for this layer only once the capture is stable and repeat runs on an unchanged site show a residual — set the number from what you measured, not from a guess. Prefer the absolute cap over maxDiffPixelRatio on anything variable-height: the ratio is a fraction of image area, so on a fullPage: true shot the budget grows with the page. 0.5% of 1440×900 is about 6,500 px; the same 0.5% of 1440×8000 is about 57,600 px — enough to hide a whole component.
The Defaults Differ
| Default | Pixelmatch library | Playwright |
|---|---|---|
threshold |
0.1 | 0.2 |
Playwright's choice is more forgiving — designed to absorb typical variation in real browser captures.
Two Extra Knobs Playwright Adds
| Option | Default | Job |
|---|---|---|
maxDiffPixels |
unset | Absolute integer cap on differing pixels |
maxDiffPixelRatio |
unset | Cap as a fraction of total pixels (0–1) |
A test passes when:
- diffCount <= maxDiffPixels (if configured), AND
- diffCount / totalPixels <= maxDiffPixelRatio (if configured)
If neither is configured, any non-zero diff fails the test.
Common Mistakes
- Wrong: Reading pixelmatch's
0.1default and writing it into Playwright — explicitly settingthreshold: 0.1is stricter than Playwright's default of0.2 - Wrong: Setting
maxDiffPixels: 0— redundant; that's the default behavior - Wrong: Setting both
maxDiffPixelsandmaxDiffPixelRatiowithout thought — the strictest of the two wins
See Also
- Threshold — what threshold values mean
- Tuning Recipes — scenario-by-scenario threshold reference
- Playwright docs: toHaveScreenshot options