visual-testing-advanced

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Advanced Visual Testing

高级视觉测试

<default_to_action> When detecting visual regressions or validating UI:
  1. CAPTURE baseline screenshots (first run establishes baseline)
  2. COMPARE new screenshots against baseline (pixel-by-pixel or AI)
  3. MASK dynamic content (timestamps, ads, user counts)
  4. TEST across devices (desktop, tablet, mobile viewports)
  5. REVIEW and approve intentional changes, fail on regressions
Quick Visual Testing Steps:
  • Set up baseline on main branch
  • Compare feature branch against baseline
  • Mask dynamic elements (timestamps, avatars)
  • Use AI-powered comparison to reduce false positives
  • Integrate in CI/CD to block visual regressions
Critical Success Factors:
  • Functional tests don't catch visual bugs
  • AI-powered tools reduce false positives
  • Review diffs, don't just auto-approve </default_to_action>
<default_to_action> 当检测视觉回归或验证UI时:
  1. 捕获基准截图(首次运行建立基准)
  2. 将新截图与基准进行对比(像素级或AI驱动)
  3. 屏蔽动态内容(时间戳、广告、用户数量等)
  4. 跨设备测试(桌面、平板、移动设备视口)
  5. 审核并批准有意的变更,若出现回归则标记失败
快速视觉测试步骤:
  • 在主分支上设置基准
  • 将功能分支与基准进行对比
  • 屏蔽动态元素(时间戳、头像等)
  • 使用AI驱动的对比减少误报
  • 集成到CI/CD中以拦截视觉回归
关键成功因素:
  • 功能测试无法捕获视觉bug
  • AI驱动的工具可减少误报
  • 需审核差异结果,不要仅依赖自动批准 </default_to_action>

Quick Reference Card

快速参考卡片

When to Use

适用场景

  • UI component changes
  • CSS/styling modifications
  • Responsive design validation
  • Cross-browser consistency checks
  • UI组件变更
  • CSS/样式修改
  • 响应式设计验证
  • 跨浏览器一致性检查

Visual Bug Types

视觉Bug类型

Bug TypeDescription
Layout shiftElements moved position
Color changeUnintended color modification
Font renderingTypography issues
AlignmentSpacing/alignment problems
Missing imagesBroken image paths
OverflowContent clipping
Bug类型描述
布局偏移元素位置移动
颜色变更非预期的颜色修改
字体渲染排版问题
对齐问题间距/对齐异常
图片缺失图片路径损坏
内容溢出内容被截断

Comparison Algorithms

对比算法

AlgorithmBest For
Pixel diffExact match requirement
Structural similarityHandle anti-aliasing
AI semanticIgnore insignificant changes

算法适用场景
像素对比要求完全匹配的场景
结构相似度处理抗锯齿问题
AI语义对比忽略无关紧要的变更

Visual Regression with Playwright

基于Playwright的视觉回归测试

javascript
import { test, expect } from '@playwright/test';

test('homepage visual regression', async ({ page }) => {
  await page.goto('https://example.com');

  // Capture and compare screenshot
  await expect(page).toHaveScreenshot('homepage.png');
  // First run: saves baseline
  // Subsequent runs: compares to baseline
});

test('responsive design', async ({ page }) => {
  // Mobile viewport
  await page.setViewportSize({ width: 375, height: 667 });
  await page.goto('https://example.com');
  await expect(page).toHaveScreenshot('homepage-mobile.png');

  // Tablet viewport
  await page.setViewportSize({ width: 768, height: 1024 });
  await expect(page).toHaveScreenshot('homepage-tablet.png');
});

javascript
import { test, expect } from '@playwright/test';

test('homepage visual regression', async ({ page }) => {
  await page.goto('https://example.com');

  // Capture and compare screenshot
  await expect(page).toHaveScreenshot('homepage.png');
  // First run: saves baseline
  // Subsequent runs: compares to baseline
});

test('responsive design', async ({ page }) => {
  // Mobile viewport
  await page.setViewportSize({ width: 375, height: 667 });
  await page.goto('https://example.com');
  await expect(page).toHaveScreenshot('homepage-mobile.png');

  // Tablet viewport
  await page.setViewportSize({ width: 768, height: 1024 });
  await page.goto('https://example.com');
  await expect(page).toHaveScreenshot('homepage-tablet.png');
});

Handling Dynamic Content

处理动态内容

javascript
test('mask dynamic elements', async ({ page }) => {
  await page.goto('https://example.com');

  await expect(page).toHaveScreenshot({
    mask: [
      page.locator('.timestamp'),     // Dynamic time
      page.locator('.user-count'),    // Live counter
      page.locator('.advertisement'), // Ads
      page.locator('.avatar')         // User avatars
    ]
  });
});

javascript
test('mask dynamic elements', async ({ page }) => {
  await page.goto('https://example.com');

  await expect(page).toHaveScreenshot({
    mask: [
      page.locator('.timestamp'),     // Dynamic time
      page.locator('.user-count'),    // Live counter
      page.locator('.advertisement'), // Ads
      page.locator('.avatar')         // User avatars
    ]
  });
});

AI-Powered Visual Testing (Percy)

AI驱动的视觉测试(Percy)

javascript
import percySnapshot from '@percy/playwright';

