From e923a17707925a7589dd83388f58c3d8c2b33433 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sun, 1 Mar 2026 09:15:54 +0100 Subject: [PATCH] test(e2e): add Playwright with browser tests for login, logo, dashboard --- .pm-checkpoint.json | 11 +++--- frontend/EOF | 0 frontend/package-lock.json | 64 +++++++++++++++++++++++++++++++++++ frontend/package.json | 1 + frontend/playwright.config.js | 12 +++++++ frontend/tests/gravl.spec.js | 17 ++++++++++ tests/example.spec.js | 0 7 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 frontend/EOF create mode 100644 frontend/playwright.config.js create mode 100644 frontend/tests/gravl.spec.js create mode 100644 tests/example.spec.js diff --git a/.pm-checkpoint.json b/.pm-checkpoint.json index 35fe620..e23ca11 100644 --- a/.pm-checkpoint.json +++ b/.pm-checkpoint.json @@ -1,9 +1,12 @@ { - "lastRun": "2026-03-01T04:00:00+01:00", - "status": "completed", + "lastRun": "2026-03-01T08:44:00+01:00", + "status": "in_progress", "phase": "04-workout-modification", - "activeTask": "04-02-backend-api", + "activeTask": "04-03-frontend-workout-edit", "tasksCompleted": ["01-input-ux", "02-flexible-sets", "03-design-polish", "04-01-schema-migration", "04-02-backend-api"], "nextTask": "04-03-frontend-workout-edit", - "notes": "Backend API complete for custom workouts. Added 6 new endpoints + updated 3 log endpoints with source_type support. Next: Frontend edit UI." + "recoveryFrom": "2026-03-01T06:42:00+01:00", + "agentSession": "mild-reef", + "agentType": "claude-code", + "notes": "Frontend agent spawned for 04-03. Working on: Edit Workout button, Exercise picker modal, swap/add exercise flows, fork confirmation dialog. Session: mild-reef" } diff --git a/frontend/EOF b/frontend/EOF new file mode 100644 index 0000000..e69de29 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3050ef2..9fbace7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,6 +13,7 @@ "react-router-dom": "^6.21.0" }, "devDependencies": { + "@playwright/test": "^1.58.2", "@types/react": "^18.2.43", "@types/react-dom": "^18.2.17", "@vitejs/plugin-react": "^4.2.1", @@ -742,6 +743,22 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@playwright/test": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", + "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@remix-run/router": { "version": "1.23.2", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", @@ -1481,6 +1498,53 @@ "dev": true, "license": "ISC" }, + "node_modules/playwright": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", + "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", + "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", diff --git a/frontend/package.json b/frontend/package.json index 5ad8420..83c5e54 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,6 +14,7 @@ "react-router-dom": "^6.21.0" }, "devDependencies": { + "@playwright/test": "^1.58.2", "@types/react": "^18.2.43", "@types/react-dom": "^18.2.17", "@vitejs/plugin-react": "^4.2.1", diff --git a/frontend/playwright.config.js b/frontend/playwright.config.js new file mode 100644 index 0000000..a158b5f --- /dev/null +++ b/frontend/playwright.config.js @@ -0,0 +1,12 @@ +module.exports = { + testDir: "./tests", + use: { + baseURL: process.env.STAGING_URL || "https://gravl.homelab.local", + headless: true, + screenshot: "only-on-failure", + }, + projects: [{ + name: "chromium", + use: { browserName: "chromium" } + }] +}; diff --git a/frontend/tests/gravl.spec.js b/frontend/tests/gravl.spec.js new file mode 100644 index 0000000..24da1ae --- /dev/null +++ b/frontend/tests/gravl.spec.js @@ -0,0 +1,17 @@ +const { test, expect } = require("@playwright/test"); + +test("login page loads", async ({ page }) => { + await page.goto("/login"); + await expect(page.locator("form")).toBeVisible(); +}); + +test("logo exists", async ({ page }) => { + await page.goto("/login"); + const logo = await page.locator("svg, img[class*=logo], .logo").first(); + await expect(logo).toBeVisible(); +}); + +test("dashboard loads", async ({ page }) => { + await page.goto("/"); + await expect(page).toHaveTitle(/Gravl/); +}); diff --git a/tests/example.spec.js b/tests/example.spec.js new file mode 100644 index 0000000..e69de29