Installs into .claude/skills of the current project.
Are you the author of Visual Validation?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/yoodaddy0311-visual-validation)
---
context: fork
name: visual-validation
description: |
Visual regression testing using SSIM-based screenshot comparison.
Auto-activates when: visual testing, UI regression checks, screenshot comparison, component validation, CSS fix suggestions needed.
Triggers: visual, screenshot, regression, baseline, pixel, SSIM, UI validation, component check
lang: [en]
platforms: [claude-code, gemini-cli, codex-cli, cursor]
level: 3
progressive_disclosure:
enabled: true
level1_tokens: 120
level2_tokens: 4000
triggers:
- "visual"
- "screenshot"
- "regression"
- "baseline"
- "pixel"
- "SSIM"
- "visual test"
- "UI validation"
- "component check"
- "visual diff"
agents:
- "quality-reviewer"
- "frontend-developer"
tokens: "~4K"
category: "testing"
source_hash: 89156f3e
whenNotToUse: "Non-UI code paths (APIs, business logic, CLI tools) or environments without browser/screenshot capabilities where visual regression comparison is not feasible."
---
# Visual Validation
> **Wiring note:** the SSIM toolkit (`lib/visual/visual-validator.js`, `screenshot-differ.js`, `style-fixer.js`) is a **skill-invoked utility**, not a runtime-hooked subsystem. It runs only when this skill activates or `/visual-check` is invoked and the agent follows the workflow below — there is no middleware/hook that captures screenshots automatically. Screenshot capture itself goes through Playwright MCP instructions emitted by the validator. (Auto-wiring via a Playwright MCP post-render hook is a possible future enhancement, not currently implemented.)
## When This Skill Applies
- Comparing UI screenshots against approved baselines
- Detecting visual regressions after CSS or layout changes
- Validating component appearance across environments or browsers
- Generating CSS fix suggestions from visual diffs
## Core Workflow
### 1. Establish a Baseline
Before running validation, capture and store a reference (baseline) screenshot:
```
/visual-check https://example.com --baseline ./baselines/home.png
```
Or use `createBaseline()` from `lib/visual/visual-validator.js` to generate Playwright capture instructions.
### 2. Run Validation
Compare the current render against the baseline:
```
/visual-check https://example.com --baseline ./baselines/home.png --threshold 0.95
```
### 3. Interpret Results
- **passed: true** — similarity ≥ threshold, no action needed
- **passed: false** — `diffRegions` lists changed areas; `fixSuggestions` provide CSS remediation hints
## Threshold Guidelines
| Scenario | Recommended Threshold |
|----------|-----------------------|
| Pixel-perfect static pages | 0.98 |
| Standard UI components (default) | 0.95 |
| Responsive / fluid layouts | 0.90 |
| Dynamic content with animations | 0.85 |
Always use the **lowest acceptable threshold** for your use case to avoid false positives.
### 현재 정책 티어 고해상도 가이드 (4.7 세대부터)
- Playwright 스크린샷 기본 해상도: **2576px** (이전 1568px) — 3.75MP 이내
- 모델 좌표는 실제 픽셀과 1:1 매핑 → 스케일 팩터 계산 불필요
- 고해상도는 토큰을 더 소모 — 고충실도가 불필요한 경우 다운샘플 권장
- Playwright 설정: viewport `{ width: 2576, height: 1600 }` 또는 원본 유지 후 `fullPage: true`
## Best Practices
### Disable Animations
CSS animations and transitions cause false diffs. The validator automatically injects:
```css
*, *::before, *::after {
animation-duration: 0s !important;
transition-duration: 0s !important;
}
```
Pass `--disableAnimations false` only when testing animation state is intentional.
### Exclude Dynamic Elements
Hide timestamps, ads, live counters, and other dynamic regions before capture:
```
/visual-check https://example.com --exclude ".ad-banner, #live-clock, [data-dynamic]"
```
### Maximum 3 Iterations
The validator runs up to `--iterations 3` (default) comparison attempts. After 3 passes without reaching threshold, fix suggestions are returned for manual CSS remediation.
### Scope to Components
Use `--selector` to scope screenshots to a specific component rather than the full page. This reduces noise and improves accuracy:
```
/visual-check https://example.com/docs --selector ".sidebar-nav" --threshold 0.98
```
## Integration with Playwright MCP
The validator does not call Playwright directly — it returns **structured MCP tool instructions**:
```json
[
{ "tool": "playwright_navigate", "params": { "url": "https://example.com" } },
{ "tool": "playwright_evaluate", "params": { "script": "/* disable animations */" } },
{ "tool": "playwright_screenshot", "params": { "name": "actual", "storeBase64": true } }
]
```
These instructions should be dispatched via the Playwright MCP server at runtime.
## Fix Suggestion Categories
| Category | Description | Common CSS Properties |
|----------|-------------|----------------------|
| `spacing` | Margin/padding changes | `margin`, `padding`, `gap` |
| `color` | Background or text color changes | `color`, `background-color`, `fill` |
| `typography` | Font rendering differences | `font-family`, `font-size`, `font-weight` |
| `alignment` | Layout offset or flex/grid drift | `display`, `justify-content`, `align-items` |
| `size` | Element dimension changes | `width`, `height`, `min-*`, `max-*` |
| `visibility` | Show/hide state changes | `display`, `visibility`, `opacity` |
## Quick Reference
```
/visual-check [url]
--baseline <path> Baseline image path (required for comparison)
--threshold <0-1> Similarity threshold (default: 0.95)
--iterations <n> Max retry iterations (default: 3)
--selector <css> Scope screenshot to element
--exclude <css-list> Hide dynamic elements before capture
```
---
## References
- See `${CLAUDE_SKILL_DIR}/references/validation-thresholds.md` for validation thresholds
## Rationalizations
> 이 절은 참고 자료다 — 아래 변명·반박은 모델이 작업 중 스스로 지름길을 점검하는 데 쓰고, 사용자에게 묻는 질문 목록이나 별도 게이트로 쓰지 않는다. 반박에 비추어 스스로 바로잡을 수 없으면 이 스킬의 Step·Checkpoint 규칙을 따른다.
The following table captures common excuses agents make to skip the rigor of this skill, paired with factual rebuttals.
| Excuse | Rebuttal |
|--------|----------|
| "screenshot diff is flaky" | SSIM with tolerance is not flaky — pixel-exact is; use the right metric |
| "eyeballing it is faster" | eyeballing misses subpixel shifts and rebrand drifts — tools do not blink |
| "visual tests break on every CSS change" | they break on every unintended CSS change — that is the feature, update baselines intentionally |
| "we do not need visual tests for an API" | dashboards and admin UIs are visual surfaces; APIs with docs have rendered docs |
| "baselines bloat the repo" | store baselines in object storage, not git — bloat is a storage choice |