From playwright-visual
Configure Playwright's pixel-diff comparison engine: tune `maxDiffPixels`, `maxDiffPixelRatio`, and `threshold` per component type; normalize cross-platform font anti-aliasing; and mask locators that emit dynamic content (timestamps, avatars, ads).
How this skill is triggered — by the user, by Claude, or both
Slash command
/playwright-visual:visual-comparisonThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Configure Playwright's pixel-diff comparison engine: tune `maxDiffPixels`, `maxDiffPixelRatio`, and `threshold` per component type; normalize cross-platform font anti-aliasing; and mask locators that emit dynamic content (timestamps, avatars, ads).
Configure Playwright's pixel-diff comparison engine: tune maxDiffPixels, maxDiffPixelRatio, and threshold per component type; normalize cross-platform font anti-aliasing; and mask locators that emit dynamic content (timestamps, avatars, ads).
playwright.config.ts and per-assertion overrides.| Surface type | maxDiffPixelRatio | Notes |
|---|---|---|
| Icon / small UI element | 0.01 | Tight tolerance; even minor regressions matter |
| Component (button, card, form) | 0.02 | Balanced for design fidelity |
| Section / block | 0.03 | Some sub-pixel variance acceptable |
| Full page / layout | 0.05 | Font and scroll-bar rendering varies across OS |
playwright.config.ts)import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: {
maxDiffPixelRatio: 0.02, // default for all visual tests
animations: 'disabled', // always disable animations globally
threshold: 0.1, // per-pixel color distance threshold (0–1)
},
},
projects: [
{
name: 'visual',
use: {
...devices['Desktop Chrome'],
// Lock viewport for baseline consistency
viewport: { width: 1280, height: 800 },
},
testMatch: 'tests/visual/**/*.visual.spec.ts',
},
],
});
// Tighter threshold for an icon
await expect(page.getByTestId('logo-icon')).toHaveScreenshot('logo.png', {
maxDiffPixelRatio: 0.01,
animations: 'disabled',
});
// Looser threshold for a full-page layout
await expect(page).toHaveScreenshot('home-full.png', {
fullPage: true,
maxDiffPixelRatio: 0.05,
animations: 'disabled',
});
// Absolute pixel budget (alternative to ratio)
await expect(page.getByTestId('hero')).toHaveScreenshot('hero.png', {
maxDiffPixels: 50,
animations: 'disabled',
});
Pass an array of Locator objects to mask. Playwright renders those regions as solid magenta rectangles before comparison, eliminating noise from content that changes between runs.
await expect(page).toHaveScreenshot('dashboard.png', {
fullPage: true,
animations: 'disabled',
mask: [
page.getByTestId('last-updated-timestamp'), // live clock
page.getByTestId('user-avatar'), // per-user image
page.locator('[data-ad-slot]'), // ad network content
page.getByTestId('notification-badge'), // count changes per user
],
});
Cross-platform font rendering is the most common source of spurious visual failures. Mitigate with:
await page.addStyleTag({
content: `
* {
-webkit-font-smoothing: antialiased !important;
-moz-osx-font-smoothing: grayscale !important;
text-rendering: optimizeLegibility !important;
}
`,
});
threshold: a per-pixel threshold of 0.1–0.2 absorbs sub-pixel color differences without hiding genuine regressions.| Use case | Recommendation |
|---|---|
| Component isolation test | Use clip or an element-level toHaveScreenshot |
| Layout / grid verification | Use fullPage: true |
| Hero / above-the-fold section | Use element-level capture with getByTestId |
| Full-page scroll behavior | Use fullPage: true with maxDiffPixelRatio: 0.05 |
// Clip to a specific bounding box
await expect(page).toHaveScreenshot('nav.png', {
clip: { x: 0, y: 0, width: 1280, height: 64 },
animations: 'disabled',
});
animations: 'disabled' — either globally in playwright.config.ts or per assertion.maxDiffPixelRatio over maxDiffPixels for viewport-independent thresholds.npx claudepluginhub gagandeepp/software-agent-teams --plugin playwright-visualGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.