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 run tsc -p test/tests/k6/tsconfig.json yourself.

Harness anatomy

RepoCommitWhat it contributes
vuer_docker8ae9f0c (PR #223)k6.yml, .env:CI_DOMAIN, README ## E2E Testing
vuer_oss0e63bcd166 (PR #8085) — tip of origin/develtest/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 file

The 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.json is a separate tsconfig (types:["k6"], strict, allowImportingTsExtensions, noEmit). The root tsconfig does not include test/.
  • yarn lint ignores test/*.
  • There is no typecheck npm 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.json

Ordering: 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.

OpenHoursSetup is load-bearing

It 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 of Core still runs. Only downstream projects get skipped.
  • In k6, scenarios with no startTime all start at t=0 and run concurrently. The shared-iterations executor defaults to maxDuration: 10m. So a naive one-scenario-per-test all.ts destroys the chain silently. The FKITDEV-9200 port restructures all.ts into a single sequential scenario with maxDuration: '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):

OptionTrade-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 OSSNew auth surface in the product
(c) xk6-sql custom k6 buildAbandons the pinned stock image
(d) Seed through the UISlow, fragile, circular for the tests that test that UI

Operational warnings

The e2e suite is destructive

The Playwright e2e suite runs with NODE_ENV=dev and can erase the database. The k6 port inherits that property unchanged. Point it only at a throwaway environment — see dev-build-host for the fk-dev VM.

k6.yml passes no browser args

It sets only CI_DOMAIN. It never passes K6_BROWSER_ARGS, so the docker path has no fake camera/mic and no --disable-web-security. compatibility-test and callback-request’s lobby need those. The k6 README.md documents the flags for native runs only. Open item on FKITDEV-9200.