Simplify and standardize testing structure

This commit is contained in:
adilallo
2026-01-28 14:04:04 -07:00
parent e7a31789e3
commit 7ea724a8d9
95 changed files with 1534 additions and 15485 deletions
-391
View File
@@ -1,391 +0,0 @@
# Performance Optimization Guide
## 📋 Table of Contents
- [Overview](#overview)
- [Performance Targets](#performance-targets)
- [Frontend Optimizations](#frontend-optimizations)
- [Performance Monitoring](#performance-monitoring)
- [Bundle Analysis](#bundle-analysis)
- [Web Vitals Tracking](#web-vitals-tracking)
- [Performance Testing](#performance-testing)
- [Troubleshooting](#troubleshooting)
- [Best Practices](#best-practices)
## 🎯 Overview
This guide covers the comprehensive performance optimization strategy implemented in Community Rule 3.0 to achieve sub-2-second load times across all platform features.
### Performance Philosophy
- **Measure First**: Comprehensive monitoring before optimization
- **Performance Budgets**: Enforce limits to prevent regression
- **Real User Monitoring**: Track actual user experience
- **Continuous Optimization**: Regular monitoring and improvement
## 🎯 Performance Targets
### Core Web Vitals
- **LCP (Largest Contentful Paint)**: < 2.5s (Good)
- **FID (First Input Delay)**: < 100ms (Good)
- **CLS (Cumulative Layout Shift)**: < 0.1 (Good)
- **FCP (First Contentful Paint)**: < 1.8s (Good)
- **TTFB (Time to First Byte)**: < 800ms (Good)
### Bundle Size Targets
- **Initial JavaScript Bundle**: < 250KB gzipped (currently 101KB)
- **Total Bundle Size**: < 2MB
- **Individual Component Bundles**: < 50KB
- **Image Assets**: Optimized with WebP/AVIF formats
### Lighthouse Scores
- **Performance**: > 90
- **Accessibility**: > 90
- **Best Practices**: > 90
- **SEO**: > 90
## ⚡ Frontend Optimizations
### 1. Code Splitting
Dynamic imports for non-critical components to reduce initial bundle size:
```javascript
// Dynamic imports for non-critical components
const NumberedCards = dynamic(() => import("./components/NumberedCards"), {
loading: () => <div className="loading-placeholder">Loading...</div>,
});
const LogoWall = dynamic(() => import("./components/LogoWall"), {
loading: () => <div className="loading-placeholder">Loading...</div>,
});
```
### 2. React.memo Optimization
Applied to all 30+ components to prevent unnecessary re-renders:
```javascript
import React, { memo } from "react";
const MyComponent = memo(({ prop1, prop2 }) => {
return <div>{/* Component content */}</div>;
});
MyComponent.displayName = "MyComponent";
export default MyComponent;
```
### 3. useMemo and useCallback
Optimized expensive computations and event handlers:
```javascript
import React, { memo, useMemo, useCallback } from "react";
const OptimizedComponent = memo(({ data, onAction }) => {
// Memoize expensive computations
const processedData = useMemo(() => {
return data.map((item) => expensiveOperation(item));
}, [data]);
// Memoize event handlers
const handleClick = useCallback(
(id) => {
onAction(id);
},
[onAction],
);
return <div onClick={handleClick}>{/* Component content */}</div>;
});
```
### 4. Image Optimization
Enhanced `next/image` with lazy loading and blur placeholders:
```javascript
import Image from "next/image";
<Image
src="/assets/image.jpg"
alt="Description"
width={300}
height={200}
sizes="(max-width: 768px) 100vw, 50vw"
loading="lazy"
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>;
```
### 5. Font Optimization
Preloading and fallbacks for all fonts:
```javascript
import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google";
const inter = Inter({
subsets: ["latin"],
preload: true,
fallback: ["system-ui", "arial"],
});
const bricolageGrotesque = Bricolage_Grotesque({
subsets: ["latin"],
preload: true,
fallback: ["system-ui", "arial"],
});
```
### 6. Error Boundaries
Comprehensive error handling to prevent cascade failures:
```javascript
import React, { Component } from "react";
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error("ErrorBoundary caught an error:", error, errorInfo);
}
render() {
if (this.state.hasError) {
return <div>Something went wrong.</div>;
}
return this.props.children;
}
}
```
## 📊 Performance Monitoring
### Available Scripts
```bash
# Individual monitoring tools
npm run bundle:analyze # Analyze bundle sizes and budgets
npm run performance:monitor # Performance metrics and Lighthouse CI
npm run web-vitals:track # Core Web Vitals tracking
# Comprehensive testing
npm run test:performance # All performance tests
npm run monitor:all # All monitoring tools
```
### Performance Dashboard
Access the performance monitoring dashboard at `/monitor` to view:
- Real-time Web Vitals metrics
- Historical performance data
- Bundle analysis results
- Performance budget status
- Optimization recommendations
## 📦 Bundle Analysis
### Bundle Analyzer Script
The bundle analyzer provides comprehensive analysis of bundle sizes:
```bash
npm run bundle:analyze
```
**Features:**
- Analyzes static assets, chunks, and pages
- Checks against performance budgets
- Generates optimization recommendations
- Saves results in JSON and Markdown formats
**Output Files:**
- `.next/analyze/bundle-analysis.json` - Detailed analysis data
- `.next/analyze/bundle-report.md` - Human-readable report
### Performance Budgets
Defined in `performance-budgets.json`:
```json
{
"budgets": [
{
"name": "lcp",
"maxValue": 2500,
"description": "Largest Contentful Paint"
},
{
"name": "bundle-size",
"maxSizeKB": 250,
"description": "Initial JavaScript bundle size"
}
]
}
```
## 📈 Web Vitals Tracking
### Real-time Monitoring
The Web Vitals tracking system collects and reports Core Web Vitals:
```bash
npm run web-vitals:track
```
**Features:**
- Collects LCP, FID, CLS, FCP, TTFB metrics
- Stores historical data (last 100 entries per metric)
- Generates summary reports
- Provides optimization recommendations
**API Endpoint:**
- `POST /api/web-vitals` - Receives Web Vitals data
- `GET /api/web-vitals` - Returns aggregated metrics
### Web Vitals Dashboard
The dashboard component displays real-time and historical metrics:
```javascript
import WebVitalsDashboard from "./components/WebVitalsDashboard";
<WebVitalsDashboard />;
```
## 🧪 Performance Testing
### Comprehensive Testing
Run all performance tests with a single command:
```bash
npm run test:performance
```
**Test Coverage:**
- Bundle analysis with budget checking
- Performance monitoring with Lighthouse CI
- Web Vitals tracking setup
- Comprehensive reporting
### Individual Tests
```bash
# Bundle analysis only
npm run bundle:analyze
# Performance monitoring only
npm run performance:monitor
# Web Vitals tracking only
npm run web-vitals:track
# All monitoring tools
npm run monitor:all
```
## 🔧 Troubleshooting
### Common Issues
#### 1. Bundle Size Exceeds Budget
```bash
# Check bundle analysis
npm run bundle:analyze
# Review recommendations in .next/analyze/bundle-report.md
# Consider code splitting or removing unused dependencies
```
#### 2. Web Vitals Poor Performance
```bash
# Check Web Vitals data
npm run web-vitals:track
# Review dashboard at /monitor
# Optimize images, fonts, or JavaScript
```
#### 3. Performance Tests Failing
```bash
# Run comprehensive performance test
npm run test:performance
# Check individual components
npm run bundle:analyze
npm run performance:monitor
```
### Debug Commands
```bash
# Debug bundle analysis
npm run bundle:analyze --verbose
# Debug performance monitoring
npm run performance:monitor --debug
# Check Web Vitals data
curl http://localhost:3000/api/web-vitals
```
## 🎯 Best Practices
### Development
1. **Always use React.memo** for components that receive props
2. **Implement useMemo/useCallback** for expensive operations
3. **Use dynamic imports** for non-critical components
4. **Optimize images** with proper sizing and formats
5. **Preload critical fonts** and resources
### Monitoring
1. **Run bundle analysis** before major releases
2. **Monitor Web Vitals** in production
3. **Check performance budgets** in CI/CD
4. **Review optimization recommendations** regularly
### Performance Budgets
1. **Set realistic budgets** based on user needs
2. **Monitor budget violations** in CI/CD
3. **Optimize when budgets are exceeded**
4. **Update budgets** as requirements change
## 📚 Additional Resources
- **Next.js Performance**: https://nextjs.org/docs/advanced-features/measuring-performance
- **Web Vitals**: https://web.dev/vitals/
- **Lighthouse CI**: https://github.com/GoogleChrome/lighthouse-ci
- **React Performance**: https://react.dev/learn/render-and-commit
---
**Last Updated**: December 2024
**Maintained by**: CommunityRule Development Team
-810
View File
@@ -1,810 +0,0 @@
# Testing Framework Documentation
## 📋 Table of Contents
- [Overview](#overview)
- [Testing Architecture](#testing-architecture)
- [Quick Start](#quick-start)
- [Test Types & Coverage](#test-types--coverage)
- [Unit & Integration Testing](#unit--integration-testing)
- [E2E Testing](#e2e-testing)
- [Visual Regression Testing](#visual-regression-testing)
- [Accessibility Testing](#accessibility-testing)
- [Performance Testing](#performance-testing)
- [CI/CD Pipeline](#cicd-pipeline)
- [Development Workflow](#development-workflow)
- [Best Practices](#best-practices)
- [Troubleshooting](#troubleshooting)
## 🎯 Overview
The CommunityRule platform uses a comprehensive testing framework with multiple layers to ensure code quality, functionality, visual consistency, and accessibility across all browsers and devices.
### Testing Stack
- **Unit/Integration**: Vitest + JSDOM + React Testing Library
- **E2E**: Playwright (Chromium, Firefox, WebKit, Mobile)
- **Visual Regression**: Playwright Screenshots
- **Performance**: Lighthouse CI
- **Accessibility**: Axe-core + Playwright
- **CI/CD**: Gitea Actions
### Current Status
-**428 Unit Tests** (94.88% coverage - exceeds 85% target)
-**92 E2E Tests** across 4 browsers
-**23 Visual Regression Tests** per browser
-**Performance Budgets** with Lighthouse CI
-**WCAG 2.1 AA Compliance** with automated testing
-**Bundle Analysis** with automated monitoring
-**Web Vitals Tracking** with real-time metrics
-**Performance Optimization** with React.memo and code splitting
## 🏗 Testing Architecture
### Test Pyramid
- **Unit Tests**: Fast, focused, high coverage (94.88%)
- **Integration Tests**: Component interactions, data flow
- **E2E Tests**: Critical user journeys, cross-browser compatibility
### Testing Philosophy
**JSDOM Limitations**: Unit tests in JSDOM can't truly test responsive behavior since CSS media queries aren't evaluated. Therefore:
- **Unit/Integration Tests**: Test component structure, accessibility, and configuration
- **E2E Tests**: Test real responsive behavior at actual viewport widths
- **Visual Tests**: Capture visual consistency across breakpoints
## 🚀 Quick Start
### Prerequisites
```bash
# Install dependencies
npm install
# Install Playwright browsers
npx playwright install
```
### Essential Commands
```bash
# Unit tests with coverage
npm test
# E2E tests
npm run e2e
# Visual regression tests
npm run visual:test
# Performance tests
npm run lhci
# Storybook tests
npm run test:sb
```
## 🧪 Test Types & Coverage
### Test Structure
```
tests/
├── unit/ # Component unit tests
│ ├── Button.test.jsx # 12 tests
│ ├── Logo.test.jsx # 12 tests
│ ├── RuleCard.test.jsx # 18 tests
│ ├── SectionHeader.test.jsx # 17 tests
│ ├── NumberedCard.test.jsx # 18 tests
│ └── accessibility.test.jsx # 18 tests
├── integration/ # Component integration tests
│ ├── component-interactions.integration.test.jsx
│ ├── page-flow.integration.test.jsx
│ ├── user-journey.integration.test.jsx
│ ├── layout.integration.test.jsx
│ └── ContentLockup.integration.test.jsx
└── e2e/ # End-to-end tests
├── homepage.spec.ts # Homepage functionality
├── user-journeys.spec.ts # User workflows
├── header.responsive.spec.js # Responsive header
├── footer.responsive.spec.js # Responsive footer
├── visual-regression.spec.ts # Visual consistency
├── accessibility.spec.ts # Accessibility compliance
└── performance.spec.ts # Performance metrics
```
### Coverage Requirements
- **Statements**: >85% (Current: 94.88%) ✅
- **Branches**: >80% (Current: 86.93%) ✅
- **Functions**: >80% (Current: 88.67%) ✅
- **Lines**: >85% (Current: 94.88%) ✅
## 🧩 Unit & Integration Testing
### Framework
- **Vitest**: Fast unit test runner
- **JSDOM**: Browser environment simulation
- **React Testing Library**: Component testing utilities
- **MSW**: API mocking
### Configuration
```javascript
// vitest.config.js
export default defineConfig({
plugins: [react({ jsxRuntime: "automatic" })],
test: {
environment: "jsdom",
setupFiles: ["./vitest.setup.js"],
coverage: {
provider: "v8",
thresholds: { lines: 85, functions: 85, statements: 85, branches: 80 },
},
},
});
```
### Writing Unit Tests
```jsx
// tests/unit/Component.test.jsx
import { render, screen } from "@testing-library/react";
import { describe, test, expect, afterEach } from "vitest";
import { cleanup } from "@testing-library/react";
import Component from "../../app/components/Component";
describe("Component", () => {
afterEach(() => cleanup());
test("renders correctly", () => {
render(<Component />);
expect(screen.getByRole("button")).toBeInTheDocument();
});
test("handles user interactions", async () => {
const user = userEvent.setup();
render(<Component />);
const button = screen.getByRole("button");
await user.click(button);
expect(button).toHaveClass("clicked");
});
});
```
### Testing Library Queries (Priority Order)
1. **`getByRole`**: Most accessible, tests user experience
2. **`getByLabelText`**: For form inputs
3. **`getByText`**: For content
4. **`getByTestId`**: Last resort, avoid when possible
### Integration Testing
```jsx
test("components work together", () => {
render(
<div>
<Header />
<MainContent />
<Footer />
</div>,
);
// Test that components complement each other
expect(screen.getByRole("banner")).toBeInTheDocument();
expect(screen.getByRole("main")).toBeInTheDocument();
expect(screen.getByRole("contentinfo")).toBeInTheDocument();
});
```
### Available Scripts
```bash
npm test # Run all tests with coverage
npm run test:watch # Run tests in watch mode
npm run test:ui # Run tests with UI
```
## 🌐 E2E Testing
### Framework
- **Playwright**: Cross-browser E2E testing
- **Browsers**: Chromium, Firefox, WebKit, Mobile
- **Accessibility**: Axe-core integration
### Configuration
```typescript
// playwright.config.ts
export default defineConfig({
testDir: "./tests/e2e",
projects: [
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
{ name: "firefox", use: { ...devices["Desktop Firefox"] } },
{ name: "webkit", use: { ...devices["Desktop Safari"] } },
{ name: "mobile", use: { ...devices["iPhone 13"] } },
],
use: {
timezoneId: "UTC",
locale: "en-US",
headless: true,
},
});
```
### Test Categories
#### 1. Functional Tests
- Page loading and sections
- Component functionality
- Navigation and interactions
- User workflows
#### 2. Responsive Tests
- Layout changes between breakpoints
- Component visibility at different viewports
- Interactive behavior across screen sizes
#### 3. Accessibility Tests
- WCAG 2.1 AA compliance
- Screen reader compatibility
- Keyboard navigation
- Color contrast
### Writing E2E Tests
```typescript
// tests/e2e/example.spec.ts
import { test, expect } from "@playwright/test";
test.describe("Feature", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/");
});
test("should work correctly", async ({ page }) => {
await expect(page).toHaveTitle(/CommunityRule/);
await expect(page.locator("h1")).toBeVisible();
});
test("responsive behavior", async ({ page }) => {
// Test mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
await expect(page.getByTestId("mobile-nav")).toBeVisible();
// Test desktop viewport
await page.setViewportSize({ width: 1280, height: 800 });
await expect(page.getByTestId("desktop-nav")).toBeVisible();
});
});
```
### Available Scripts
```bash
npm run e2e # Run all E2E tests
npm run e2e:ui # Run E2E tests with UI
npm run e2e:serve # Start dev server and run tests
```
## 🎨 Visual Regression Testing
### Overview
Visual regression testing ensures UI consistency across browsers and prevents unintended visual changes by comparing screenshots against baseline images.
### Configuration
- **Snapshot Template**: `{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png`
- **Deterministic Rendering**: Fixed timezone (UTC), locale (en-US), viewport
- **Tolerance**: 2% pixel difference or 500 pixels maximum
- **Animation Handling**: Disabled during capture
### Screenshots Generated
- **Full page screenshots** (mobile, tablet, desktop)
- **Component screenshots** (hero, logo wall, cards, etc.)
- **Interactive states** (hover, focus, loading, error)
- **Special modes** (dark mode, high contrast, reduced motion)
### Breakpoint Coverage
- **Mobile**: 375x667 (iPhone)
- **Tablet**: 768x1024 (iPad)
- **Desktop**: 1280x800 (Standard)
- **Large Desktop**: 1920x1080 (Full HD)
### Managing Visual Changes
```bash
# Update baselines after intentional changes
npm run visual:update
# Run visual regression tests
npm run visual:test
# Run with UI for debugging
npm run visual:ui
```
### Snapshot Management
```bash
# Update snapshots for all projects
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts
# Update snapshots for specific project
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
# View test results
npx playwright show-report
```
## ♿ Accessibility Testing
### Framework
- **Unit Level**: jest-axe with Vitest (`tests/accessibility/unit/`)
- **E2E Level**: Playwright accessibility tests (`tests/accessibility/e2e/`)
- **Standards**: WCAG 2.1 AA compliance
### Test Organization
Accessibility tests are organized in a dedicated `tests/accessibility/` folder:
```
tests/accessibility/
├── unit/ # Unit-level accessibility tests
│ └── components.test.jsx # Component accessibility (jest-axe)
└── e2e/ # E2E accessibility tests
└── wcag-compliance.spec.ts # WCAG compliance (Playwright)
```
### Unit-Level Accessibility Testing
```jsx
// tests/accessibility/unit/components.test.jsx
import { axe, toHaveNoViolations } from "jest-axe";
test("component has no accessibility violations", async () => {
const { container } = render(<Component />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
```
### E2E Accessibility Testing
```typescript
// tests/accessibility/e2e/wcag-compliance.spec.ts
import { test, expect } from "@playwright/test";
test("WCAG 2.1 AA compliance - homepage", async ({ page }) => {
await page.goto("/");
// Check for proper HTML structure
const html = page.locator("html");
const lang = await html.getAttribute("lang");
expect(lang).toBeTruthy();
// Check for main heading
const h1 = page.locator("h1").first();
await expect(h1).toBeVisible();
});
```
### Running Accessibility Tests
```bash
# Run all accessibility tests
npm test tests/accessibility/
# Run unit accessibility tests only
npm test tests/accessibility/unit/
# Run E2E accessibility tests only
npx playwright test tests/accessibility/e2e/
# Run specific accessibility test
npx playwright test tests/accessibility/e2e/wcag-compliance.spec.ts
```
### Manual Testing Checklist
- [ ] Screen reader compatibility
- [ ] Keyboard navigation
- [ ] Color contrast (WCAG AA)
- [ ] Focus management
- [ ] ARIA attributes
- [ ] Semantic HTML
### WCAG 2.1 AA Requirements
- **Perceivable**: Text alternatives, captions, adaptable content
- **Operable**: Keyboard accessible, timing adjustable, navigation
- **Understandable**: Readable, predictable, input assistance
- **Robust**: Compatible with assistive technologies
## ⚡ Performance Testing
### Framework
- **Lighthouse CI**: Automated performance testing
- **Bundle Analysis**: Real-time bundle size monitoring
- **Web Vitals Tracking**: Core Web Vitals collection and reporting
- **Performance Monitoring**: Comprehensive performance metrics
- **Performance Budgets**: Defined thresholds with automated enforcement
### Configuration
```json
// .lighthouserc.json
{
"ci": {
"collect": {
"url": ["http://localhost:3010"],
"chromeFlags": [
"--no-sandbox",
"--disable-dev-shm-usage",
"--disable-gpu",
"--headless"
]
},
"assert": {
"assertions": {
"categories:performance": ["warn", { "minScore": 0.8 }],
"categories:accessibility": ["error", { "minScore": 0.8 }]
}
}
}
}
```
### Performance Metrics
- **Core Web Vitals**: LCP < 2.5s, FID < 100ms, CLS < 0.1
- **Performance Score**: >80
- **Accessibility Score**: >80
- **Best Practices**: >90
- **Bundle Size**: <250KB gzipped (currently 101KB)
### Performance Budgets
- **First Contentful Paint**: <3000ms
- **Largest Contentful Paint**: <5000ms
- **First Input Delay**: <100ms
- **TTFB**: <700ms
- **Bundle Size**: <250KB gzipped
- **Total Bundle Size**: <2MB
### Performance Optimizations
- **✅ Code Splitting**: Dynamic imports for non-critical components
- **✅ React.memo**: Applied to all 30+ components
- **✅ Image Optimization**: Enhanced `next/image` with lazy loading
- **✅ Font Optimization**: Preloading and fallbacks
- **✅ Bundle Analysis**: Real-time monitoring with budgets
- **✅ Error Boundaries**: Comprehensive error handling
### Available Scripts
```bash
# Individual monitoring tools
npm run bundle:analyze # Analyze bundle sizes and budgets
npm run performance:monitor # Performance metrics and Lighthouse CI
npm run web-vitals:track # Core Web Vitals tracking
# Comprehensive testing
npm run test:performance # All performance tests
npm run monitor:all # All monitoring tools
# Traditional Lighthouse CI
npm run lhci # Run Lighthouse CI
npm run lhci:mobile # Run with mobile preset
npm run lhci:desktop # Run with desktop preset
```
### Performance Monitoring Dashboard
Access the performance monitoring dashboard at `/monitor` to view:
- Real-time Web Vitals metrics
- Historical performance data
- Bundle analysis results
- Performance budget status
- Optimization recommendations
## 🔄 CI/CD Pipeline
### Gitea Actions Workflow
Location: `.gitea/workflows/ci.yaml`
### Pipeline Jobs
#### 1. Unit Tests
- **Node.js versions**: 18, 20
- **Coverage reporting**: Codecov integration
- **Parallel execution**: Matrix strategy
#### 2. E2E Tests
- **Browsers**: Chromium, Firefox, WebKit
- **Parallel execution**: Matrix strategy
- **Artifact upload**: Test results and reports
#### 3. Visual Regression Tests
- **Screenshot comparison**: Baseline vs current
- **Cross-browser validation**: All 4 browser projects
#### 4. Performance Tests
- **Lighthouse CI**: Performance budgets
- **Core Web Vitals**: Monitoring
- **Accessibility compliance**
#### 5. Storybook Tests
- **Component testing**: Automated tests
- **Accessibility validation**: WCAG compliance
- **Build verification**: Storybook compilation
#### 6. Lint & Format
- **ESLint**: Code quality
- **Prettier**: Code formatting
#### 7. Build Verification
- **Next.js build**: Application compilation
- **Storybook build**: Documentation compilation
### Triggers
```yaml
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
```
## 🛠 Development Workflow
### 1. Feature Development
```bash
# Create feature branch
git checkout -b feature/new-component
# Write tests first (TDD)
npm run test:watch
# Implement feature
# Ensure tests pass
# Run E2E tests
npm run e2e
# Commit changes
git add .
git commit -m "feat: add new component with tests"
```
### 2. Pull Request Process
1. **Create PR** → CI pipeline starts automatically
2. **Review CI Results** → All 7 jobs must pass
3. **Check Coverage** → Ensure >85% coverage
4. **Review Visual Changes** → Check screenshot diffs
5. **Merge** → Only if all checks pass
### 3. Visual Changes
```bash
# Make visual changes
# Run visual regression tests
npm run visual:test
# If changes are intentional, update baselines
npm run visual:update
# Review and commit updated snapshots
git add tests/e2e/visual-regression.spec.ts-snapshots/
git commit -m "Update visual regression snapshots for [describe changes]"
```
### 4. Performance Monitoring
```bash
# Check performance before deploying
npm run lhci
# Review performance budgets
# Update .lighthouserc.json if needed
```
## 📋 Best Practices
### 1. Test-Driven Development
- Write tests before implementation
- Use descriptive test names
- Test edge cases and error scenarios
- Maintain high test coverage
### 2. Component Testing
```jsx
// ✅ Good: Test behavior, not implementation
test("shows error message when form is invalid", () => {
render(<Form />);
fireEvent.click(screen.getByRole("button"));
expect(screen.getByText("Please fill all fields")).toBeInTheDocument();
});
// ❌ Avoid: Testing implementation details
test("calls onSubmit with form data", () => {
const mockSubmit = vi.fn();
render(<Form onSubmit={mockSubmit} />);
// Implementation details...
});
```
### 3. E2E Testing
- Test user workflows, not technical details
- Use semantic selectors (role, text, label)
- Test accessibility features
- Include error scenarios
### 4. Visual Regression
- Update baselines only for intentional changes
- Review screenshot diffs carefully
- Test across multiple viewports
- Consider animation states
### 5. Performance Testing
- Set realistic performance budgets
- Monitor Core Web Vitals
- Test on different network conditions
- Regular performance audits
### 6. Responsive Testing
```javascript
// ✅ Good: Test real viewport sizes
await page.setViewportSize({ width: 640, height: 700 });
// ✅ Good: Test visibility at breakpoints
if (bp.name === "xs") {
await expect(page.getByTestId("auth-xs")).toBeVisible();
}
// ❌ Avoid: Testing responsive behavior in JSDOM
// JSDOM doesn't evaluate CSS media queries
```
## 🔧 Troubleshooting
### Common Issues
#### 1. Unit Tests Failing
```bash
# Run tests locally
npm test
# Check for:
# - Missing imports
# - Incorrect assertions
# - Component changes
# - Test environment issues
```
#### 2. E2E Tests Failing
```bash
# Run locally first
npm run e2e
# Common issues:
# - Selector changes
# - Component structure changes
# - Network issues
# - Browser compatibility
```
#### 3. Visual Regression Failing
```bash
# Check if changes are intentional
npm run visual:test
# Update baselines if needed
npm run visual:update
# Review screenshot diffs in CI artifacts
```
#### 4. Performance Tests Failing
```bash
# Run locally
npm run lhci
# Check performance budgets in .lighthouserc.json
# Optimize slow components
# Review bundle size
```
#### 5. CI Pipeline Issues
```bash
# Check Gitea Actions logs
# Verify workflow configuration
# Check for missing dependencies
# Review environment variables
```
### Debug Commands
```bash
# Debug unit tests
npm run test:ui
# Debug E2E tests
npm run e2e:ui
# Debug with browser dev tools
npx playwright test --debug
# Run specific test file
npx playwright test tests/e2e/homepage.spec.ts
# Run tests in headed mode
npx playwright test --headed
```
## 📚 Additional Resources
### Documentation
- [Vitest Documentation](https://vitest.dev/)
- [Playwright Documentation](https://playwright.dev/)
- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/)
- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci)
- [Storybook Testing](https://storybook.js.org/docs/writing-tests/introduction)
### Tools
- [Codecov](https://codecov.io/) - Coverage reporting
- [Axe-core](https://github.com/dequelabs/axe-core) - Accessibility testing
- [MSW](https://mswjs.io/) - API mocking
### Best Practices
- [Testing Best Practices](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
- [E2E Testing Guide](https://playwright.dev/docs/best-practices)
- [Visual Regression Testing](https://storybook.js.org/docs/writing-tests/visual-testing)
---
**Last Updated**: December 2024
**Framework Version**: Next.js 15 + React 19 + Tailwind 4 + Storybook 9
**Maintained by**: CommunityRule Development Team
-357
View File
@@ -1,357 +0,0 @@
# Testing Quick Reference
## 🚀 Essential Commands
### Daily Development
```bash
# Run all tests with coverage
npm test
# Watch mode (during development)
npm run test:watch
# E2E tests
npm run e2e
# Visual regression tests
npm run visual:test
# Performance check
npm run lhci
# Performance monitoring
npm run test:performance # Comprehensive performance testing
npm run bundle:analyze # Bundle size analysis
npm run web-vitals:track # Web Vitals tracking
npm run monitor:all # All monitoring tools
# Storybook tests
npm run test:sb
```
### Test UI & Debugging
```bash
# Debug unit tests
npm run test:ui
# Debug E2E tests
npm run e2e:ui
# Debug with browser
npx playwright test --debug
# Run tests in headed mode
npx playwright test --headed
```
## 📊 Current Test Status
- **Unit Tests**: 94.88% ✅ (Target: >85%)
- **Integration Tests**: 5 comprehensive test suites ✅
- **E2E Tests**: 92 tests across 4 browsers ✅
- **Visual Regression**: 23 tests per browser ✅
- **Accessibility Tests**: WCAG 2.1 AA compliance ✅
- **Performance Tests**: Lighthouse CI with budgets ✅
- **Bundle Analysis**: Real-time monitoring with budgets ✅
- **Web Vitals Tracking**: Core Web Vitals collection ✅
- **Performance Optimization**: React.memo + code splitting ✅
## 🔧 Common Test Commands
### Unit Testing
```bash
# Run specific test file
npm test -- --run tests/unit/Component.test.jsx
# Run tests matching pattern
npm test -- --run Component
# Run with coverage report
npm test -- --coverage
# Run in watch mode
npm run test:watch
```
### E2E Testing
```bash
# Run specific test file
npm run e2e -- tests/e2e/homepage.spec.ts
# Run specific project (browser)
npm run e2e -- --project=chromium
# Run with headed browser
npm run e2e -- --headed
# Run with debug mode
npm run e2e -- --debug
```
### Visual Regression
```bash
# Update snapshots for all projects
npm run visual:update
# Update snapshots for specific project
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
# View test results
npx playwright show-report
```
### Performance Testing
```bash
# Run mobile performance test
npm run lhci:mobile
# Run desktop performance test
npm run lhci:desktop
# Run with custom budget
npm run performance:budget
```
### Accessibility Testing
```bash
# Run all accessibility tests
npm test tests/accessibility/
# Run unit accessibility tests only
npm test tests/accessibility/unit/
# Run E2E accessibility tests only
npx playwright test tests/accessibility/e2e/
# Run specific accessibility test
npx playwright test tests/accessibility/e2e/wcag-compliance.spec.ts
```
## 📱 Browser Support
| Browser | Project Name | Status |
| ----------- | ------------ | --------------- |
| **Chrome** | `chromium` | ✅ Full Support |
| **Firefox** | `firefox` | ✅ Full Support |
| **Safari** | `webkit` | ✅ Full Support |
| **Mobile** | `mobile` | ✅ Full Support |
## 🎯 Testing Best Practices
### 1. Test Structure (AAA Pattern)
```jsx
test("should do something", () => {
// Arrange: Set up test data
const data = { name: "Test" };
// Act: Perform the action
const result = processData(data);
// Assert: Verify the outcome
expect(result).toBe("Processed Test");
});
```
### 2. Query Priority
1. **`getByRole`** - Most accessible, tests user experience
2. **`getByLabelText`** - For form inputs
3. **`getByText`** - For content
4. **`getByTestId`** - Last resort, avoid when possible
### 3. Async Testing
```jsx
test("async operation", async () => {
const user = userEvent.setup();
render(<Component />);
const button = screen.getByRole("button");
await user.click(button);
await waitFor(() => {
expect(screen.getByText("Success")).toBeInTheDocument();
});
});
```
### 4. Responsive Testing
```javascript
// ✅ Good: Test real viewport sizes
await page.setViewportSize({ width: 640, height: 700 });
// ✅ Good: Test visibility at breakpoints
if (bp.name === "xs") {
await expect(page.getByTestId("auth-xs")).toBeVisible();
}
// ❌ Avoid: Testing responsive behavior in JSDOM
// JSDOM doesn't evaluate CSS media queries
```
## 🔍 Common Issues & Solutions
### Visual Regression Failures
```bash
# Regenerate snapshots
npm run visual:update
# Check for environment differences
# Ensure deterministic rendering in Playwright config
```
### E2E Test Failures
```bash
# Use waitFor instead of waitForTimeout
await page.waitForSelector("button", { state: "visible" });
# Use role-based selectors
await page.getByRole("button", { name: "Submit" }).click();
# Check for selector changes
# Verify component structure hasn't changed
```
### Performance Test Failures
```bash
# Check Chrome path on macOS
# Ensure arm64 Chrome for Apple Silicon
# Verify performance budgets in .lighthouserc.json
```
### Unit Test Failures
```bash
# Check for missing imports
# Verify component exports
# Ensure test environment setup
# Check for component changes
```
## 📈 Performance Budgets
### Lighthouse CI Targets
- **Performance Score**: >80
- **Accessibility Score**: >80
- **Best Practices**: >90
- **SEO Score**: >90
### Core Web Vitals
- **LCP**: <2.5s
- **FID**: <100ms
- **CLS**: <0.1
### Performance Budgets
- **First Contentful Paint**: <3000ms
- **Largest Contentful Paint**: <5000ms
- **First Input Delay**: <100ms
- **TTFB**: <700ms
## 🔄 CI/CD Pipeline Jobs
1. **Unit Tests** (Node 18, 20) - Coverage reporting
2. **E2E Tests** (Chromium, Firefox, WebKit) - Cross-browser testing
3. **Visual Regression Tests** - Screenshot comparison
4. **Performance Tests** - Lighthouse CI with budgets
5. **Storybook Tests** - Component testing & accessibility
6. **Lint & Format** - Code quality & formatting
7. **Build Verification** - Next.js & Storybook builds
## 📁 Test File Structure
```
tests/
├── unit/ # Component tests
│ ├── Button.test.jsx # 12 tests
│ ├── Logo.test.jsx # 12 tests
│ ├── RuleCard.test.jsx # 18 tests
│ ├── SectionHeader.test.jsx # 17 tests
│ ├── NumberedCard.test.jsx # 18 tests
│ └── ... # Other component tests
├── integration/ # Integration tests
│ ├── component-interactions.integration.test.jsx
│ ├── page-flow.integration.test.jsx
│ ├── user-journey.integration.test.jsx
│ ├── layout.integration.test.jsx
│ └── ContentLockup.integration.test.jsx
├── accessibility/ # Accessibility-focused tests
│ ├── unit/ # Unit-level accessibility (jest-axe)
│ │ └── components.test.jsx # Component accessibility tests
│ └── e2e/ # E2E accessibility (Playwright + axe-core)
│ └── wcag-compliance.spec.ts # WCAG compliance tests
└── e2e/ # General E2E tests
├── homepage.spec.ts # Homepage functionality
├── user-journeys.spec.ts # User workflows
├── header.responsive.spec.js # Responsive header
├── footer.responsive.spec.js # Responsive footer
├── visual-regression.spec.ts # Visual consistency
├── accessibility.spec.ts # General accessibility tests
└── performance.spec.ts # Performance metrics
```
## 🎨 Visual Regression Screenshots
### Generated Screenshots
- Full page (mobile, tablet, desktop)
- Component sections (hero, logo wall, cards)
- Interactive states (hover, focus, loading)
- Special modes (dark, high contrast, reduced motion)
### Managing Changes
```bash
# Intentional changes
npm run visual:update
# Review changes
git diff tests/e2e/visual-regression.spec.ts-snapshots/
# Commit updated snapshots
git add tests/e2e/visual-regression.spec.ts-snapshots/
git commit -m "Update visual regression snapshots for [describe changes]"
```
## 📈 Monitoring
### Test Metrics
- **Unit Tests**: 305 tests (94.88% coverage)
- **E2E Tests**: 92 tests (4 browsers)
- **Visual Screenshots**: 92 baselines per browser
- **Coverage**: >85% target (exceeded)
### CI Metrics
- **Pipeline Jobs**: 7 parallel jobs
- **Execution Time**: Monitor build performance
- **Success Rate**: Track pipeline stability
- **Artifacts**: Test results and screenshots
## 🔗 Useful Links
- **Full Testing Documentation**: [docs/guides/testing-framework.md](./testing-framework.md)
- **Vitest Docs**: https://vitest.dev/
- **Playwright Docs**: https://playwright.dev/
- **React Testing Library**: https://testing-library.com/docs/react-testing-library/intro/
- **Lighthouse CI**: https://github.com/GoogleChrome/lighthouse-ci
---
**Quick Reference Version**: December 2024
**For detailed guidelines, see [testing-framework.md](./testing-framework.md)**
-258
View File
@@ -1,258 +0,0 @@
# Testing Strategy for CommunityRule
## Overview
This document outlines our comprehensive testing strategy that properly separates unit testing from responsive behavior testing, following best practices for JSDOM limitations and real browser testing.
## Current Test Status
- **236 total tests** across the project
- **227 tests passing** (96.2% success rate)
- **9 tests failing** (performance and interaction tests)
- **15 test files** covering all major components
- **Performance Monitoring**: Comprehensive regression detection and budget enforcement
## Testing Philosophy
### The Problem with JSDOM and Responsive Testing
**Short take: Unit tests in JSDOM can't truly "switch breakpoints."** JSDOM doesn't evaluate CSS media queries, so Tailwind's `hidden sm:block …` won't change visibility when you "resize" the window.
### Solution: Proper Test Separation
- **Unit / component tests (Vitest + RTL):** assert **structure and classes**, not responsive visibility.
- **Responsive behavior:** verify with **browser-based tests** (Playwright) or **visual tests** (Chromatic/Storybook) at real viewport widths.
## Test Categories
### 1. Unit Tests (Vitest + React Testing Library)
**Purpose:** Test component structure, accessibility, and configuration data.
**What to test:**
- DOM roles/labels exist: `role="banner"`, nav landmark, menu items
- The right **Tailwind classes** are present on wrappers (`block sm:hidden`, `hidden md:block`, etc.)
- Data-driven bits produce the expected count/order (e.g., `navigationItems`, `avatarImages`, `logoConfig`)
- Component configuration and exported data structures
**Example:**
```javascript
// tests/unit/Header.structure.test.js
test("logo wrappers include breakpoint classes", () => {
render(<Header />);
const logoWrappers = screen.getAllByTestId("logo-wrapper");
// Check first logo variant (xs only)
expect(logoWrappers[0]).toHaveClass("block", "sm:hidden");
// Check second logo variant (sm only)
expect(logoWrappers[1]).toHaveClass("hidden", "sm:block", "md:hidden");
});
```
### 2. Browser-Based Tests (Playwright)
**Purpose:** Test real responsive behavior at actual viewport widths.
**What to test:**
- **Visibility** at real breakpoints
- **Layout changes** between breakpoints
- **Interactive behavior** at different screen sizes
- **Accessibility** across viewports
**Example:**
```javascript
// tests/e2e/header.responsive.spec.js
const breakpoints = [
{ name: "xs", width: 360, height: 700 },
{ name: "sm", width: 640, height: 700 },
{ name: "md", width: 768, height: 700 },
{ name: "lg", width: 1024, height: 700 },
{ name: "xl", width: 1280, height: 700 },
];
for (const bp of breakpoints) {
test(`header layout at ${bp.name}`, async ({ page }) => {
await page.setViewportSize({ width: bp.width, height: bp.height });
await page.goto("/");
const nav = page.getByRole("navigation", { name: /main navigation/i });
await expect(nav).toBeVisible();
});
}
```
### 3. Visual Tests (Storybook + Chromatic)
**Purpose:** Visual regression testing and design system validation.
**What to test:**
- **Visual diffs** per breakpoint
- **Design consistency** across viewports
- **Component variations** and states
**Example:**
```javascript
// stories/Header.responsive.stories.js
export default {
parameters: {
chromatic: {
viewports: [360, 640, 768, 1024, 1280],
delay: 100,
},
},
};
```
## Component Improvements
### Header Component Enhancements
1. **Added Test IDs** for easier testing:
```jsx
<div data-testid="logo-wrapper" className={config.breakpoint}>
{renderLogo(config.size, config.showText)}
</div>
```
2. **Exported Configuration** for testing:
```javascript
export const navigationItems = [...];
export const avatarImages = [...];
export const logoConfig = [...];
```
3. **Structured Breakpoint Containers**:
```jsx
<div data-testid="nav-xs" className="block sm:hidden">
<div data-testid="nav-sm" className="hidden sm:block md:hidden">
<div data-testid="nav-md" className="hidden md:block lg:hidden">
```
## Test File Structure
```
tests/
├── unit/ # Unit tests (Vitest + RTL)
│ ├── Header.test.jsx # CONSOLIDATED: Comprehensive Header tests
│ ├── Footer.test.jsx
│ ├── Layout.test.jsx
│ └── Page.test.jsx
├── integration/ # Integration tests
│ └── ContentLockup.integration.test.jsx
├── e2e/ # Browser tests (Playwright)
│ └── header.responsive.spec.js # NEW: Responsive behavior tests
└── stories/ # Storybook stories
└── Header.responsive.stories.js # NEW: Visual testing
```
## Best Practices
### Unit Testing (JSDOM)
1. **Test structure, not visibility**:
```javascript
// ✅ Good: Test classes exist
expect(element).toHaveClass("block", "sm:hidden");
// ❌ Bad: Test visibility (doesn't work in JSDOM)
expect(element).toBeVisible();
```
2. **Use test IDs for containers**:
```javascript
// ✅ Good: Test specific containers
const logoWrapper = screen.getByTestId("logo-wrapper");
// ❌ Bad: Query by complex class strings
const logoWrapper = document.querySelector(".block.sm\\:hidden");
```
3. **Test configuration data**:
```javascript
// ✅ Good: Test exported configuration
expect(navigationItems).toHaveLength(3);
expect(logoConfig).toHaveLength(5);
```
### Browser Testing (Playwright)
1. **Test real viewport sizes**:
```javascript
await page.setViewportSize({ width: 640, height: 700 });
```
2. **Test visibility at breakpoints**:
```javascript
if (bp.name === "xs") {
await expect(page.getByTestId("auth-xs")).toBeVisible();
}
```
3. **Test accessibility across viewports**:
```javascript
const interactiveElements = [
page.getByRole("link", { name: /use cases/i }),
page.getByRole("button", { name: /create rule/i }),
];
for (const element of interactiveElements) {
await expect(element).toBeVisible();
await expect(element).toBeEnabled();
}
```
## Running Tests
### Unit Tests
```bash
npm test # Run all unit tests
npm test tests/unit/ # Run only unit tests
npm test Header.structure # Run specific test file
```
### Browser Tests
```bash
npx playwright test # Run all browser tests
npx playwright test header.responsive.spec.js # Run specific test
```
### Visual Tests
```bash
npm run storybook # Start Storybook
npx chromatic --project-token=xxx # Run visual tests
```
## Future Improvements
1. **Add more Playwright tests** for other components
2. **Set up Chromatic** for visual regression testing
3. **Add performance tests** for responsive behavior
4. **Create component-specific test utilities**
5. **Add accessibility testing** with axe-core
## Key Takeaways
1. **JSDOM limitations** require separating structure tests from visibility tests
2. **Test IDs** make testing more reliable and maintainable
3. **Exported configuration** enables better data structure testing
4. **Real browser testing** is essential for responsive behavior
5. **Visual testing** catches design regressions across breakpoints
This strategy provides comprehensive coverage while respecting the limitations of different testing environments.
-391
View File
@@ -1,391 +0,0 @@
# Visual Regression Testing Guide
## Overview
Visual regression testing ensures UI consistency across browsers and prevents unintended visual changes by comparing screenshots against baseline images. This guide covers the complete workflow for managing visual regression tests.
## 🚀 Quick Start
### First-Time Setup
```bash
# 1. Generate baseline snapshots for all projects
npm run visual:update
# 2. Verify snapshots were created
ls tests/e2e/visual-regression.spec.ts-snapshots/
# 3. Commit the snapshots
git add tests/e2e/visual-regression.spec.ts-snapshots/
git commit -m "Add baseline visual regression snapshots"
# 4. Verify setup works
npm run visual:test
```
### Daily Workflow
```bash
# Run visual regression tests
npm run visual:test
# Run with UI for debugging
npm run visual:ui
# Update snapshots after UI changes
npm run visual:update
```
## 📝 Managing Visual Changes
### When UI Changes Are Intentional
1. **Make your UI changes** (design updates, component modifications, etc.)
2. **Update snapshots to reflect new design:**
```bash
npm run visual:update
```
3. **Review changes:**
```bash
git diff tests/e2e/visual-regression.spec.ts-snapshots/
```
4. **Commit updated snapshots:**
```bash
git add tests/e2e/visual-regression.spec.ts-snapshots/
git commit -m "Update snapshots for [describe changes]"
```
### When UI Changes Are Unintentional
1. **Investigate the failure** - Check what changed and why
2. **Fix the regression** - Revert or fix the unintended change
3. **Re-run tests** - Ensure they pass without updating snapshots
4. **Commit the fix** - Don't update snapshots for bug fixes
## ⚙️ Configuration
### Playwright Configuration
The visual regression tests use these key settings in `playwright.config.ts`:
```typescript
export default defineConfig({
expect: {
toHaveScreenshot: {
animations: "disabled",
maxDiffPixelRatio: 0.02, // 2% tolerance
maxDiffPixels: 500, // 500 pixel tolerance
},
},
use: {
timezoneId: "UTC", // Consistent timezone
locale: "en-US", // Consistent locale
headless: true, // Headless for CI
},
snapshotPathTemplate:
"{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png",
});
```
### Deterministic Rendering
To ensure consistent screenshots across environments:
- **Fixed timezone**: UTC
- **Fixed locale**: en-US
- **Fixed viewport**: 1280x800 (configurable per test)
- **Disabled animations**: Prevents timing-related differences
- **Browser-specific snapshots**: Separate baselines per browser
## 📱 Breakpoint Coverage
### Standard Viewports
| Breakpoint | Width | Height | Description |
| ----------- | ------ | ------ | ---------------- |
| **Mobile** | 375px | 667px | iPhone portrait |
| **Tablet** | 768px | 1024px | iPad portrait |
| **Desktop** | 1280px | 800px | Standard desktop |
| **Large** | 1920px | 1080px | Full HD desktop |
### Custom Viewports
```typescript
test("mobile layout", async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await expect(page).toHaveScreenshot("mobile-layout.png");
});
test("tablet layout", async ({ page }) => {
await page.setViewportSize({ width: 768, height: 1024 });
await expect(page).toHaveScreenshot("tablet-layout.png");
});
```
## 🎨 Screenshot Types
### Full Page Screenshots
```typescript
test("homepage full page", async ({ page }) => {
await expect(page).toHaveScreenshot("homepage-full.png", {
fullPage: true,
animations: "disabled",
scale: "css",
});
});
```
### Component Screenshots
```typescript
test("hero section", async ({ page }) => {
const hero = page.locator("[data-testid='hero-section']");
await expect(hero).toHaveScreenshot("hero-section.png");
});
```
### Interactive States
```typescript
test("button hover state", async ({ page }) => {
const button = page.getByRole("button", { name: "Submit" });
// Normal state
await expect(button).toHaveScreenshot("button-normal.png");
// Hover state
await button.hover();
await expect(button).toHaveScreenshot("button-hover.png");
});
```
### Special Modes
```typescript
test("dark mode", async ({ page }) => {
// Enable dark mode
await page.evaluate(() => {
document.documentElement.classList.add("dark");
});
await expect(page).toHaveScreenshot("dark-mode.png");
});
test("high contrast", async ({ page }) => {
// Enable high contrast
await page.evaluate(() => {
document.body.style.filter = "contrast(200%)";
});
await expect(page).toHaveScreenshot("high-contrast.png");
});
```
## 🔄 Snapshot Management
### Update Commands
```bash
# Update all snapshots for all projects
npm run visual:update
# Update snapshots for specific project
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
# Update snapshots for specific test
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --grep="homepage"
```
### Snapshot Naming Convention
Snapshots follow this pattern:
```
{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png
```
Examples:
- `tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-chromium.png`
- `tests/e2e/visual-regression.spec.ts-snapshots/hero-section-firefox.png`
- `tests/e2e/visual-regression.spec.ts-snapshots/button-hover-webkit.png`
- `tests/e2e/visual-regression.spec.ts-snapshots/mobile-layout-mobile.png`
### File Organization
```
tests/e2e/visual-regression.spec.ts-snapshots/
├── homepage-full-chromium.png
├── homepage-full-firefox.png
├── homepage-full-webkit.png
├── homepage-full-mobile.png
├── hero-section-chromium.png
├── hero-section-firefox.png
├── hero-section-webkit.png
├── hero-section-mobile.png
└── ... (92 total screenshots)
```
## 🐛 Troubleshooting
### Common Issues
#### 1. "Snapshot doesn't exist" errors
**Cause**: Baseline snapshots haven't been generated or are missing
**Solution**:
```bash
# Regenerate all snapshots
npm run visual:update
# Or regenerate for specific project
PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium
```
#### 2. Platform differences (macOS vs Linux)
**Cause**: Different font rendering between platforms
**Solution**:
- Use CI-generated snapshots for consistency
- Ensure deterministic rendering settings
- Check font availability across platforms
#### 3. Minor pixel differences
**Cause**: Font rendering, anti-aliasing, scaling differences
**Solution**:
- Check tolerance settings in `playwright.config.ts`
- Use `scale: "css"` for consistent scaling
- Ensure deterministic CSS properties
#### 4. Animation-related failures
**Cause**: Animations not fully disabled
**Solution**:
- Ensure `animations: "disabled"` is set in test configuration
- Wait for animations to complete before screenshots
- Use `waitForTimeout` if necessary
#### 5. Height differences (especially WebKit)
**Cause**: WebKit may render elements with slightly different heights
**Solution**:
- Increase tolerance for height-sensitive tests
- Use `maxDiffPixels: 1000` for specific tests
- Consider using `ignoreSize: false` (default)
### Debug Commands
```bash
# Run with UI for visual debugging
npm run visual:ui
# Run specific test with debugging
npx playwright test tests/e2e/visual-regression.spec.ts --grep="homepage" --debug
# Run with headed browser
npx playwright test tests/e2e/visual-regression.spec.ts --headed
# View test results
npx playwright show-report
```
### Environment Consistency
To ensure consistent results:
1. **Use same Node.js version** across environments
2. **Use same Playwright version** across environments
3. **Use same browser versions** when possible
4. **Set consistent environment variables** (timezone, locale)
5. **Use deterministic CSS** (avoid random values, timestamps)
## 📊 CI/CD Integration
### CI Workflow
Visual regression tests run automatically in the CI pipeline:
- **Main branch**: Tests run against existing snapshots
- **Feature branches**: Tests run against existing snapshots
- **Artifacts**: Test results and screenshots uploaded for review
### CI Best Practices
1. **Don't regenerate snapshots in CI** for feature branches
2. **Use CI-generated snapshots** as the source of truth
3. **Review screenshot diffs** in CI artifacts
4. **Fail fast** on visual regressions
### Artifact Management
```yaml
# Example CI artifact configuration
- name: Upload visual regression results
if: always()
uses: actions/upload-artifact@v3
with:
name: visual-regression-results
path: |
test-results/
tests/e2e/visual-regression.spec.ts-snapshots/
```
## 🎯 Best Practices
### 1. Snapshot Management
- **Update snapshots only for intentional changes**
- **Review all changes** before committing
- **Use descriptive names** for snapshot files
- **Keep snapshots in version control**
### 2. Test Design
- **Test critical UI components** first
- **Use consistent viewport sizes** across tests
- **Test responsive breakpoints** systematically
- **Include interactive states** when relevant
### 3. Performance
- **Limit snapshot count** to essential components
- **Use appropriate timeouts** for slow operations
- **Parallelize tests** when possible
- **Cache browser installations** in CI
### 4. Maintenance
- **Regular cleanup** of outdated snapshots
- **Update snapshots promptly** after UI changes
- **Monitor test execution time** and optimize
- **Review and update tolerance settings** as needed
## 📚 Additional Resources
- **Main Testing Documentation**: [testing-framework.md](./testing-framework.md) | [testing.md](./testing.md)
- **Playwright Visual Testing**: https://playwright.dev/docs/screenshots
- **Visual Regression Best Practices**: https://storybook.js.org/docs/writing-tests/visual-testing
- **CI/CD Integration**: [testing-quick-reference.md](./testing-quick-reference.md)
- **Performance Guide**: [performance.md](./performance.md)
---
**Last Updated**: December 2024
**Maintained by**: CommunityRule Development Team