--- name: visual-verify description: Verify a frontend page visually using Playwright. Takes screenshots (dark/light mode), extracts visible text, checks element positioning and responsive layout. Use when asked to verify a page, check how it looks, take a screenshot, or after building a new UI component. --- # Visual Verify ## When to use - After creating or modifying a frontend page/component - When asked "how does it look", "verify the page", "take a screenshot" - To check dark/light mode rendering - To verify text content (i18n) renders correctly - To check centering, alignment, and responsive layout ## When NOT to use - For unit tests or API testing (use test runners instead) - For full E2E test suites (use Playwright test framework directly) - When the dev server is not running ## Prerequisites - Playwright installed in the frontend project: `pnpm add -D playwright` - Chromium browser installed: `npx playwright install chromium` - Dev server running (usually `pnpm dev` on localhost:3000) ## Inputs | Input | Required | Default | Example | |-------|----------|---------|---------| | URL | Yes | — | `http://localhost:3000/login` | | Checks | No | all | `text`, `screenshot`, `position`, `responsive`, `interaction` | | Theme | No | both | `dark`, `light`, `both` | | Viewport | No | 1280x720 | `375x667` (mobile) | ## Workflow ### 1. Launch browser and navigate ```javascript const { chromium } = require('playwright'); const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: 1280, height: 720 } }); await page.goto(URL); await page.waitForTimeout(2000); // Wait for hydration ``` ### 2. Extract visible text ```javascript const text = await page.locator('body').innerText(); // Report: verify all expected text is present (i18n keys rendered) ``` ### 3. Check element positioning ```javascript // Verify centering of a key element const box = await page.locator('SELECTOR').boundingBox(); const vp = page.viewportSize(); const centerX = Math.round(box.x + box.width / 2); const centerY = Math.round(box.y + box.height / 2); // Report: distance from viewport center ``` ### 4. Take screenshots ```javascript // Dark mode (default) await page.screenshot({ path: '/tmp/verify-dark.png', fullPage: true }); // Light mode await page.evaluate(() => { document.documentElement.classList.remove('dark'); document.documentElement.style.colorScheme = 'light'; }); await page.waitForTimeout(500); await page.screenshot({ path: '/tmp/verify-light.png', fullPage: true }); ``` ### 5. Responsive check (optional) ```javascript // Mobile viewport await page.setViewportSize({ width: 375, height: 667 }); await page.waitForTimeout(500); await page.screenshot({ path: '/tmp/verify-mobile.png', fullPage: true }); // Tablet await page.setViewportSize({ width: 768, height: 1024 }); await page.waitForTimeout(500); await page.screenshot({ path: '/tmp/verify-tablet.png', fullPage: true }); ``` ### 6. Interaction check (optional) ```javascript // Click a button and verify outcome await page.locator('button[type="submit"]').click(); await page.waitForTimeout(1000); const errorText = await page.locator('body').innerText(); // Report: what changed after interaction ``` ### 7. Report findings Produce a summary: ``` === Visual Verification: === ✅ Text renders: ✅ Horizontally centered (X: 640/640) ⚠️ Vertically offset (Y: 414 vs 360) — acceptable, content above pushes down ✅ Dark mode: screenshot saved ✅ Light mode: screenshot saved ⚠️ Mobile: form overflows at 375px width ``` ### 8. Clean up ```javascript await browser.close(); ``` ## Output - Console report with pass/fail per check - Screenshots at `/tmp/verify-*.png` (dark, light, mobile, tablet) - Actionable findings if issues detected ## Troubleshooting | Issue | Resolution | |-------|-----------| | Page blank / no text | Increase `waitForTimeout` — hydration may be slow | | Cannot find module 'playwright' | Run `pnpm add -D playwright` in the frontend project | | Browser not found | Run `npx playwright install chromium` | | Connection refused | Ensure dev server is running on the expected port | | Dark mode not toggling | Check if theme uses `class="dark"` on `` or `data-theme` attribute |