141 lines
4.2 KiB
Markdown
141 lines
4.2 KiB
Markdown
---
|
|
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: <URL> ===
|
|
✅ Text renders: <key phrases found>
|
|
✅ 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 `<html>` or `data-theme` attribute |
|