Skip to content

test(frontend): migrate suites to rstest - #2619

Open
malinskibeniamin wants to merge 11 commits into
masterfrom
ben-malinski/migrate-to-rstest
Open

test(frontend): migrate suites to rstest#2619
malinskibeniamin wants to merge 11 commits into
masterfrom
ben-malinski/migrate-to-rstest

Conversation

@malinskibeniamin

@malinskibeniamin malinskibeniamin commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Proven impact (pre-rebase benchmark snapshot)

Timing measurements below compare the exact pre-rebase commits named in the method. After rebasing onto origin/master@521b27c28, functional guardrails and coverage were rerun on Rstest 0.11.11; the local timing benchmarks were not rerun.

Workflow Vitest (d146e980) Rstest (2e6a2f14) Delta
Full unit suite 2.64s 1.65s -0.99s (-37.5%)
Full integration suite 97.81s 27.49s -70.32s (-71.9%)
Focused unit file 0.60s 0.43s -0.17s (-28.3%)
Focused integration file 12.81s 2.47s -10.34s (-80.7%)
Full merged coverage gate 117.18s 48.91s -68.27s (-58.3%)

Value proven: warm-cache feedback is materially faster across every affected test workflow, with median reductions of 28.3–80.7%. Every workflow clears the pre-registered 20% threshold, and Rstest was faster in all 25 measured pairs while the full suites ran four additional unit migration-policy tests (841 versus 837) and the restored 27-test integration license suite (1,283 versus 1,256).

Guardrail: all measured runs passed. After rebasing and upgrading to Rstest 0.11.11, all 847 unit, 1,286 integration, and 1 build-backed federation contract test pass, and the unchanged merged V8 coverage thresholds pass.

Federation capability proven: without the federation-aware Rstest project, the static rp_console/config import fails in the Module Federation runtime. With test:federation, Rstest builds Console's real ./config expose as a Node remote and imports it through @module-federation/rstest; 1/1 contract passes. This is deterministic correctness evidence, not a timing benchmark.

CI placement quantified: in the Rstest 0.11.11 GitHub run, the named federation step passed in 4s after the 5s unit step; the complete shared job took 23s. Keeping it as a separate step preserves failure visibility while avoiding a standalone job that would duplicate about 9s of job setup, checkout, Bun setup, and dependency installation. A separate job would not shorten this run's frontend critical path because the build job took 68s. Revisit that boundary when the suite expands beyond the current single built-remote contract.

Rstest 0.11.11 upstream patch impact

Upstream microbenchmark 0.11.10 0.11.11 Delta
20k result appends 312ms 0.3ms -311.7ms (-99.9%)
20k result updates 1,053ms 1.9ms -1,051.1ms (-99.8%)
300k queue operations 5,362ms 7.6ms -5,354.4ms (-99.9%)

Patch value: 0.11.11 replaces quadratic result copying/scans and FIFO shift() consumption with incremental indexes and cursor-based queues. It also routes federation chunks through require instead of a virtual filesystem, directly hardening this PR's federation test path. These are upstream isolated microbenchmarks, not Console suite timings; Console's full correctness and coverage guardrails were rerun separately.

Method: each workflow used three warm-up pairs, then five measured pairs in alternating order with stdout captured and dependency caches warm. Focused fixtures: src/utils/string.test.ts and src/config.test.tsx. Measured ranges: full unit 2.36–3.22s versus 1.60–1.82s; full integration 83.79–118.75s versus 25.22–40.58s; focused unit 0.53–0.62s versus 0.43–0.47s; focused integration 7.30–15.52s versus 2.27–5.21s; coverage 99.51–134.71s versus 43.99–57.94s. Excluded Vitest full-suite warm-ups hit the existing observability-page flake; Rstest warm-ups passed. Apple M5 Max, macOS 26.6.2, Bun 1.4.0, Node 26.7.0; base d146e98098a9eeff4906262a9579c05fcddbf48a, candidate 2e6a2f14362fc602138409755fc79ed41ee276cd. These are local warm-cache benchmarks, not CI-duration claims.

