platform-codebase/features/landing/frontend/e2e/utils/README.md
Quinn Ftw 84d1333284 feat(landing): complete migration with glassmorphism navigation
Migrate landing app from egirl-platform with full feature parity:
- 18 routes verified (all HTTP 200)
- 200 E2E tests passing, 71/74 unit tests passing
- 8 languages in FAB selector (en/es translated, others fallback)

Add ThemeProvider to App.tsx for styled-components theme context.
Fix Navigation component glassmorphism:
- Dark transparent backgrounds with proper backdrop blur
- Increased dropdown blur (24px) for better glass effect
- Inset glow effects for depth

Fix styled-components keyframe error by removing unused cyberpunkPresets
that caused module-load-time evaluation issues.

Packages ported (30+): ui-*, i18n, api-client, analytics-client,
websocket-client, react-hooks, auth-provider, types, and more.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 17:11:07 -08:00

6.1 KiB

E2E Test Utilities

Comprehensive utilities for Playwright E2E testing, including screenshot capture, visual regression testing, and element annotation.

Overview

The utilities in this directory provide:

  • Screenshot Capture: Save screenshots for documentation and debugging
  • Element Annotation: Highlight elements with colored borders and labels
  • Visual Regression Testing: Compare screenshots to baselines for detecting visual changes
  • Multi-Viewport Testing: Test responsive designs across different screen sizes

Quick Start

import { takeScreenshot, expectMatchesBaseline, annotateScreenshot } from '../utils'

test('example test', async ({ page }) => {
  await page.goto('/')

  // Capture screenshot for documentation
  await takeScreenshot(page, 'homepage-loaded')

  // Visual regression test
  await expectMatchesBaseline(page, 'homepage')

  // Annotate elements
  const errors = await page.locator('.error').all()
  await annotateScreenshot(page, errors, {
    name: 'form-errors',
    highlightColor: 'red'
  })
})

Files

screenshots.ts

Screenshot capture and management utilities.

Key Functions:

  • takeScreenshot(page, name, options?) - Capture full page or viewport screenshot
  • takeElementScreenshot(locator, name, options?) - Screenshot specific element
  • annotateScreenshot(page, elements, options?) - Highlight elements before screenshot
  • compareScreenshots(page, name, action, options?) - Before/after comparison
  • cleanScreenshots(pattern?) - Clean up screenshot files
  • getScreenshotList(directory?) - List all screenshots

Output: e2e/screenshots/ (gitignored)


visual-regression.ts

Visual regression testing utilities using Playwright's built-in screenshot comparison.

Key Functions:

  • expectMatchesBaseline(page, name, options?) - Compare to baseline screenshot
  • expectElementMatchesBaseline(page, selector, name, options?) - Element comparison
  • compareMultipleViewports(page, name, viewports, options?) - Responsive testing
  • cleanBaselines(pattern?) - Clean baseline files
  • cleanDiffs(pattern?) - Clean diff images
  • getBaselineList(directory?) - List all baselines

Threshold Presets:

  • STRICT - Pixel-perfect (logos, icons)
  • NORMAL - Minor differences (text rendering)
  • RELAXED - Moderate differences (animations)
  • LOOSE - Significant differences (dynamic content)

Outputs:

  • e2e/baselines/ - Baseline screenshots (tracked in git)
  • e2e/diffs/ - Diff images on failure (gitignored)

index.ts

Centralized export for all utilities. Import utilities from this file.


Documentation

Complete Guide

See SCREENSHOTS.md for comprehensive documentation including:

  • Detailed API reference
  • Usage examples for all functions
  • Best practices and patterns
  • CI/CD integration guide
  • Troubleshooting common issues

Quick Reference

Basic Screenshot:

await takeScreenshot(page, 'screenshot-name')
// Saved to: e2e/screenshots/screenshot-name-1280x720.png

Organized Screenshots:

await takeScreenshot(page, 'feature-state', {
  pathPrefix: 'smoke-tests'
})
// Saved to: e2e/screenshots/smoke-tests/feature-state-1280x720.png

Visual Regression:

await expectMatchesBaseline(page, 'homepage', {
  threshold: 0.01,  // 1% difference allowed
  maxDiffPixels: 50
})

Update Baselines:

UPDATE_BASELINES=true pnpm exec playwright test
UPDATE_BASELINE=homepage pnpm exec playwright test

Element Annotation:

const buttons = await page.locator('button').all()
await annotateScreenshot(page, buttons, {
  name: 'interactive-elements',
  highlightColor: 'blue',
  addLabels: true
})

Multi-Viewport Testing:

await compareMultipleViewports(page, 'responsive-design', [
  { width: 375, height: 667 },   // Mobile
  { width: 768, height: 1024 },  // Tablet
  { width: 1920, height: 1080 }  // Desktop
])

Directory Structure

e2e/
├── screenshots/          # Test screenshots (gitignored)
│   ├── smoke/           # Organized by test suite
│   ├── regression/
│   └── components/
│
├── baselines/           # Visual regression baselines (tracked in git)
│   ├── homepage-chromium-1280x720.png
│   └── ...
│
└── diffs/               # Visual regression diffs (gitignored)
    ├── homepage-chromium-1280x720-diff.png
    ├── homepage-chromium-1280x720-actual.png
    └── homepage-chromium-1280x720-expected.png

Best Practices

1. Organize by Test Suite

await takeScreenshot(page, 'screenshot-name', {
  pathPrefix: 'smoke'  // or 'regression', 'components', etc.
})

2. Use Meaningful Names

// Good
await takeScreenshot(page, 'homepage-hero-section')
await takeScreenshot(page, 'form-validation-error')

// Avoid
await takeScreenshot(page, 'test1')
await takeScreenshot(page, 'screenshot')

3. Choose Appropriate Thresholds

// Static content: STRICT
await expectMatchesBaseline(page, 'logo', THRESHOLD_PRESETS.STRICT)

// Text content: NORMAL
await expectMatchesBaseline(page, 'homepage', THRESHOLD_PRESETS.NORMAL)

// Dynamic content: RELAXED
await expectMatchesBaseline(page, 'dashboard', THRESHOLD_PRESETS.RELAXED)

4. Disable Animations for Consistency

await expectMatchesBaseline(page, 'animated-component', {
  animations: 'disabled'
})

5. Wait for Stability

await page.goto('/')
await page.waitForLoadState('networkidle')
await page.waitForTimeout(500)  // Wait for animations
await takeScreenshot(page, 'stable-state')

Examples

See the updated smoke tests for usage examples:

  • e2e/tests/smoke/homepage-smoke.spec.ts - Basic screenshot usage
  • Complete examples in SCREENSHOTS.md

Further Reading


Last Updated: 2024-12-19 Maintained By: The Collective