The Grafana k6 browser-test harness that lives in vuer_oss test/tests/k6/ and is run from vuer_docker’s k6.yml. Landed by FKITDEV-9041; the migration of the existing Playwright suite onto it is FKITDEV-9200. This note covers the harness itself — how it is wired, how to run it, and the three structural things it does not give you (CI verification, test ordering, fixture seeding).
For Agents
Nothing about the k6 suite is verified by CI. It is not linted, not typechecked, and not run by any workflow. Treat every change to
test/tests/k6/as unverified until you runtsc -p test/tests/k6/tsconfig.jsonyourself.
Harness anatomy
| Repo | Commit | What it contributes |
|---|---|---|
| vuer_docker | 8ae9f0c (PR #223) | k6.yml, .env:CI_DOMAIN, README ## E2E Testing |
| vuer_oss | 0e63bcd166 (PR #8085) — tip of origin/devel | test/tests/k6/ — all.ts, lib/env.ts, lib/flows.ts, tsconfig.json, README.md, + 2 reference migrations |
k6.yml runs the stock grafana/k6:master-with-browser image — no custom k6 build, no extensions. It mounts /workspace/vuer_oss/test/tests/k6 → /e2e and its command is:
run /e2e/${K6_TEST_FILE:-all.ts}
The only env var it passes through is CI_DOMAIN.
docker compose -f k6.yml up # whole suite (all.ts)
K6_TEST_FILE=auditlog.ts docker compose -f k6.yml up # single fileThe two reference migrations shipped with the scaffolding are dashboard and selfservice-list.
Nothing in CI verifies this suite
The k6 suite is invisible to every gate
test/tests/k6/tsconfig.jsonis a separate tsconfig (types:["k6"],strict,allowImportingTsExtensions,noEmit). The root tsconfig does not includetest/.yarn lintignorestest/*.- There is no
typechecknpm script in the repo, and no typecheck job in CI (see typescript-in-vuer-repos — TS in the vuer repos is editor/ESLint-only).Net effect: a k6 test file can be syntactically broken, type-broken, or reference a deleted page object and no gate will notice.
Typecheck it by hand, with @types/k6 installed:
tsc -p test/tests/k6/tsconfig.jsonOrdering: what k6 loses
playwright.config.ts wires 14 projects through dependencies into a strictly ordered stateful chain. Every project assumes the state the previous one left behind.
Playwright project dependency chain (14 projects)
graph TD Setup["Setup"] --> OH["<b>OpenHoursSetup</b><br/><i>load-bearing</i>"] OH --> Audit["Auditlog"] Audit --> VC["Videochat"] VC --> VCR["VideochatReplay"] VCR --> VCI["VideochatInspect"] VCR --> FE["FourEye"] VCI --> SSVC["SelfServiceVideochat"] FE --> SSVC SSVC --> Core["Core"] Core --> Cust["Customization"] Cust --> SSV2["SelfServiceV2"] SSV2 --> SSOP["SelfServiceOssPages"] SSV2 --> Arch["Archive"] SSOP --> ES["EmergencyShutdown"] Arch --> ES ES --> WL["WaitingList"] style OH fill:#3d2020,stroke:#c44,color:#fff style Setup fill:#264653,stroke:#2a9d8f,color:#fff
OpenHoursSetupis load-bearingIt runs
setOpenHours('00:00','24:00')across all seven days, and everything downstream chains off it. Without it the vuer_css customer flow never renders its callback button — tests fail in ways that look unrelated to opening hours.
Two ordering subtleties worth keeping straight:
- Within a single Playwright project (e.g.
Core), a failing test fails only itself — the rest ofCorestill runs. Only downstream projects get skipped. - In k6, scenarios with no
startTimeall start at t=0 and run concurrently. Theshared-iterationsexecutor defaults tomaxDuration: 10m. So a naive one-scenario-per-testall.tsdestroys the chain silently. The FKITDEV-9200 port restructuresall.tsinto a single sequential scenario withmaxDuration: '1h'instead.
The seeding blocker
Of the 45 Playwright tests under test/tests/e2e/, 30 seed their fixtures by booting the real Node app in-process. test/tests/support/helper.ts imports server/db/sequelize, server/db/models, UserService, FlowService, acl, calls sequelize.authenticate(), and exposes createCustomer, createRoom, createFlow, createFeedback, createSmsLog, createFlowProto and friends.
k6 runs its own JS VM — no Node, no require of server/**, no DB driver in the stock image. This is structural, not a porting detail.
Options considered (undecided — this is the gating decision for the remaining 30):
| Option | Trade-off |
|---|---|
(a) Node pre-seed step reusing helper.ts, handing k6 a fixtures JSON via open() | Leanest — stock image untouched, existing seeding code reused |
| (b) Test-only HTTP seed API in OSS | New auth surface in the product |
(c) xk6-sql custom k6 build | Abandons the pinned stock image |
| (d) Seed through the UI | Slow, fragile, circular for the tests that test that UI |
Operational warnings
The e2e suite is destructive
The Playwright e2e suite runs with
NODE_ENV=devand can erase the database. The k6 port inherits that property unchanged. Point it only at a throwaway environment — see dev-build-host for thefk-devVM.
k6.ymlpasses no browser argsIt sets only
CI_DOMAIN. It never passesK6_BROWSER_ARGS, so the docker path has no fake camera/mic and no--disable-web-security.compatibility-testandcallback-request’s lobby need those. The k6README.mddocuments the flags for native runs only. Open item on FKITDEV-9200.
Related
- FKITDEV-9200 — the migration ticket: inventory, delivered ports, open items
- playwright-to-k6-translation-recipe — how to port an individual test, and what cannot be ported
- vuer_oss · vuer_docker · vuer_css
- typescript-in-vuer-repos — why there is no typecheck gate to begin with
- nyc-cannot-load-typescript — the other broken coverage path in this repo
- dev-build-host — where to actually run this