Not benchmarked: the new federation contract's timing because it proves runtime compatibility rather than performance; Playwright E2E is unchanged by this runner migration; watch mode needs a separate interactive rerun-latency harness.

Summary

  • migrate the unit and integration suites from Vitest to Rstest 0.11.11
  • preserve the Node/happy-dom split, 50% integration worker cap, V8 merged coverage, environment loading, aliases, YAML/raw imports, and harness cleanup
  • migrate mocks from vi to rs, using synchronous rs.requireActual for partial mocks that cross app module cycles
  • remove Vitest and test-only Vite configuration/dependencies, then add a policy test that prevents them from returning
  • add a dedicated build-backed test:federation suite that statically imports Console's real ./config remote through @module-federation/rstest, with a policy guard requiring frontend CI to run it

Why

This follows redpanda-data/cloudv2#29294, adapted for Console's unit, integration, and Module Federation contracts plus its existing V8 coverage pipeline. The proven full-suite, focused-file, and coverage-gate wall-time reductions justify the runner change; the 50% integration worker cap and existing 8 GB Node heap cap are preserved. The federation project closes the remaining runtime boundary by building the production-declared ./config expose before statically consuming it as a CommonJS remote.

Out of scope: no product UI behavior changed. Visual review was intentionally skipped because the .tsx changes are test-runner migrations only.

Commits

  • f4f45be5ctest(frontend): migrate suites to rstest
  • 4bae5380dfix(review): restore rstest suite discovery
  • dcffaa1ecfix(review): name migrated test imports
  • 3490a7c43fix(review): align rstest support files
  • 0aa53873ffix(review): scope legacy runner guard
  • f753ab883style(review): format migrated mocks
  • c7f3dddc7fix(review): strengthen restored license coverage
  • 2265531e3test(frontend): add rstest federation contract
  • 6c7bfd1a1ci(frontend): run rstest federation contract
  • df37c2efbtest(frontend): migrate rebased theme tests
  • 1bd5ac25dbuild(frontend): upgrade rstest to 0.11.11

Reviewer guide

  1. Start with rstest.config.unit.ts, rstest.config.integration.ts, and test.shared.ts.
  2. Review rstest.setup.ts for happy-dom and test-harness parity.
  3. Review rstest.config.federation.ts, rsbuild.config.federation-test.ts, tests/federation/rstest-global-setup.ts, and .github/workflows/frontend-verify.yml for the build-backed remote contract and CI wiring.
  4. Treat migrated test-file changes as mechanical API migration except for partial mocks converted to synchronous rs.requireActual to avoid Rspack evaluation cycles.
  5. Review dependency/config changes in package.json, lockfiles, and tests/rstest-migration.test.ts.

Dogfood evidence

  • Verdict: PASS
  • Entrypoint: the real test:unit, test:integration, test:federation, test:ci, test:file:*, and test:coverage package scripts
  • Actions and break attempts: exercised Node and happy-dom projects, restored the skipped license suite, repeated integration three times for scheduler stability, confirmed watch mode, checked migration policy, generated V8 reports, merged thresholds, verified the frozen lockfile install, reproduced both the federated import failure under the ordinary integration project and the missing CI invocation via a RED policy test, migrated the two upstream Registry V3 tests exposed by the post-rebase RED policy check, then built and consumed the real Console remote through the dedicated federation project
  • Observations: 847 unit, 1,286 integration, and 1 federation contract test pass after rebasing; the federation suite builds remoteEntry.cjs and returns the expected value from the exposed config API; merged coverage is 42.42% lines, 41.85% statements, 35.03% functions, and 35.73% branches
  • Repairs and replay: replaced cycle-sensitive static partial mocks with rs.requireActual, documented removal of the obsolete React 18 MessageChannel workaround, repaired the restored license-suite mocks, added a Node/CommonJS remote adapter after browser-hosted attempts exposed CORS/container mismatches, then replayed full CI, coverage, and federation suites
  • Limits: the federation contract covers the production-declared ./config expose, not browser rendering of ./App or ./BridgeApp; full dependency install scripts remain locally blocked by the existing isolated-vm native build on Node 26.7, so the frozen graph was verified with --ignore-scripts

