- Storybook 8 setup with dark glass canvas, stories for all ui/ components - Visual regression tests (Playwright screenshots, 0.5% pixel diff) - Bundle size CI gate (fail > 250KB gzipped) - Comprehensive mock data: 20+ items for films, songs, books, TV, images, places, podcasts, news, nostr events; mock TMDB responses - E2E cross-browser matrix: Chromium + Firefox + WebKit + iPhone 14 + Galaxy S21 - Proxy integration tests (SSE format, tool_use, error handling, disconnect) - Lighthouse CI config (LCP < 3s, CLS < 0.15) - Dependency audit: weekly GitHub Actions workflow with license checker - CI workflow: lint, typecheck, test, bundle size, e2e, lighthouse, audit Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
|
|
test.describe('Visual Regression', () => {
|
|
test('ChatPage renders correctly', async ({ page }) => {
|
|
await page.goto('/')
|
|
await page.waitForLoadState('networkidle')
|
|
await expect(page).toHaveScreenshot('chat-page.png', {
|
|
maxDiffPixelRatio: 0.005,
|
|
fullPage: true,
|
|
})
|
|
})
|
|
|
|
test('ContentPanel renders correctly', async ({ page }) => {
|
|
await page.goto('/')
|
|
await page.waitForLoadState('networkidle')
|
|
// Open content panel by clicking a content tab
|
|
const filmTab = page.getByRole('button', { name: /film/i }).first()
|
|
if (await filmTab.isVisible()) {
|
|
await filmTab.click()
|
|
await page.waitForTimeout(500)
|
|
await expect(page).toHaveScreenshot('content-panel-films.png', {
|
|
maxDiffPixelRatio: 0.005,
|
|
})
|
|
}
|
|
})
|
|
|
|
test('PassphraseDialog renders correctly', async ({ page }) => {
|
|
await page.goto('/')
|
|
await page.waitForLoadState('networkidle')
|
|
// PassphraseDialog shows on first load if crypto is enabled
|
|
const dialog = page.locator('.glass-card').filter({ hasText: 'Unlock AIUI' })
|
|
if (await dialog.isVisible()) {
|
|
await expect(dialog).toHaveScreenshot('passphrase-dialog.png', {
|
|
maxDiffPixelRatio: 0.005,
|
|
})
|
|
}
|
|
})
|
|
|
|
test('BottomSheet renders correctly on mobile', async ({ page }) => {
|
|
await page.setViewportSize({ width: 390, height: 844 })
|
|
await page.goto('/')
|
|
await page.waitForLoadState('networkidle')
|
|
await expect(page).toHaveScreenshot('mobile-view.png', {
|
|
maxDiffPixelRatio: 0.005,
|
|
fullPage: true,
|
|
})
|
|
})
|
|
})
|