Create a reusable Claude skill that discovers important pages in web applications, captures screenshots before/after code changes, and generates visual comparison reports. Works in headless environments and requires zero modifications to target applications.
The skill will support three main commands:
/screenshot discover- Analyze codebase to find main pages/routes/screenshot capture [--baseline|--comparison]- Capture screenshots of discovered pages/screenshot compare- Compare baseline vs comparison screenshots and generate report
Validate that UI migrations (PatternFly upgrades, design system changes, refactoring) preserve visual styling across important application pages.
- Application: PatternFly React app at
/home/jmatthews.linux/Shared/patternfly_experiments/patternfly-migration-workshop - Main pages: Projects, Workloads (with submenus: Pods, Deployments), Storage
- Routing: State-based (not React Router)
- Dev server: Vite on port 3000
- Goal: Capture before PatternFly migration, after migration, and compare
Claude Skill with Playwright for browser automation + Pixelmatch for visual diffs
Key Design Principles:
- Generic: Works with any web application (React Router, state-based routing, etc.)
- Isolated: Zero modifications to target application
- Intelligent: Auto-discovers routes and important pages
- Headless: Runs in VM without GUI
- Stateful: Remembers what was captured for later comparison
The skill will be stored in Claude's skills directory with isolated dependencies.
Skill location: ~/.claude/skills/screenshot-visual-regression/
Structure:
~/.claude/skills/screenshot-visual-regression/
├── skill.json # Skill manifest
├── package.json # Isolated dependencies
├── node_modules/ # Isolated from target app
├── src/
│ ├── index.ts # Main skill entry point
│ ├── discover.ts # Route/page discovery logic
│ ├── capture.ts # Screenshot capture logic
│ ├── compare.ts # Comparison and reporting
│ └── helpers/
│ ├── codebase-analyzer.ts # Analyzes routing patterns
│ ├── page-navigator.ts # Generic navigation
│ ├── screenshot-utils.ts # Browser utilities
│ └── state-manager.ts # Persist discovery metadata
└── .screenshots/ # Created in target app's directory
├── .screenshot-config.json # Auto-generated config
├── baseline/
├── comparison/
├── diff/
└── reports/
File: ~/.claude/skills/screenshot-visual-regression/skill.json
{
"name": "screenshot-visual-regression",
"version": "1.0.0",
"description": "Discover pages, capture screenshots, and compare visual changes",
"commands": {
"discover": {
"description": "Analyze codebase to find main pages and routes",
"usage": "/screenshot discover [--url <dev-server-url>]"
},
"capture": {
"description": "Capture screenshots of discovered pages",
"usage": "/screenshot capture --baseline | --comparison",
"options": {
"--baseline": "Capture baseline (before changes)",
"--comparison": "Capture comparison (after changes)"
}
},
"compare": {
"description": "Compare baseline and comparison screenshots",
"usage": "/screenshot compare [--threshold <0.0-1.0>]"
}
},
"dependencies": {
"playwright": "^1.40.0",
"pixelmatch": "^5.3.0",
"pngjs": "^7.0.0"
}
}File: ~/.claude/skills/screenshot-visual-regression/src/discover.ts
Discovery Strategy:
- Analyze routing configuration (React Router, state-based, file-based, etc.)
- Find page components in common locations (pages/, routes/, views/)
- Detect navigation structure (menus, sidebars)
- Identify interactive states (tabs, modals, expanded sections)
- Optionally crawl running dev server to discover dynamic routes
- Generate
.screenshot-config.jsonwith discovered targets
For current PatternFly app:
- Parse
src/App.tsxfor state-based routing - Find navigation items in JSX (Nav, NavItem, NavExpandable)
- Detect page components (ProjectsPage, WorkloadsPage, StoragePage)
- Find tabs in WorkloadsPage
- Generate config with 8 screenshot targets
File: ~/.claude/skills/screenshot-visual-regression/src/capture.ts
Capture Process:
- Load
.screenshot-config.jsonfrom target app directory - Verify dev server is running (check configured URL)
- Launch headless Playwright browser
- For each target in config:
- Navigate using generic navigation helper
- Wait for page readiness (network idle + selectors)
- Capture full-page screenshot
- Save to
baseline/orcomparison/directory
- Report summary of captured screenshots
Generic Navigation:
- Support clicking elements by text, selector, or role
- Handle expandable menus
- Support tab switching by index or text
- Configurable wait strategies per target
File: ~/.claude/skills/screenshot-visual-regression/src/compare.ts
Comparison Process:
- Load baseline and comparison screenshots
- For each screenshot pair:
- Use pixelmatch to generate pixel diff
- Calculate difference percentage
- Generate diff image highlighting changes
- Create HTML report with:
- Summary statistics (identical, different, missing)
- Side-by-side before/after/diff view
- Difference percentage for each page
- Thumbnails for quick overview
- Save to
reports/comparison-report-{timestamp}.html - Output summary to Claude conversation
File: ~/.claude/skills/screenshot-visual-regression/src/helpers/state-manager.ts
Manages:
.screenshot-config.jsonin target app directory- Stores discovered routes/pages
- Tracks baseline/comparison capture timestamps
- Persists dev server URL and settings
- Allows manual editing of config for fine-tuning
Config Format:
{
"version": "1.0",
"devServerUrl": "http://localhost:3000",
"viewport": { "width": 1920, "height": 1080 },
"discoveredAt": "2026-01-26T10:00:00Z",
"baselineCapturedAt": "2026-01-26T10:05:00Z",
"comparisonCapturedAt": null,
"targets": [
{
"name": "projects-page",
"description": "Projects page with user profiles",
"navigation": {
"type": "click",
"selector": "nav >> text='Projects'"
},
"waitFor": ".pf-v6-c-card",
"enabled": true
},
// ... more targets
]
}File: ~/.claude/skills/screenshot-visual-regression/src/helpers/codebase-analyzer.ts
Analysis Capabilities:
- React Router v6: Parse routes from JSX/config
- Next.js: Analyze pages/ or app/ directory structure
- State-based: Parse component code for routing logic
- File-based: Detect routing patterns from directory structure
- Navigation: Extract menu items from common components
- Interactive Elements: Find tabs, accordions, modals
For PatternFly app specifically:
- Read src/App.tsx
- Parse state type:
type PageType = 'projects' | 'workloads' | 'storage' - Find navigation JSX structure
- Detect WorkloadsPage has submenus and tabs
- Generate navigation selectors based on text content
Skill Location (Isolated):
~/.claude/skills/screenshot-visual-regression/
├── skill.json
├── package.json
├── node_modules/ # Skill dependencies (isolated)
└── src/
├── index.ts
├── discover.ts
├── capture.ts
├── compare.ts
└── helpers/
├── codebase-analyzer.ts
├── page-navigator.ts
├── screenshot-utils.ts
└── state-manager.ts
Target Application (Minimal Additions):
/home/jmatthews.linux/Shared/patternfly_experiments/patternfly-migration-workshop/
├── src/ # UNTOUCHED
├── package.json # UNTOUCHED
├── node_modules/ # UNTOUCHED
└── .screenshots/ # Created by skill (gitignored)
├── .screenshot-config.json # Auto-generated
├── baseline/
│ ├── projects-page.png
│ ├── workloads-pods-details-tab.png
│ └── ... (8 total)
├── comparison/
│ └── (same structure after migration)
├── diff/
│ └── (diff images)
└── reports/
└── comparison-report-{timestamp}.html
# User starts the dev server
$ npm run dev
# User runs discovery in Claude Code CLI
$ /screenshot discover --url http://localhost:3000What happens:
- Skill analyzes codebase routing patterns
- Crawls running app to find pages
- Generates
.screenshots/.screenshot-config.json - Shows discovered pages to user for review/editing
- User can manually edit config to add/remove targets
# Dev server should be running
$ npm run dev
# In Claude Code CLI
$ /screenshot capture --baselineWhat happens:
- Skill loads
.screenshots/.screenshot-config.json - Launches headless browser
- Navigates to each discovered page
- Captures 8 screenshots
- Saves to
.screenshots/baseline/ - Reports summary to user
User performs PatternFly migration:
- Upgrade packages
- Fix breaking changes
- Application code/config untouched except for migration
# Restart dev server with migrated code
$ npm run dev
# In Claude Code CLI
$ /screenshot capture --comparisonWhat happens:
- Skill loads same config from Phase 1
- Captures screenshots with same navigation paths
- Saves to
.screenshots/comparison/
# In Claude Code CLI
$ /screenshot compareWhat happens:
- Skill compares baseline vs comparison screenshots
- Generates pixel diffs for each page
- Creates HTML report
- Shows summary in CLI (X identical, Y different)
- User opens
.screenshots/reports/comparison-report-{timestamp}.htmlto review
Discovery Intelligence:
- Uses Claude's code analysis to parse routing patterns
- Detects common frameworks: React Router, Next.js, state-based, file-based
- Analyzes navigation components to find menu structure
- Scans page components for interactive elements (tabs, modals)
- Generates navigation steps as declarative config (not hardcoded scripts)
Generic Navigation Engine:
- Config-driven navigation (supports any app structure)
- Navigation types:
click: Click element by selector, text, or rolenavigate: Direct URL navigationsequence: Multiple navigation stepswait: Custom wait conditions
- Smart waiting: network idle + selector + animations
- Fallback strategies if navigation fails
Browser Configuration:
- Headless Chromium (Playwright)
- Viewport: 1920×1080 (configurable)
- Args: --no-sandbox, --disable-dev-shm-usage (VM compatibility)
- DeviceScaleFactor: 1 (consistent screenshots)
Comparison Algorithm:
- Pixelmatch threshold: 0.1 (configurable via --threshold flag)
- Generates diff images with highlighted changes
- Calculates per-page and overall difference percentages
- Handles missing screenshots gracefully
State Management:
- Config stored in target app's
.screenshots/directory - Automatically gitignored (recommended)
- Can be committed for team collaboration
- Timestamps track when captures were made
- Idempotent: can re-run captures safely
Skill Files (In ~/.claude/skills/screenshot-visual-regression/):
- skill.json - Skill manifest defining commands and metadata
- package.json - Node.js dependencies (playwright, pixelmatch, pngjs, tsx)
- src/index.ts - Main entry point, command router
- src/discover.ts - Discovery command implementation
- src/capture.ts - Capture command implementation
- src/compare.ts - Compare command implementation
- src/helpers/codebase-analyzer.ts - Routing pattern detection and parsing
- src/helpers/page-navigator.ts - Generic navigation engine
- src/helpers/screenshot-utils.ts - Browser utilities and wait strategies
- src/helpers/state-manager.ts - Config file management
Generated Files (In target app's .screenshots/ directory):
- .screenshot-config.json - Auto-generated by discover command, manually editable
- baseline/*.png - Baseline screenshots (created by capture --baseline)
- comparison/*.png - Comparison screenshots (created by capture --comparison)
- diff/*.png - Visual diff images (created by compare)
- reports/*.html - Comparison reports (created by compare)
Application Files:
- None - Zero modifications to application code, package.json, or configuration
Recommended .gitignore Addition:
# Visual regression testing
.screenshots/baseline/
.screenshots/comparison/
.screenshots/diff/
.screenshots/reports/
# Keep config for team collaboration:
# !.screenshots/.screenshot-config.json
- Verify skill directory created at
~/.claude/skills/screenshot-visual-regression/ - Check dependencies installed:
ls ~/.claude/skills/screenshot-visual-regression/node_modules/ - Verify skill available:
/screenshotshould show in Claude Code autocomplete
# Navigate to PatternFly app
cd /home/jmatthews.linux/Shared/patternfly_experiments/patternfly-migration-workshop
# Start dev server
npm run dev
# In Claude Code CLI, run discovery
/screenshot discover --url http://localhost:3000Verify:
.screenshots/.screenshot-config.jsoncreated in app directory- Config contains 8 targets (Projects, Workloads×Pods×3tabs, Workloads×Deployments×3tabs, Storage)
- Navigation selectors look correct
- Can manually edit config if needed
# Ensure dev server running
/screenshot capture --baselineVerify:
- 8 PNG files created in
.screenshots/baseline/ - Files named correctly (projects-page.png, workloads-pods-details-tab.png, etc.)
- Images render correctly (open one to visually inspect)
- All pages captured without errors
# Make a small CSS change as mock migration
# (e.g., change a color in src/styles/components.css)
# Restart dev server
npm run dev
# Capture comparison
/screenshot capture --comparisonVerify:
- 8 PNG files created in
.screenshots/comparison/ - Same filenames as baseline
- Visual differences visible in modified areas
/screenshot compareVerify:
- Diff images created in
.screenshots/diff/ - HTML report created in
.screenshots/reports/comparison-report-{timestamp}.html - CLI shows summary: "X identical, Y different"
- Open HTML report - shows side-by-side comparisons
- Report highlights pixel differences correctly
- Verify no DISPLAY environment variable:
echo $DISPLAY - Run capture command - should work without GUI
- If browser fails, install deps:
cd ~/.claude/skills/screenshot-visual-regression && npx playwright install-deps chromium
- Check app's
package.json- no new dependencies - Check app's
node_modules/- no playwright/pixelmatch - Only
.screenshots/directory added to app - Skill dependencies isolated in
~/.claude/skills/screenshot-visual-regression/node_modules/
Issue: Browser fails to launch
- Solution: Run
npx playwright install-deps chromiumto install system dependencies
Issue: Screenshots are blank/white
- Solution: Increase wait times or verify dev server is accessible at localhost:3000
Issue: PatternFly components not fully rendered
- Solution: Adjust wait selectors in screenshot-config.ts or increase timeout values
Issue: False positive diffs in identical content
- Solution: Increase pixelmatch threshold from 0.1 to 0.2 or higher
After implementation, you will have a reusable Claude skill that:
- Works with any web application (not just this PatternFly app)
- Auto-discovers important pages by analyzing routing patterns
- Captures baseline screenshots before code changes
- Captures comparison screenshots after code changes
- Generates visual diff reports highlighting pixel-level differences
- Runs in headless environments without browser GUI
- Maintains zero impact on target applications (isolated dependencies)
For this specific PatternFly migration:
- Discover 8 important page states automatically
- Capture baseline before PatternFly v6+ migration
- Perform migration with confidence
- Capture comparison after migration
- Generate report showing which pages have visual changes
- Quickly identify and fix any styling regressions
Future reusability:
- Use
/screenshot discoveron any React/Next.js/Vue app - Generic enough for different routing patterns
- Can be used for design system migrations, refactoring, theme changes
- Config can be shared across team for consistent screenshot targets