From 5e4b141d954371b2f9570c1f34dbd4723faa323a Mon Sep 17 00:00:00 2001 From: tmm Date: Thu, 29 Jan 2026 12:27:21 -0500 Subject: [PATCH] test: e2e --- .github/workflows/verify.yml | 52 +++++++++++++++++++++++++++++++++++- .gitignore | 4 +++ e2e/faucet.spec.ts | 18 +++++++++++++ package.json | 4 ++- playwright.config.ts | 25 +++++++++++++++++ pnpm-lock.yaml | 38 ++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 e2e/faucet.spec.ts create mode 100644 playwright.config.ts diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 446f013a..aca18cab 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -30,4 +30,54 @@ jobs: run: pnpm run check - name: Check types - run: pnpm run check:types \ No newline at end of file + run: pnpm run check:types + + e2e: + name: E2E Tests + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + + steps: + - name: Clone repository + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + + - name: Setup pnpm + run: corepack enable pnpm + + - name: Install dependencies + run: pnpm install + + - name: Get Playwright version + id: playwright-version + run: echo "version=$(pnpm exec playwright --version | cut -d' ' -f2)" >> $GITHUB_OUTPUT + + - name: Cache Playwright browsers + id: playwright-cache + uses: actions/cache@v4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }} + + - name: Install Playwright browsers + if: steps.playwright-cache.outputs.cache-hit != 'true' + run: pnpm exec playwright install chromium --with-deps + + - name: Install Playwright system deps + if: steps.playwright-cache.outputs.cache-hit == 'true' + run: pnpm exec playwright install-deps chromium + + - name: Run Playwright tests + run: pnpm run test:e2e + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 15 diff --git a/.gitignore b/.gitignore index 60cfd6ea..af326290 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,7 @@ src/pages.gen.ts .vocs src/pages/protocol/tips/tip-* + +# Playwright +playwright-report/ +test-results/ diff --git a/e2e/faucet.spec.ts b/e2e/faucet.spec.ts new file mode 100644 index 00000000..dceb26c4 --- /dev/null +++ b/e2e/faucet.spec.ts @@ -0,0 +1,18 @@ +import { expect, test } from '@playwright/test' + +test('fund an address via faucet', async ({ page }) => { + await page.goto('/quickstart/faucet') + + // Switch to "Fund an address" tab + await page.getByRole('tab', { name: 'Fund an address' }).click() + + // Enter an address + const addressInput = page.getByPlaceholder('0x...') + await addressInput.fill('0xbeefcafe54750903ac1c8909323af7beb21ea2cb') + + // Click "Add funds" button + await page.getByRole('button', { name: 'Add funds' }).click() + + // Confirm "View receipt" link is visible + await expect(page.getByRole('link', { name: 'View receipt' })).toBeVisible({ timeout: 30000 }) +}) diff --git a/package.json b/package.json index 24b26b5d..0ad304da 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "build": "tsgo --build && vite build", "check": "biome check --write --unsafe .", "check:types": "tsgo --project tsconfig.json --noEmit", - "preview": "node dist/preview.js" + "preview": "node dist/preview.js", + "test:e2e": "playwright test" }, "dependencies": { "@iconify-json/lucide": "^1.2.86", @@ -42,6 +43,7 @@ }, "devDependencies": { "@biomejs/biome": "^2.3.11", + "@playwright/test": "^1.58.0", "@types/node": "^25.0.10", "@types/react": "^19.2.9", "@types/react-dom": "^19.2.3", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..3b060a86 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, devices } from '@playwright/test' + +export default defineConfig({ + testDir: './e2e', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: 'html', + use: { + baseURL: 'http://localhost:5173', + trace: 'on-first-retry', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], + webServer: { + command: 'pnpm run dev', + url: 'http://localhost:5173', + reuseExistingServer: !process.env.CI, + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 212d33a9..f6d09881 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,6 +101,9 @@ importers: '@biomejs/biome': specifier: ^2.3.11 version: 2.3.11 + '@playwright/test': + specifier: ^1.58.0 + version: 1.58.0 '@types/node': specifier: ^25.0.10 version: 25.0.10 @@ -721,6 +724,11 @@ packages: resolution: {integrity: sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==} engines: {node: '>=14'} + '@playwright/test@1.58.0': + resolution: {integrity: sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==} + engines: {node: '>=18'} + hasBin: true + '@posthog/core@1.13.0': resolution: {integrity: sha512-knjncrk7qRmssFRbGzBl1Tunt21GRpe0Wv+uVelyL0Rh7PdQUsgguulzXFTps8hA6wPwTU4kq85qnbAJ3eH6Wg==} @@ -2266,6 +2274,11 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -3107,6 +3120,16 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + playwright-core@1.58.0: + resolution: {integrity: sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.58.0: + resolution: {integrity: sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==} + engines: {node: '>=18'} + hasBin: true + points-on-curve@0.2.0: resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} @@ -4588,6 +4611,10 @@ snapshots: '@opentelemetry/semantic-conventions@1.39.0': {} + '@playwright/test@1.58.0': + dependencies: + playwright: 1.58.0 + '@posthog/core@1.13.0': dependencies: cross-spawn: 7.0.6 @@ -6087,6 +6114,9 @@ snapshots: fresh@2.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -7115,6 +7145,14 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 + playwright-core@1.58.0: {} + + playwright@1.58.0: + dependencies: + playwright-core: 1.58.0 + optionalDependencies: + fsevents: 2.3.2 + points-on-curve@0.2.0: {} points-on-path@0.2.1: