Running headless Chrome inside CI means a large download, a container that needs fonts installed, and a class of flake that only shows up on the build machine.
If the pages are reachable over HTTP, capture them from outside instead.
for page in / /pricing /docs; do
name=$(echo "$page" | tr '/' '_')
curl -s -o "shots/${name}.png" \
"https://api.screenshotline.com/take?url=https://example.com${page}&viewport_width=1280&full_page=true&cache=false" \
-H "X-Access-Key: $KEY"
done
Then compare against the committed baseline with whatever image diff you already use.
The settings that make diffs stable
cache=false. A cached image is yesterday's render, which is the opposite
of what a regression test wants.
A fixed viewport. Width changes layout, so pin it rather than relying on a default that might change.
block_ads=true and block_cookie_banners=true, both on by default.
Third-party content is the main source of false positives in visual diffs.
hide_selector for anything that animates forever. The renderer waits for
finite animations, but a carousel that rotates on a timer will differ on every
capture and no renderer can fix that for you.
Check more than the pixels
Two response headers are worth asserting on in the same test:
X-Blank-Suspected: false, so a page that failed to render does not pass as "no visual change".X-Upstream-Status: 200, so a deploy serving a 500 page is not compared as though it were content.
That turns a pixel test into a smoke test with a picture attached.
What this does not replace
Component-level snapshot tests inside your own test runner are faster and more precise for UI units. This is for whole pages, in a real browser, against a deployed environment, which is the part component tests cannot see.