Network helpers, docs hygiene, Outline sync notes
CI / skip-ci-check (push) Successful in 6s
CI / release (push) Has been skipped
CI / build-and-test (push) Successful in 42s
CI / secret-scan (push) Successful in 2s

This commit was merged in pull request #1.
This commit is contained in:
2026-07-14 19:50:42 -05:00
parent 7369b1c5e5
commit 6e3763f44f
14 changed files with 635 additions and 87 deletions
+6 -2
View File
@@ -3,7 +3,7 @@
## 1. Depend on a release
```bash
npm install git+https://git.levkin.ca/ilia/playkit.git#v0.1.0
npm install git+https://git.levkin.ca/ilia/playkit.git#v0.3.0
npm install -D @playwright/test
npx playwright install chromium
```
@@ -25,7 +25,8 @@ Store in Infisical `LevkinOps` / `Development` (path e.g. `/playkit/punimtag`):
- `PLAYKIT_BASE_URL=https://punimtagdev.levkin.ca`
- `E2E_ADMIN_EMAIL` / `E2E_ADMIN_PASSWORD` (dedicated test user — not a humans password)
- optional `PLAYKIT_PUSHGATEWAY_URL`
- optional `PLAYKIT_PUSHGATEWAY_URL=http://10.0.10.24:9091` (Pushgateway on the observability LXC — config lives in ansible `deploy/observability/`; scrape job + `live-playkit` Grafana board are wired, but confirm `make deploy-observability` has actually been run before turning `PLAYKIT_METRICS_ENABLED=true` on in CI)
- for mail specs: `PLAYKIT_MAIL_PROVIDER=mailpit` (default) + `MAILPIT_BASE_URL` / `MAILPIT_USER` / `MAILPIT_PASSWORD`, or `MAILTRAP_*` for SaaS
Sync into Gitea Actions secrets for the consumer repo.
@@ -54,3 +55,6 @@ e2e:
PR → CI green (unit + e2e when secrets present) → merge → documented deploy script.
Do not claim “fixed” from a bare `pct exec` hotfix without a follow-up PR.
**Adoption pause:** do not add playkit to other app repos until punimtag + kit CI
have soaked for a few days. See `docs/IDEAS.md`.
+53
View File
@@ -0,0 +1,53 @@
# Ideas backlog (from similar OSS tools)
Notes from comparing `@levkin/playkit` to public kits (2026-07). Tracking items
also live in `ROADMAP.md` — this page expands *why* / *how*, not just the checkbox.
## Already shipping (borrowed shape)
- **Network interception + error monitor** — see `docs/NETWORK.md`. Sourced from
[`playwright-utils`](https://github.com/seontechnologies/playwright-utils)
(spy/stub + background 4xx/5xx “Sentry for tests”), trimmed to Levkin needs.
## Documented next (not implemented yet)
### Test burn-in (flake detection)
`playwright-utils` “burn-in” re-runs a spec N times (local or CI) before merge.
That is the *mechanism* behind playkits “flake quarantine” roadmap item —
implement burn-in first (CLI flag or `PLAYKIT_BURN_IN=N`), then quarantine can
consume “failed once in N” signals into Grafana / Annotations.
### Scheduled synthetic monitoring
[`playwright-exporter`](https://github.com/maravexa/playwright-exporter) runs
Playwright suites on a cron and exposes pass/fail + duration as Prometheus
metrics. Overlaps with “deploy-smoke CLI”. Prefer evaluating that tool (or a
thin wrapper) on a schedule against punimtag DEV **before** writing a bespoke
`playkit smoke` binary.
### Functional-core / fixture-shell audit
`playwright-utils` ships each utility as a plain function *and* a fixture.
Playkit already does this for `createPlaykitRuntime`; `ApiClient` /
`MailpitClient` are class-first. Audit later: keep classes, add thin function
wrappers only where consumers repeatedly wrap them themselves.
### Remote-write vs Pushgateway
[`playwright-prometheus-remote-write-reporter`](https://github.com/vitalics/playwright-prometheus-remote-write-reporter)
avoids a Pushgateway by writing straight into Prometheus. **Moot for now**
homelab Pushgateway is wired in ansible `deploy/observability` (pending apply).
Keep as a simplification option if Pushgateway ops cost ever hurts.
### Enterprise polish already on the roadmap
Contract testing (OpenAPI), axe-core a11y, and visual regression match what
`kitium-ai/playwright-helpers` treats as table stakes — already listed under
v0.5+ in `ROADMAP.md`; no extra checklist needed.
## Adoption pause
**Do not wire other app repos onto playkit yet.** Shake out punimtag + kit CI
for a few days (metrics path, release job, network helpers) before migrating
`screening` / `slack-sieve` / `portfolio`. Revisit after that soak.
+63
View File
@@ -0,0 +1,63 @@
# Network helpers (page traffic)
`ApiClient` *makes* HTTP calls from the test process. These helpers watch what the
**browser page** itself does during UI flows — spy/mock specific calls, and fail
tests that silently collect 4xx/5xx in the background.
## Spy / mock — `interceptNetworkCall`
Set up **before** the action that triggers the request:
```ts
import { interceptNetworkCall } from '@levkin/playkit';
const users = interceptNetworkCall({
page,
method: 'GET',
url: '**/api/users',
});
await page.goto('/users');
const { status, responseJson } = await users;
expect(status).toBe(200);
```
Stub a response:
```ts
const users = interceptNetworkCall({
page,
url: '**/api/users',
fulfillResponse: {
status: 200,
body: [{ id: 1, name: 'e2e' }],
},
});
await page.goto('/users');
await users;
await expect(page.getByText('e2e')).toBeVisible();
```
## Background errors — `startNetworkErrorMonitor`
Catches silent backend failures while the UI still looks fine:
```ts
import { startNetworkErrorMonitor } from '@levkin/playkit';
test('dashboard stays clean', async ({ page }) => {
const net = startNetworkErrorMonitor(page, {
excludePatterns: [/analytics\.google\.com/, 'sentry.io'],
});
try {
await page.goto('/dashboard');
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
} finally {
net.assertNoErrors(); // throws with method/status/url list if any 4xx/5xx
}
});
```
Opt out of known 4xx paths via `excludePatterns` (substring or `RegExp`).
Call `assertNoErrors()` (or `stop()`) so the listener is removed.
+34
View File
@@ -0,0 +1,34 @@
# Outline live docs checklist
Canonical prose stays in git (`README.md`, `docs/*`, `ROADMAP.md`).
Browsable front door: **Outline** → collection **QA & Dev** → doc **Playkit**
(`https://notes.levkin.ca`).
## When to update Outline
Update the Outline Playkit page **whenever playkit ships a release** (after the
tag / Gitea release is green), or whenever you merge a docs-only change that
changes consumer behavior:
1. Tag / release finished (or main docs PR merged)
2. Open Outline → QA & Dev → Playkit
3. Sync at least: current version pin, “whats in the box”, install snippet,
link to CHANGELOG / ROADMAP / NETWORK.md
4. Optional: `make outline-setup` from ansible only if you maintain seed notes there —
prefer editing the living page by hand so it stays readable
Paste template (adjust version):
```markdown
# @levkin/playkit
Shared Playwright + API e2e kit. **Source of truth is the git repo.**
- Repo: https://git.levkin.ca/ilia/playkit
- Current: vX.Y.Z
- Consumers: punimtag (e2e/) — *pause further adoption until soak completes*
## Quick links
- README · CONSUMER.md · NETWORK.md · IDEAS.md · ROADMAP · CHANGELOG
- Metrics: dash.levkin.ca → Live — Playkit e2e
```