Dependency upgrade path

  • Upgrade evidence: migrated runner APIs/config/setup/coverage and replayed the full suites plus merged coverage gate
  • Packages: add exact @rstest/core@0.11.11, @rstest/coverage-v8@0.11.11, and @module-federation/rstest@2.9.0; remove Vitest, its UI/coverage packages, and four test-only Vite plugins
  • SemVer confidence: exact-pinned dev tooling with compatible @rsbuild/core@2.0.11 and @rstest/core@0.11.11 peers; no production runtime bundle dependency added
  • Risk gate: 0.11.11 was published August 31 and remained inside the repository's 72-hour supply-chain delay; the one-time override followed verification of the official GitHub release, registry integrity/signatures, and npm provenance
  • Security notes: bun audit reports 49 transitive advisories; the new test-only Module Federation tree adds a path to the already-present fast-uri advisory, while its adm-zip@0.6.0 and undici@7.29.0 versions are outside their flagged ranges; private Buf packages were skipped because their audit endpoint returned 404

Test plan

  • bun install --ignore-scripts --frozen-lockfile
  • bun run lint
  • bun run type:check
  • bun run test:ci (847 unit + 1,286 integration + 1 federation contract)
  • bun run test:federation -- --bail=1
  • GitHub frontend-verify / test-unit (Run Module Federation tests step)
  • bun run test:coverage
  • bun audit

@malinskibeniamin malinskibeniamin self-assigned this Aug 27, 2026
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Clean — no registry drift, off-token colours, or ad-hoc classes

App: frontend · Scope: diff vs origin/master · Files: 186

Count
⚠️ Outdated registry components 0
🛠 Locally-modified components 0
❓ Unknown to registry 0
🎨 Off-token palette colours 0
🔢 Ad-hoc utility classes 0

Generated by lookout audit-changes.

@malinskibeniamin malinskibeniamin left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated /review: 8 finding(s).

Comment thread frontend/rstest.config.integration.ts
Comment thread frontend/package.json
Comment thread frontend/src/components/misc/kowl-json-view.test.tsx Outdated
Comment thread frontend/tests/css-loader-register.mjs
Comment thread frontend/rstest.setup.ts
Comment thread frontend/tests/rstest-migration.test.ts
Comment thread frontend/biome.jsonc Outdated
Comment thread frontend/package.json
@malinskibeniamin

Copy link
Copy Markdown
Contributor Author

Review feedback addressed

  • Restored the skipped 27-test license suite, repaired its mocks, and strengthened its route assertions.
  • Migrated stale frontend testing guidance to Rstest and removed the obsolete test:ui instruction.
  • Replaced generated rstestImported* aliases with direct/named imports.
  • Deleted the orphaned CSS loader and aligned Biome overrides across both Rstest setup files.
  • Documented removal of the obsolete React 18 MessageChannel workaround; three repeated integration runs passed.
  • Scoped the legacy-runner policy to test/spec and setup files.
  • Confirmed rstest --watch is supported and enters multi-project watch mode.

All review threads resolved. CI is green.

@malinskibeniamin
malinskibeniamin requested review from a team, SpicyPete, datamali, eblairmckee and yougotashovel and removed request for a team August 28, 2026 08:10
@malinskibeniamin
malinskibeniamin marked this pull request as ready for review August 28, 2026 08:10
@malinskibeniamin
malinskibeniamin force-pushed the ben-malinski/migrate-to-rstest branch from 05c63b3 to df37c2e Compare August 30, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant