Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["chrome-devtools-mcp@latest"]
}
}
}
28 changes: 27 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,30 @@ jobs:
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run build
- run: npm run test:e2e
- name: Run E2E tests (functional only)
run: npx playwright test --grep-invert "Visual Regression"

visual-regression:
runs-on: ubuntu-latest
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
NEXT_PUBLIC_CHAIN_ID: "8453"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run build
- name: Run visual regression
run: npx playwright test e2e/visual-regression.spec.ts --update-snapshots
- name: Upload snapshots
if: always()
uses: actions/upload-artifact@v4
with:
name: visual-regression-snapshots
path: e2e/__snapshots__/
retention-days: 30
29 changes: 29 additions & 0 deletions .github/workflows/update-snapshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Update Visual Snapshots

on:
workflow_dispatch:

jobs:
update-snapshots:
runs-on: ubuntu-latest
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
NEXT_PUBLIC_CHAIN_ID: "8453"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run build
- name: Generate snapshots
run: npx playwright test e2e/visual-regression.spec.ts --update-snapshots
- name: Upload snapshots
uses: actions/upload-artifact@v4
with:
name: visual-snapshots-linux
path: e2e/__snapshots__/
retention-days: 30
103 changes: 103 additions & 0 deletions e2e/visual-regression.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { test, expect } from "@playwright/test";

/**
* Visual regression tests — screenshot key pages at desktop and mobile viewports.
* Baselines stored in e2e/__snapshots__/.
* Update with: npx playwright test e2e/visual-regression.spec.ts --update-snapshots
*/

const DESKTOP = { width: 1280, height: 720 };
const MOBILE = { width: 375, height: 812 };

test.describe("Visual Regression — Desktop", () => {
test.beforeEach(async ({ page }) => {
await page.setViewportSize(DESKTOP);
});

test("Home page", async ({ page }) => {
await page.goto("/");
// Wait for content to settle
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("home-desktop.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});

test("Create page", async ({ page }) => {
await page.goto("/create");
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("create-desktop.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});

test("Token page", async ({ page }) => {
await page.goto("/token");
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("token-desktop.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});

test("Agents page", async ({ page }) => {
await page.goto("/agents");
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("agents-desktop.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});
});

test.describe("Visual Regression — Mobile", () => {
test.beforeEach(async ({ page }) => {
await page.setViewportSize(MOBILE);
});

test("Home page", async ({ page }) => {
await page.goto("/");
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("home-mobile.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});

test("Create page", async ({ page }) => {
await page.goto("/create");
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("create-mobile.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});

test("Token page", async ({ page }) => {
await page.goto("/token");
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("token-mobile.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});

test("Agents page", async ({ page }) => {
await page.goto("/agents");
await page.waitForLoadState("networkidle");
await page.waitForTimeout(500);
await expect(page).toHaveScreenshot("agents-mobile.png", {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});
});
1 change: 1 addition & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineConfig } from "@playwright/test";

export default defineConfig({
testDir: "./e2e",
snapshotPathTemplate: "{testDir}/__snapshots__/{testFileName}/{arg}{ext}",
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
Expand Down
Loading