Capture both page states with Playwright for Python under the same browser and viewport conditions, then compare the resulting images with a pixel-diff library such as pixelmatch. The comparison can give you a difference image and a count of changed pixels; it cannot decide by itself whether a change is a real regression. Keep captures reproducible, choose any tolerance deliberately, and inspect the diff before accepting a new baseline.
What a pixel comparison tells you
A screenshot comparison checks rendered pixels, not the page’s HTML, CSS, or behavior. An exact comparison answers whether two images are identical. A tolerant comparison can ignore small colour variations or a limited number of changed pixels, depending on the tool and settings.
This distinction matters for visual regression checks: font rendering or other environmental variation may change pixels even when the page looks effectively the same, while a generous tolerance can conceal a genuine defect. A diff image helps you see where changes occurred; a numeric difference count helps automate a pass/fail decision.
Capture comparable screenshots with Playwright for Python
Install Playwright for Python and the Python pixelmatch package. Playwright also needs its browser binaries installed. Run these commands in the same Python environment you will use for the script:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
python -m pip install playwright pixelmatch Pillow
python -m playwright install chromium
The following script captures a reference and a current render at the same viewport, then compares them. On the first run, it saves a baseline and reports that no comparison was made. On later runs, it writes a difference image and prints the number of differing pixels.
import asyncio
from pathlib import Path
from PIL import Image
from pixelmatch import pixelmatch
from playwright.async_api import async_playwright
URL = "https://example.com"
BASELINE = Path("baseline.png")
CURRENT = Path("current.png")
DIFF = Path("diff.png")
async def capture(path: Path) -> None:
async with async_playwright() as playwright:
browser = await playwright.chromium.launch()
page = await browser.new_page(
viewport={"width": 1280, "height": 800},
device_scale_factor=1,
)
await page.goto(URL, wait_until="networkidle", timeout=60_000)
await page.screenshot(path=str(path), full_page=True)
await browser.close()
async def main() -> None:
await capture(CURRENT)
if not BASELINE.exists():
CURRENT.replace(BASELINE)
print(f"Saved initial baseline to {BASELINE}; no diff was calculated.")
return
with Image.open(BASELINE).convert("RGBA") as baseline, Image.open(CURRENT).convert("RGBA") as current:
if baseline.size != current.size:
raise ValueError(
f"Image dimensions differ: baseline={baseline.size}, current={current.size}. "
"Make the page content and capture conditions consistent before comparing."
)
diff = Image.new("RGBA", baseline.size)
changed = pixelmatch(
baseline,
current,
diff,
threshold=0.1,
includeAA=False,
)
diff.save(DIFF)
total = baseline.width * baseline.height
print(f"Changed pixels: {changed} of {total}; diff image: {DIFF}")
asyncio.run(main())
The example uses the Python package’s PIL image support. The threshold value is a configuration choice, not a universal definition of an acceptable change. The includeAA option controls how anti-aliased pixels are treated by this comparison. Check the package’s current documentation and compatibility before standardising its API or options in a project.
Capture a viewport, full page, or one element
Use a viewport screenshot when only the visible screen matters. Set full_page=True to capture the full scrollable page, as in the example. To capture one element, locate it and call screenshot() on the locator:
element = page.locator("main article").first
await element.screenshot(path="article.png")
For processing in memory rather than writing a capture to disk, Playwright’s screenshot method can return image bytes. Its Python screenshot API supports file, full-page, element, and in-memory capture, and documents passing screenshot data to a third-party pixel-diff facility. Choose the scope that corresponds to the regression you want to detect; changing scope between baseline and current capture makes the comparison invalid.
Recommended Free Tools
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Make the page state repeatable
Use the same browser engine and version, operating system, viewport, device scale factor, and capture mode for both images. Rendering can vary with host environment, browser settings, hardware, power conditions, and headless mode. A baseline created on one setup may therefore differ from a capture made on another even if the page code has not changed.
- Fix or seed test data so records and ordering do not change between runs.
- Control clocks, rotating banners, animations, and other time-dependent content where possible.
- Wait for the page state you need.
networkidleis one option, but sites with persistent network activity may require waiting for a meaningful selector or application-specific readiness signal instead. - Keep authentication, cookies, locale, timezone, and other state consistent if they affect the rendered page.
- When a region is intentionally variable, consider hiding it in the capture or excluding it under a clearly documented policy rather than weakening the comparison for the whole page.
Playwright Test’s visual assertion guide describes a stylePath option for hiding volatile regions and notes that screenshots may vary across environments. That assertion belongs to Playwright Test; it is not automatically available through Playwright’s Python screenshot API.
Choose a comparison policy
Exact equality
Use exact image equality only when captures are deterministic enough that any pixel change should fail. It is useful for tightly controlled pages and environments, but small rendering variations can create noisy failures.
Per-pixel tolerance
A perceptual colour threshold determines how different a pixel’s colour must be before it is counted. A maximum differing-pixel count determines how many such pixels are allowed overall. These are separate controls: one governs the per-pixel decision, the other the aggregate allowance.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Playwright Test documents a threshold scale from 0 (strict) to 1 (lax), with a documented default of 0.2 in its JavaScript documentation, and provides maxDiffPixels as a further control. Its guide gives maxDiffPixels: 100 as an example. These are Playwright Test settings and examples, not recommended Python pixelmatch values or evidence that the same settings suit your application.
Start with a strict policy, review representative differences, and loosen it only to accommodate known harmless variance. Keep the diff image as part of the review process: a count alone cannot tell you whether changed pixels are a broken button or a benign antialiasing difference.
Review and update baselines deliberately
When a comparison fails, inspect the current capture and diff before changing the baseline. Confirm first that the page loaded into the expected state and that the capture environment matches the baseline. If a code change intentionally alters the design, review and approve that change, then replace the baseline through a deliberate update step. Do not automatically accept every newly captured image: doing so can turn a real regression into the new expected result.
Playwright Test’s documented workflow separates comparison from snapshot updating and provides an explicit update operation. The Python capture-and-diff script above deliberately does not overwrite its baseline when it detects a difference.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
Troubleshooting
The script cannot launch Chromium
Install the browser binaries for the active Playwright environment with python -m playwright install chromium. If you installed Playwright in a virtual environment, run the command from that environment.
The images have different dimensions
Full-page height can change when content length or loading state changes. Check viewport and device scale settings, page data, and readiness waits. If the difference is intentional, recapture a reviewed baseline rather than silently resizing images, which can distort the comparison.
The diff is noisy despite no apparent design change
Match browser and host conditions, then look for asynchronous content, fonts, animations, rotating material, and time-sensitive elements. Only after establishing that the remaining differences are harmless should you tune the threshold or allowed changed-pixel count.
The diff misses an obvious change
Review the selected capture scope and comparison settings. A high colour threshold or large changed-pixel allowance can suppress meaningful differences. Lower the tolerance or allowance and verify the diff against known intentional and unintended changes.
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 glitchesBest Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
The capture times out waiting for network idle
Some pages maintain requests indefinitely or load content after network activity appears idle. Use a page-specific readiness condition, such as waiting for a selector that indicates the relevant content is present, and keep that condition identical for baseline and current captures.
Or skip the browser setup
If you need a screenshot without managing a browser installation and comparison workflow, ScreenshotNeo provides a screenshot API. Its response distinguishes clean captures from bot checks or failed page outcomes, and the service bills only clean shots; cache hits also cost nothing. Cookie and consent banners, newsletter popups, and chat widgets are removed before capture by default, and each step can be turned off. Its MCP server provides screenshot tools for AI agents.
Here is a one-request Python example that saves a screenshot. See the ScreenshotNeo API documentation for request options and response handling.
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
ScreenshotNeo offers 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000. Learn more at ScreenshotNeo or sign up for the free plan.
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 reinstallFrequently Asked Questions
Can a pixel diff tell me whether a visual change is a bug?
No. It identifies image differences; deciding whether a change is a regression requires reviewing the changed region against the intended page state.
Is Playwright’s toHaveScreenshot() available in Playwright for Python?
The documented visual assertion is part of Playwright Test. The Python screenshot API captures images and can pass them to a separate image-diff implementation; it is not the same assertion interface.
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.




