library/specializations/ux-ui-design/skills/screenshot-comparison/SKILL.md
Visual regression testing through screenshot capture and comparison. Pixel-diff analysis, responsive screenshot capture across viewports, and visual change reporting with highlighted differences.
npx skillsauth add a5c-ai/babysitter screenshot-comparisonInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are screenshot-comparison - a specialized skill for visual regression testing through screenshot capture and pixel-level comparison, ensuring UI consistency across changes.
This skill enables AI-powered visual regression testing including:
pixelmatch or similar diff libraryCapture screenshots with various configurations:
// Full page screenshot
const screenshot = await page.screenshot({
fullPage: true,
path: 'screenshots/home-full.png'
});
// Element screenshot
const element = await page.locator('.hero-section');
await element.screenshot({ path: 'screenshots/hero.png' });
// Viewport-specific screenshot
await page.setViewportSize({ width: 375, height: 667 });
await page.screenshot({ path: 'screenshots/home-mobile.png' });
// Hide dynamic elements
await page.evaluate(() => {
document.querySelectorAll('[data-testid="timestamp"]')
.forEach(el => el.style.visibility = 'hidden');
});
await page.screenshot({ path: 'screenshots/home-stable.png' });
Compare screenshots and generate diff images:
const pixelmatch = require('pixelmatch');
const { PNG } = require('pngjs');
const fs = require('fs');
const baseline = PNG.sync.read(fs.readFileSync('baseline.png'));
const current = PNG.sync.read(fs.readFileSync('current.png'));
const { width, height } = baseline;
const diff = new PNG({ width, height });
const numDiffPixels = pixelmatch(
baseline.data,
current.data,
diff.data,
width,
height,
{
threshold: 0.1, // Sensitivity (0-1)
includeAA: false, // Ignore antialiasing
diffColor: [255, 0, 0], // Diff highlight color
diffColorAlt: [0, 255, 0] // Alt color for anti-aliased
}
);
fs.writeFileSync('diff.png', PNG.sync.write(diff));
const diffPercentage = (numDiffPixels / (width * height)) * 100;
console.log(`Diff: ${diffPercentage.toFixed(2)}%`);
Capture screenshots across multiple viewports:
const viewports = [
{ name: 'mobile', width: 375, height: 667 },
{ name: 'tablet', width: 768, height: 1024 },
{ name: 'desktop', width: 1440, height: 900 },
{ name: 'wide', width: 1920, height: 1080 }
];
const results = [];
for (const viewport of viewports) {
await page.setViewportSize({
width: viewport.width,
height: viewport.height
});
await page.screenshot({
path: `screenshots/${pageName}-${viewport.name}.png`,
fullPage: true
});
results.push({
viewport: viewport.name,
path: `screenshots/${pageName}-${viewport.name}.png`
});
}
Generate comprehensive diff reports:
{
"testRun": {
"id": "vr-2026-01-24-001",
"timestamp": "2026-01-24T10:30:00Z",
"branch": "feature/new-header",
"commit": "abc123"
},
"summary": {
"total": 25,
"passed": 22,
"failed": 2,
"new": 1,
"passRate": "88%"
},
"comparisons": [
{
"name": "homepage-desktop",
"status": "passed",
"diffPercentage": 0.01,
"threshold": 0.1,
"baseline": "baseline/homepage-desktop.png",
"current": "current/homepage-desktop.png"
},
{
"name": "header-mobile",
"status": "failed",
"diffPercentage": 5.2,
"threshold": 0.1,
"baseline": "baseline/header-mobile.png",
"current": "current/header-mobile.png",
"diff": "diffs/header-mobile-diff.png",
"changedRegions": [
{ "x": 10, "y": 5, "width": 200, "height": 50, "description": "Logo area" }
]
},
{
"name": "new-feature-banner",
"status": "new",
"current": "current/new-feature-banner.png",
"requiresApproval": true
}
]
}
Manage screenshot baselines:
# Update baseline for specific test
/skill screenshot-comparison update-baseline \
--test header-mobile \
--approve
# Update all failed baselines
/skill screenshot-comparison update-baseline \
--all-failed \
--approve
# Review pending approvals
/skill screenshot-comparison review \
--status pending
Test individual components in isolation:
// Storybook integration
const stories = await getStorybookStories();
for (const story of stories) {
// Navigate to story
await page.goto(`${storybookUrl}/iframe.html?id=${story.id}`);
// Wait for component
await page.waitForSelector('#storybook-root > *');
// Capture component screenshot
const component = await page.locator('#storybook-root > *');
await component.screenshot({
path: `screenshots/components/${story.id}.png`
});
}
This skill can leverage the following MCP servers:
| Server | Description | Installation | |--------|-------------|--------------| | Percy via BrowserStack MCP | Cloud-based visual testing | BrowserStack | | Playwright MCP Server | Browser automation with screenshots | GitHub |
This skill integrates with the following processes:
component-library.js - Component visual regressionresponsive-design.js - Responsive visual testinghifi-prototyping.js - Design-to-implementation comparisonWhen executing operations, provide structured output:
{
"operation": "compare",
"status": "completed",
"summary": {
"total": 10,
"passed": 9,
"failed": 1
},
"results": [
{
"name": "header-desktop",
"status": "passed",
"diffPercentage": 0.02
}
],
"artifacts": [
"report.html",
"diffs/header-mobile-diff.png"
]
}
development
Model documentation skill for generating model cards following Google's model card framework.
development
MLflow integration skill for experiment tracking, model registry, and artifact management. Enables LLMs to log experiments, compare runs, manage model lifecycle, and retrieve artifacts through the MLflow API.
data-ai
LIME-based local explanation skill for individual predictions across tabular, text, and image data.
devops
Kubeflow Pipelines skill for ML workflow orchestration, component management, and Kubernetes-native ML.