Visual Qa
by @kbo4sho
Perform pixel-level visual regression testing on web apps by capturing, comparing screenshots, and gating deployments based on configurable similarity thresh...
clawhub install visual-qaπ About This Skill
name: visual-qa description: Visual regression testing pipeline for web applications. Capture baseline screenshots, compare against new builds using pixel-level diffing, and gate deployments based on visual similarity thresholds. Use when: visual QA, visual regression testing, screenshot comparison, UI verification, visual diff, pre-deploy check, or validating UI changes before merge.
Visual QA
A visual regression testing pipeline for web applications. Capture baseline screenshots of your app, compare new screenshots against baselines using pixel-level diffing, and pass/fail based on configurable similarity thresholds.
When to Use
Quick Start
1. Capture Baselines
# Capture single URL
python scripts/capture.py http://localhost:3000 --output .visual-qa/baselinesCapture multiple viewports
python scripts/capture.py http://localhost:3000 --viewports desktop mobile tablet --output .visual-qa/baselinesCapture multiple pages from config
python scripts/capture.py --config .visual-qa.json --output .visual-qa/baselines
2. Compare Against Baselines
# Compare new screenshots
python scripts/diff.py --baseline .visual-qa/baselines --current .visual-qa/current --threshold 99
3. All-in-One Gate
# Capture + diff in one command
python scripts/gate.py --baseline .visual-qa/baselines --url http://localhost:3000 --threshold 99With local dev server
python scripts/gate.py --baseline .visual-qa/baselines --server "npm run dev" --port 3000 --threshold 99Using config file
python scripts/gate.py --config .visual-qa.json
Config File Pattern
Create .visual-qa.json in your project root:
{
"urls": ["/", "/about", "/pricing"],
"baseUrl": "http://localhost:3000",
"viewports": ["desktop", "mobile"],
"threshold": 99,
"server": "npm run dev",
"port": 3000,
"baselineDir": ".visual-qa/baselines",
"ignore": [".visual-qa/diffs", ".visual-qa/current"]
}
Scripts
All scripts support --help for detailed usage.
capture.py
Capture screenshots using Playwright (headless Chromium).
Features:
{url-slug}_{viewport}.pngUsage:
python scripts/capture.py --output [options]
python scripts/capture.py --config --output
diff.py
Compare screenshots using pixel-level diffing (Pillow).
Features:
Usage:
python scripts/diff.py --baseline --current --output --threshold
gate.py
All-in-one gate: capture + diff in a single command.
Features:
Usage:
python scripts/gate.py --baseline --url --threshold
python scripts/gate.py --baseline --server --port --threshold
python scripts/gate.py --config
Workflow Examples
Initial Baseline Capture
# Start your app
npm run devCapture baselines (desktop + mobile)
python scripts/capture.py http://localhost:3000 --viewports desktop mobile --output .visual-qa/baselines
CI/CD Integration
# In your CI pipeline after build
python scripts/gate.py --baseline .visual-qa/baselines --server "npm start" --port 3000 --threshold 99Exit code 0 = pass, 1 = fail
if [ $? -eq 0 ]; then
echo "Visual QA passed β"
else
echo "Visual QA failed β"
exit 1
fi
Review Workflow
# 1. Developer makes UI changes
2. Capture new screenshots
python scripts/capture.py http://localhost:3000 --output .visual-qa/current3. Generate diff images
python scripts/diff.py --baseline .visual-qa/baselines --current .visual-qa/current --output .visual-qa/diffs4. Review diff images in .visual-qa/diffs/
5. If changes are intentional, update baselines:
rm -rf .visual-qa/baselines
mv .visual-qa/current .visual-qa/baselines
Multi-Page Testing
Create .visual-qa.json:
{
"urls": ["/", "/products", "/about", "/contact"],
"baseUrl": "http://localhost:3000",
"viewports": ["desktop", "mobile"],
"threshold": 99,
"baselineDir": ".visual-qa/baselines"
}
# Capture all pages
python scripts/capture.py --config .visual-qa.json --output .visual-qa/baselinesGate all pages
python scripts/gate.py --config .visual-qa.json
Dependencies
Scripts require Playwright and Pillow:
pip install playwright pillow
python -m playwright install chromium
Scripts will check for dependencies and print install instructions if missing.
Thresholds
The --threshold parameter controls similarity percentage (0-100):
Experiment to find the right threshold for your app. Start strict (99%) and loosen if you get false positives.
Ignoring Dynamic Content
For pages with dynamic content (dates, user-specific data):
1. Use data attributes to hide dynamic elements during testing:
[data-test-hide] { visibility: hidden !important; }
2. Capture specific viewport regions (future enhancement)
3. Loosen threshold for pages with acceptable dynamic content
Troubleshooting
"Command not found: python"
python3 instead of python"Playwright not installed"
pip install playwright && python -m playwright install chromium"Similarity below threshold but images look the same"
"Server not starting"
--port matches your server's portnpm run dev, npm start, etc.)"Images not found"
{url-slug}_{viewport}.pngTips
.visual-qa/diffs and .visual-qa/current to .gitignoreIntegration with Other Skills
For detailed script options, run:
python scripts/capture.py --help
python scripts/diff.py --help
python scripts/gate.py --help
β‘ When to Use
π‘ Examples
1. Capture Baselines
# Capture single URL
python scripts/capture.py http://localhost:3000 --output .visual-qa/baselinesCapture multiple viewports
python scripts/capture.py http://localhost:3000 --viewports desktop mobile tablet --output .visual-qa/baselinesCapture multiple pages from config
python scripts/capture.py --config .visual-qa.json --output .visual-qa/baselines
2. Compare Against Baselines
# Compare new screenshots
python scripts/diff.py --baseline .visual-qa/baselines --current .visual-qa/current --threshold 99
3. All-in-One Gate
# Capture + diff in one command
python scripts/gate.py --baseline .visual-qa/baselines --url http://localhost:3000 --threshold 99With local dev server
python scripts/gate.py --baseline .visual-qa/baselines --server "npm run dev" --port 3000 --threshold 99Using config file
python scripts/gate.py --config .visual-qa.json
π Tips & Best Practices
.visual-qa/diffs and .visual-qa/current to .gitignore