diff --git a/.gitignore b/.gitignore index 30994385..9e7642de 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,11 @@ vite.config.js.timestamp-* vite.config.ts.timestamp-* +# Playwright +/test-results/ +/playwright-report/ +/playwright/.cache/ + # Generated assets static/favicon.ico static/pwa-64x64.png diff --git a/e2e/smoke.spec.ts b/e2e/smoke.spec.ts new file mode 100644 index 00000000..38899da3 --- /dev/null +++ b/e2e/smoke.spec.ts @@ -0,0 +1,12 @@ +import {expect, test} from "@playwright/test" + +test("boots the SPA on the home page", async ({page}) => { + const response = await page.goto("/") + + expect(response?.ok()).toBeTruthy() + + // adapter-static serves an empty shell that hydrates client-side, so the presence of + // rendered text proves the Svelte app actually mounted (not just that a file was served). + // TODO: tighten this to assert concrete onboarding UI once the markup is settled. + await expect(page.locator("body")).toContainText(/\S/, {timeout: 15_000}) +}) diff --git a/package.json b/package.json index 3cb04a98..c00a50f9 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check src && eslint src", + "test": "playwright test", + "test:ui": "playwright test --ui", "format": "git diff head --name-only --diff-filter d | grep -E '(js|ts|svelte|css)$' | xargs -r prettier --write", "format:all": "prettier --write src", "prepare": "husky" @@ -18,6 +20,7 @@ "devDependencies": { "@capacitor/assets": "^3.0.5", "@eslint/js": "^9.39.2", + "@playwright/test": "^1.49.1", "@sveltejs/kit": "^2.61.1", "@sveltejs/vite-plugin-svelte": "^5.1.1", "@tailwindcss/postcss": "^4.2.2", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..7b3bde87 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,27 @@ +import {defineConfig, devices} from "@playwright/test" + +// E2E tests live in ./e2e and run against the dev server (port 1847 from vite.config.ts). +// Run with `pnpm test:e2e` (after `pnpm exec playwright install` to fetch browsers). +export default defineConfig({ + testDir: "e2e", + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + reporter: "html", + use: { + baseURL: "http://localhost:1847", + trace: "on-first-retry", + }, + // Boots the SvelteKit dev server before the suite and reuses one if already running locally. + webServer: { + command: "pnpm dev", + url: "http://localhost:1847", + reuseExistingServer: !process.env.CI, + timeout: 120_000, + }, + projects: [ + {name: "chromium", use: {...devices["Desktop Chrome"]}}, + {name: "firefox", use: {...devices["Desktop Firefox"]}}, + {name: "webkit", use: {...devices["Desktop Safari"]}}, + ], +})