AgentSkillsCN

visual-testing-web

在为Web应用——Next.js、SvelteKit、React、Django、Go+HTMX,或静态网站——进行视觉验证时加载此模块。提供Browser MCP工具的使用方法,以及Playwright的典型模式。

SKILL.md
--- frontmatter
name: visual-testing-web
description: Load when running visual validation for web applications - Next.js, SvelteKit, React, Django, Go+HTMX, or static sites. Provides Browser MCP tool usage and Playwright patterns.

Web Visual Testing

Platform: web
Applicable Recipes: nextjs-supabase, sveltekit-supabase, t3-stack, django-htmx, go-templ-htmx, react-fastapi-postgres, static-site
Primary Tools: Browser MCP tools, Playwright, Percy, Chromatic


🔄 Tight Loop (Default)

Goal: Get high-signal visual feedback fast (minutes, not hours) with minimal flake.

Start Small:

  • Screens: Focus on 1–3 screens/components most impacted by the story
  • Breakpoints: Start with mobile (375px) + desktop (1024px) only
  • States: Cover default + loading + empty + error + one interaction state (hover/focus)

Run Order:

  1. Stabilize UI (disable animations, wait for network idle)
  2. Capture screenshots for scoped screens at scoped breakpoints
  3. Run accessibility audit + check console errors
  4. If diffs occur: decide "expected change" vs "bug", update baselines or fix UI

Expand Only When:

  • Initial findings reveal responsive issues → add tablet/wide
  • Story explicitly covers all breakpoints
  • Epic validation requires full matrix

🌐 Browser MCP Tools

Use these tools for live validation:

ToolPurposeExample
browser_navigateNavigate to pagesbrowser_navigate("http://localhost:3000/dashboard")
browser_resizeSet viewport for responsivebrowser_resize(375, 667)
browser_take_screenshotCapture current statebrowser_take_screenshot("dashboard-mobile.png")
browser_snapshotGet element refs for interactionBefore clicks/hovers
browser_hoverTrigger hover statesbrowser_hover(element, ref)
browser_clickTrigger click statesbrowser_click(element, ref)
browser_wait_forWait for content to loadbrowser_wait_for(text="Dashboard")

Audit Tools

ToolWhen to RunWhat It Checks
runAccessibilityAuditEvery validationWCAG violations, ARIA issues
runPerformanceAuditWhen perf targets specifiedLCP, CLS, TTI
runBestPracticesAuditEvery validationSecurity, modern APIs
runSEOAuditPublic/marketing pagesMeta tags, structure
getConsoleErrorsEvery validationRuntime errors, warnings

📱 Standard Breakpoints

NameWidthHeightWhen to Test
Mobile375667Always (Tight Loop)
Tablet7681024When responsive scope
Desktop1024768Always (Tight Loop)
Wide1280800When wide layouts in scope
Ultrawide1536864Admin dashboards only

🔧 Validation Sequence

Follow this exact sequence for each page:

code
1. NAVIGATE
   browser_navigate(url)
   browser_wait_for(text="expected content")

2. STABILIZE (before any screenshots)
   - Inject CSS to disable animations
   - Wait for network idle
   - Mask dynamic content if needed

3. RESPONSIVE CAPTURE (Tight Loop: mobile + desktop only)
   For each breakpoint:
     browser_resize(width, height)
     browser_take_screenshot("{page}-{breakpoint}.png")

4. STATE CAPTURE
   For each interactive component:
     browser_snapshot()  # Get refs
     browser_hover(element, ref)
     browser_take_screenshot("{component}-hover.png")

5. AUDITS
   runAccessibilityAudit()
   getConsoleErrors()
   runPerformanceAudit()  # If targets specified

6. VALIDATE
   Compare screenshots to wireframes
   Check ui-spec.md Testing Checklist
   Report findings

🎭 Dynamic Content Handling

Before taking screenshots, stabilize dynamic content:

CSS Injection (via browser_evaluate):

javascript
// Disable all animations
document.head.insertAdjacentHTML('beforeend', `
  <style>
    *, *::before, *::after {
      animation-duration: 0s !important;
      transition-duration: 0s !important;
    }
  </style>
`);

Masking (for Playwright CI):

javascript
await expect(page).toHaveScreenshot({
  mask: [
    page.getByTestId('timestamp'),
    page.getByTestId('avatar'),
    page.getByTestId('ad-slot')
  ]
});

Tolerance (for minor differences):

javascript
await expect(page).toHaveScreenshot({
  maxDiffPixels: 100,        // Allow up to 100 different pixels
  maxDiffPixelRatio: 0.01,   // Or 1% of total
  threshold: 0.2             // Per-pixel color threshold
});

🧪 Playwright for CI

For CI/CD visual regression, set up Playwright:

bash
# Run visual tests
npx playwright test --project=chromium

# Update baselines when changes are intentional
npx playwright test --update-snapshots

Key Patterns:

typescript
// Visual assertion
await expect(page).toHaveScreenshot('dashboard.png');

// Component screenshot
await expect(page.getByTestId('header')).toHaveScreenshot('header.png');

// Full page
await expect(page).toHaveScreenshot('page.png', { fullPage: true });

✅ Validation Criteria

CheckPass CriteriaBlocking?
Responsive layoutCorrect at mobile + desktopYes
Design tokensNo hardcoded colors/spacing in changed filesYes
Accessibility0 critical/serious issuesYes
Console errors0 errors (warnings OK)Yes
PerformanceLCP < 2.5s, CLS < 0.1 (if targets specified)No
Voice/toneMatches ux-strategy.mdNo

🔗 Integration with Storybook

If the project uses Storybook:

  1. Run Storybook: npm run storybook
  2. Navigate to component stories
  3. Capture screenshots of each state
  4. Use Chromatic or Percy for automated regression
bash
# Chromatic (if configured)
npx chromatic --project-token=xxx

# Percy (if configured)  
npx percy storybook