test('AI-powered visual test', async ({ page }) => {
  await page.goto('https://example.com');

  // Percy uses AI to ignore anti-aliasing, minor font differences
  await percySnapshot(page, 'Homepage');
});

test('component visual test', async ({ page }) => {
  await page.goto('https://example.com/components');

  // Snapshot specific component
  const button = page.locator('.primary-button');
  await percySnapshot(page, 'Primary Button', {
    scope: button
  });
});

javascript
import percySnapshot from '@percy/playwright';

test('AI-powered visual test', async ({ page }) => {
  await page.goto('https://example.com');

  // Percy uses AI to ignore anti-aliasing, minor font differences
  await percySnapshot(page, 'Homepage');
});

test('component visual test', async ({ page }) => {
  await page.goto('https://example.com/components');

  // Snapshot specific component
  const button = page.locator('.primary-button');
  await percySnapshot(page, 'Primary Button', {
    scope: button
  });
});

Playwright Configuration

Playwright配置

javascript
// playwright.config.js
export default {
  expect: {
    toHaveScreenshot: {
      maxDiffPixels: 100,      // Allow 100 pixel difference
      maxDiffPixelRatio: 0.01, // Or 1% of image
      threshold: 0.2,          // Color similarity threshold
      animations: 'disabled',  // Disable animations
      caret: 'hide'            // Hide cursor
    }
  }
};

javascript
// playwright.config.js
export default {
  expect: {
    toHaveScreenshot: {
      maxDiffPixels: 100,      // Allow 100 pixel difference
      maxDiffPixelRatio: 0.01, // Or 1% of image
      threshold: 0.2,          // Color similarity threshold
      animations: 'disabled',  // Disable animations
      caret: 'hide'            // Hide cursor
    }
  }
};

Agent-Driven Visual Testing

Agent驱动的视觉测试

typescript
// Comprehensive visual regression
await Task("Visual Regression Suite", {
  baseline: 'main-branch',
  current: 'feature-branch',
  pages: ['homepage', 'product', 'checkout'],
  devices: ['desktop', 'tablet', 'mobile'],
  browsers: ['chrome', 'firefox', 'safari'],
  threshold: 0.01
}, "qe-visual-tester");

// Returns:
// {
//   comparisons: 27,  // 3 pages × 3 devices × 3 browsers
//   differences: 2,
//   report: 'visual-regression-report.html'
// }

typescript
// Comprehensive visual regression
await Task("Visual Regression Suite", {
  baseline: 'main-branch',
  current: 'feature-branch',
  pages: ['homepage', 'product', 'checkout'],
  devices: ['desktop', 'tablet', 'mobile'],
  browsers: ['chrome', 'firefox', 'safari'],
  threshold: 0.01
}, "qe-visual-tester");

// Returns:
// {
//   comparisons: 27,  // 3 pages × 3 devices × 3 browsers
//   differences: 2,
//   report: 'visual-regression-report.html'
// }

Agent Coordination Hints

Agent协作提示

Memory Namespace

内存命名空间

aqe/visual-testing/
├── baselines/*          - Baseline screenshots
├── comparisons/*        - Diff results
├── components/*         - Component snapshots
└── reports/*            - Visual regression reports
aqe/visual-testing/
├── baselines/*          - Baseline screenshots
├── comparisons/*        - Diff results
├── components/*         - Component snapshots
└── reports/*            - Visual regression reports

Fleet Coordination

集群协作

typescript
const visualFleet = await FleetManager.coordinate({
  strategy: 'visual-testing',
  agents: [
    'qe-visual-tester',   // Screenshot comparison
    'qe-test-executor',   // Cross-browser execution
    'qe-quality-gate'     // Block on visual regressions
  ],
  topology: 'parallel'
});

typescript
const visualFleet = await FleetManager.coordinate({
  strategy: 'visual-testing',
  agents: [
    'qe-visual-tester',   // Screenshot comparison
    'qe-test-executor',   // Cross-browser execution
    'qe-quality-gate'     // Block on visual regressions
  ],
  topology: 'parallel'
});

Related Skills

相关技能

  • accessibility-testing - Visual a11y checks
  • compatibility-testing - Cross-browser visuals
  • regression-testing - Regression suite

  • accessibility-testing - 视觉无障碍测试
  • compatibility-testing - 跨浏览器视觉测试
  • regression-testing - 回归测试套件

Remember

注意事项

Functional tests don't catch visual bugs. Layout shifts, color changes, font rendering, alignment issues - all invisible to functional tests but visible to users.
AI-powered tools reduce false positives. Percy, Applitools use AI to ignore insignificant differences (anti-aliasing, minor font rendering).
With Agents:
qe-visual-tester
automates visual regression across browsers and devices, uses AI to filter noise, and generates visual diff reports. Catches UI regressions before users see them.
功能测试无法捕获视觉bug。 布局偏移、颜色变更、字体渲染、对齐问题——这些都无法被功能检测到,但用户却能直观看到。
AI驱动的工具可减少误报。 Percy、Applitools等工具借助AI忽略无关紧要的差异(如抗锯齿、轻微字体渲染差异)。
借助Agents:
qe-visual-tester
可跨浏览器和设备自动化执行视觉回归测试,利用AI过滤无效差异,并生成视觉差异报告。在用户发现之前捕获UI回归问题。