chore: add Playwright E2E testing infrastructure (#673)
* feat: add Playwright testing infrastructure - Add @playwright/test dependency - Add playwright.config.ts with Chromium setup - Add test scripts (test, test:ui, test:headed) - Add hello world test to verify setup works This is the foundation for adding comprehensive E2E tests. Tests run against the Vite dev server on port 1420. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * ci: add E2E test workflow Runs Playwright tests on pull requests using Chromium. Uploads test artifacts on failure. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: rename e2e to playwright, fix CI test - Rename workflow from "E2E Tests" to "Playwright" - Rename scripts from test:e2e to test:playwright - Fix test to not require Tauri APIs (just check server responds) - Run prettier Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: CJ Pais <cj@cjpais.com>
This commit is contained in:
parent
9ea1555816
commit
9ef71046ba
6 changed files with 91 additions and 1 deletions
29
.github/workflows/playwright.yml
vendored
Normal file
29
.github/workflows/playwright.yml
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
name: "Playwright"
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
playwright:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: bunx playwright install chromium
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: bun run test:playwright
|
||||
|
||||
- name: Upload test results
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 7
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -29,3 +29,8 @@ dist-ssr
|
|||
/target/
|
||||
recording_*
|
||||
.crush/
|
||||
|
||||
# Playwright
|
||||
playwright-report/
|
||||
test-results/
|
||||
blob-report/
|
||||
|
|
|
|||
9
bun.lock
9
bun.lock
|
|
@ -31,6 +31,7 @@
|
|||
"zustand": "^5.0.8",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.58.0",
|
||||
"@tauri-apps/cli": "^2.9.1",
|
||||
"@types/node": "^24.9.1",
|
||||
"@types/react": "^18.3.26",
|
||||
|
|
@ -204,6 +205,8 @@
|
|||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@playwright/test": ["@playwright/test@1.58.0", "", { "dependencies": { "playwright": "1.58.0" }, "bin": { "playwright": "cli.js" } }, "sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg=="],
|
||||
|
||||
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.5", "", { "os": "android", "cpu": "arm" }, "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ=="],
|
||||
|
|
@ -608,6 +611,10 @@
|
|||
|
||||
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
|
||||
"playwright": ["playwright@1.58.0", "", { "dependencies": { "playwright-core": "1.58.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ=="],
|
||||
|
||||
"playwright-core": ["playwright-core@1.58.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw=="],
|
||||
|
||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
|
@ -730,6 +737,8 @@
|
|||
|
||||
"eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
"playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
"format": "prettier --write . && cd src-tauri && cargo fmt",
|
||||
"format:check": "prettier --check . && cd src-tauri && cargo fmt -- --check",
|
||||
"format:frontend": "prettier --write .",
|
||||
"format:backend": "cd src-tauri && cargo fmt"
|
||||
"format:backend": "cd src-tauri && cargo fmt",
|
||||
"test:playwright": "playwright test",
|
||||
"test:playwright:ui": "playwright test --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.16",
|
||||
|
|
@ -42,6 +44,7 @@
|
|||
"zustand": "^5.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.58.0",
|
||||
"@tauri-apps/cli": "^2.9.1",
|
||||
"@types/node": "^24.9.1",
|
||||
"@types/react": "^18.3.26",
|
||||
|
|
|
|||
26
playwright.config.ts
Normal file
26
playwright.config.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { defineConfig, devices } from "@playwright/test";
|
||||
|
||||
export default defineConfig({
|
||||
testDir: "./tests",
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: "html",
|
||||
use: {
|
||||
baseURL: "http://localhost:1420",
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
],
|
||||
webServer: {
|
||||
command: "bunx vite dev",
|
||||
url: "http://localhost:1420",
|
||||
reuseExistingServer: !process.env.CI,
|
||||
timeout: 30000,
|
||||
},
|
||||
});
|
||||
18
tests/app.spec.ts
Normal file
18
tests/app.spec.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test.describe("Handy App", () => {
|
||||
test("dev server responds", async ({ page }) => {
|
||||
// Just verify the dev server is running and responds
|
||||
const response = await page.goto("/");
|
||||
expect(response?.status()).toBe(200);
|
||||
});
|
||||
|
||||
test("page has html structure", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
|
||||
// Verify basic HTML structure exists
|
||||
const html = await page.content();
|
||||
expect(html).toContain("<html");
|
||||
expect(html).toContain("<body");
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue