test: add Playwright e2e smoke suite for punimtag dev
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 10s
CI / e2e (pull_request) Successful in 46s

Add an e2e/ Playwright harness (via @levkin/playkit) that smoke-tests
the public DEV host: login page loads, sign-out never redirects to a
LAN host, FastAPI /health responds, and forgot-password mail lands in
Mailtrap with a public reset link (Kolby #56/#57 regressions).

Wire it into Gitea Actions as a new `e2e` job (self-hosted runner,
Chromium via Playwright), gated behind the existing skip-ci-check.
Add npm root scripts (install:e2e, test:e2e) and gitignore e2e build
artifacts (node_modules, reports, .env).
This commit is contained in:
2026-07-14 17:11:38 -04:00
parent 44f3d696e4
commit 0a9223c943
15 changed files with 563 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
import { test as base, expect } from '@playwright/test';
import {
createPlaykitRuntime,
MailtrapClient,
type PlaykitFixtures,
} from '@levkin/playkit';
import { LoginPage } from './pages/LoginPage';
import { AccountMenu } from './pages/AccountMenu';
const runtime = createPlaykitRuntime({
...process.env,
PLAYKIT_PROJECT: process.env.PLAYKIT_PROJECT || 'punimtag',
PLAYKIT_ENV: process.env.PLAYKIT_ENV || 'dev',
PLAYKIT_API_BASE_URL:
process.env.PLAYKIT_API_BASE_URL ||
process.env.API_BASE_URL ||
'http://10.0.10.121:8000',
PLAYKIT_BASE_URL:
process.env.PLAYKIT_BASE_URL ||
process.env.BASE_URL ||
'https://punimtagdev.levkin.ca',
});
type PunimtagFixtures = PlaykitFixtures & {
loginPage: LoginPage;
accountMenu: AccountMenu;
e2eCredentials: { email: string; password: string } | null;
mailtrap: MailtrapClient | null;
};
export const test = base.extend<PunimtagFixtures>({
playkitConfig: async ({}, use) => use(runtime.playkitConfig),
playkitLog: async ({}, use) => use(runtime.playkitLog),
api: async ({}, use) => use(runtime.api),
timings: async ({}, use) => use(runtime.timings),
loginPage: async ({ page, playkitConfig }, use) =>
use(new LoginPage(page, playkitConfig.baseUrl)),
accountMenu: async ({ page, playkitConfig }, use) =>
use(new AccountMenu(page, playkitConfig.baseUrl)),
e2eCredentials: async ({}, use) => {
const email = process.env.E2E_ADMIN_EMAIL || process.env.E2E_EMAIL || '';
const password = process.env.E2E_ADMIN_PASSWORD || process.env.E2E_PASSWORD || '';
await use(email && password ? { email, password } : null);
},
mailtrap: async ({ playkitLog }, use) => {
await use(
MailtrapClient.fromEnv(process.env, playkitLog.child({ component: 'mailtrap' })),
);
},
});
export { expect };