Visual Regression Monitor — Website Screenshot Comparison
Pricing
from $0.01 / actor start
Visual Regression Monitor — Website Screenshot Comparison
Monitor websites for visual regressions. Capture baseline screenshots, compare against new captures, and generate pixel-accurate diff reports with highlighted changes.
Pricing
from $0.01 / actor start
Rating
0.0
(0)
Developer
Perry AY
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Visual Regression Monitor 🎯 — Detect Website Changes with Pixel-Perfect Diff Analysis
Capture website screenshots and compare them pixel-by-pixel to detect visual regressions. Generate annotated diff images, monitor pages on a schedule, and receive webhook alerts when changes are detected. Uses a headless Chromium browser for accurate, real-world screenshots.
What does it do?
The Visual Regression Monitor automates visual quality assurance for web pages. It takes full-page or viewport screenshots using headless Chromium, stores them as baselines in Apify's Key-Value Store, and then compares subsequent captures against those baselines pixel-by-pixel. When differences are found, it generates three-panel annotated diff images showing the baseline, current state, and highlighted changes.
Key capabilities:
- Baseline capture — Take screenshots of any URL and save them as reference images
- Visual comparison — Compare live pages against stored baselines with pixel-level diff reporting
- Batch processing — Compare multiple URLs concurrently for efficient monitoring
- Annotated diff reports — Generate HTML summary reports with per-URL match/mismatch status
- Webhook alerts — Send JSON alert payloads when visual mismatches are detected (ideal for CI/CD pipelines)
- Configurable thresholds — Set a diff percentage tolerance to ignore minor rendering differences
- Custom viewport — Control browser width, height, and full-page capture
Who is it for?
| Persona | Use Case |
|---|---|
| QA Engineer | Automate visual regression testing in CI/CD pipelines |
| Front-End Developer | Catch unintended UI changes before deployment |
| Site Reliability Engineer | Monitor production pages for unexpected visual drift |
| Product Manager | Verify visual consistency across environments |
| Web Agency | Scale visual QA across multiple client sites |
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | capture-baseline | Operation mode: capture-baseline, compare-baseline, batch-compare, or generate-diff-report |
url | string | — | A single URL to process (ignored if urls is provided) |
urls | array | — | One or more URLs to process (up to 50) |
viewportWidth | integer | 1280 | Browser viewport width in pixels |
viewportHeight | integer | 720 | Browser viewport height in pixels |
fullPage | boolean | false | Capture the entire scrollable page |
waitAfterLoadMs | integer | 2000 | Milliseconds to wait after page load before screenshot |
diffThreshold | number | 0.0 | Allowed diff percentage before flagging a mismatch |
timeoutSecs | integer | 60 | Max seconds to wait for page navigation |
webhookUrl | string | — | URL for POST alerts when mismatches are detected |
Quick Start
Capture Baselines
Start by capturing reference screenshots for the pages you want to monitor:
{"mode": "capture-baseline","urls": ["https://example.com", "https://httpbin.org"],"viewportWidth": 1280,"viewportHeight": 720,"fullPage": false}
Baseline images are stored in your run's Key-Value Store under keys like baseline-example.com___ and baseline-httpbin.org___.
Compare to Baseline
After baselines are stored, compare the live pages:
{"mode": "compare-baseline","urls": ["https://example.com", "https://httpbin.org"],"diffThreshold": 2.0,"webhookUrl": "https://hooks.example.com/visual-alerts"}
This captures new screenshots, compares them pixel-by-pixel against the stored baselines, and generates annotated diff images in KVS. If the diff percentage exceeds the threshold, the URL is flagged as a mismatch.
Batch Compare
For larger workloads, use batch mode to compare multiple URLs concurrently:
{"mode": "batch-compare","urls": ["https://example.com","https://httpbin.org","https://www.google.com","https://github.com"],"diffThreshold": 1.0}
All comparisons run concurrently via asyncio.gather with return_exceptions=True, so a failure on one URL does not affect others.
Generate Diff Report
After comparisons, generate an HTML report summarising all results:
{"mode": "generate-diff-report"}
The report is stored in KVS as report-latest.html and as a timestamped key. Open the KVS URL in your browser to view the dark-themed annotated report with per-URL match/mismatch status, diff percentages, and pixel counts.
Output
Each run pushes individual results to the default dataset. For comparison modes, each item contains:
| Field | Type | Description |
|---|---|---|
url | string | The URL that was processed |
match | boolean | Whether the screenshot matched the baseline |
diff_percent | number | Percentage of differing pixels |
pixels_different | integer | Raw count of differing pixels |
total_pixels | integer | Total pixels in the screenshot |
diff_kvs_key | string | KVS key for the annotated diff PNG |
baseline_kvs_key | string | KVS key for the stored baseline image |
compared_at | string | ISO 8601 comparison timestamp |
For baseline captures, each item contains:
| Field | Type | Description |
|---|---|---|
url | string | The captured URL |
success | boolean | Whether capture succeeded |
image_size_bytes | integer | Size of the PNG in bytes |
taken_at | string | ISO 8601 capture timestamp |
error | string | Error message if capture failed |
API Usage
cURL
curl -X POST "https://api.apify.com/v2/acts/perryay~visual-regression-monitor/runs" \-H "Content-Type: application/json" \-H "Authorization: Bearer YOUR_APIFY_TOKEN" \-d '{"mode": "compare-baseline","urls": ["https://example.com"],"diffThreshold": 2.0}'
Python
import requestsresponse = requests.post("https://api.apify.com/v2/acts/perryay~visual-regression-monitor/runs",headers={"Content-Type": "application/json","Authorization": "Bearer YOUR_APIFY_TOKEN"},json={"mode": "compare-baseline","urls": ["https://example.com"],"diffThreshold": 2.0})print(response.json())
Node.js
const response = await fetch("https://api.apify.com/v2/acts/perryay~visual-regression-monitor/runs",{method: "POST",headers: {"Content-Type": "application/json","Authorization": "Bearer YOUR_APIFY_TOKEN"},body: JSON.stringify({mode: "compare-baseline",urls: ["https://example.com"],diffThreshold: 2.0})});const data = await response.json();console.log(data);
Use Cases
- CI/CD visual regression testing — Run
compare-baselineafter deployments to catch unintended UI changes - Scheduled page monitoring — Use Apify's scheduler to run comparisons hourly/daily and get webhook alerts on mismatches
- Multi-environment comparison — Capture baselines from staging, compare against production
- Content verification — Detect unexpected changes to critical pages (pricing, landing pages, legal pages)
- Cross-browser QA — Run the same URLs at different viewport sizes
FAQ
General
What is visual regression testing? Visual regression testing compares screenshots of a web page taken at different times to detect unintended visual changes. It catches layout shifts, missing elements, font changes, and styling regressions that functional tests might miss.
Do I need to run capture-baseline first?
Yes. The compare-baseline and batch-compare modes require baseline images to exist in KVS. Run capture-baseline first to create them.
How are baselines stored?
Baseline images are stored in your run's Key-Value Store under keys prefixed with baseline-. They persist between runs and are accessible via the Apify Console or API.
What happens if the viewport dimensions change? If a comparison detects that the baseline and current screenshot have different dimensions, the baseline is automatically resized to match the current image using Lanczos resampling. A warning is logged.
Can I use this for responsive design testing?
Yes. Run the same URLs with different viewportWidth and viewportHeight settings to capture baselines for each breakpoint, then compare against the matching breakpoint.
What file format are the diff images? All diff images are generated as PNG with a three-panel layout: baseline (left), current (middle), and changes highlighted in red (right). A status bar at the bottom shows the URL, diff percentage, and pixel counts.
Webhooks
What does the webhook payload look like?
{"event": "visual-regression-alert","mode": "compare-baseline","timestamp": "2026-07-27T12:00:00.000Z","results": {"total_urls": 5,"failures": 2,"successes": 3}}
How do I set up scheduled monitoring?
Use Apify's built-in scheduler: create a task with mode: compare-baseline, set the desired URLs and threshold, and configure a daily or hourly schedule with a webhookUrl to receive alerts.
Technical
What browser engine is used?
Headless Chromium via Playwright. The Docker image (apify/actor-python-playwright) includes the Chromium browser binary pre-installed.
How accurate is the pixel comparison?
It uses Pillow's ImageChops.difference() for exact pixel-level comparison. Each pixel channel is compared independently. The diffThreshold parameter lets you relax strictness: 0% = pixel-perfect, 5% = tolerant to minor antialiasing or font rendering differences.
How many URLs can I process in a single run? Up to 50 URLs per run. For larger workloads, split across multiple scheduled runs or tasks.
Does it support authentication-protected pages? Currently the actor does not include cookie/session management. You can use Apify's Proxy or custom headers for basic auth scenarios.
What happens if the page fails to load? The actor retries up to 3 times with exponential backoff (2s, 4s, 8s). If all attempts fail, the URL is reported with an error and no charge is applied for that item.
How are the annotated diff images generated? A three-panel composite is created using Pillow. Differing pixels are highlighted with a semi-transparent red overlay on the current screenshot. A dark-themed stats bar at the bottom shows the URL, diff percentage, total pixels, and match/mismatch status.
MCP Integration
Connect this actor to any AI assistant via the Apify MCP Server:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com"}}}
Bearer token alternative (for headless clients like Cursor or VS Code):
{"mcpServers": {"apify": {"url": "https://mcp.apify.com","headers": {"Authorization": "Bearer YOUR_APIFY_TOKEN"}}}}
On first connection, your browser opens to sign in to Apify and authorise access.
Example prompts for your AI assistant:
- "Run visual regression monitoring on https://example.com and https://httpbin.org — compare them against their baselines"
- "Capture baseline screenshots of https://example.com at 1920×1080 viewport"
- "Generate a diff report of all URLs that have been compared so far"
Related Tools
- Website Screenshot Generator — Take full-page or viewport screenshots of any website
- OG Preview Generator — Generate Open Graph preview images for URLs
- Image Metadata Analyzer — Extract EXIF and metadata from images
- All perryay actors — Browse the full collection
SEO Keywords
Visual regression testing, screenshot diff tool, pixel comparison, visual QA automation, CI/CD visual testing, website monitoring, UI regression detection, automated screenshot comparison, web page change detection, headless browser testing, visual regression monitor, Apify actor visual testing, front-end testing tool, visual diff report, cross-browser screenshot comparison, annotated diff images, webhook visual alerts, batch URL comparison, baseline screenshot capture, pixel-perfect comparison.