Files
suaveplan/openspec/archive/2026-05-02-testing-integration-build-fix/proposal.md
2026-05-27 23:29:53 +01:00

3.6 KiB

OpenSpec Change: testing-integration-build-fix

  • Change ID: testing-integration-build-fix
  • Package: @suaveplan/testing-integration (modify)
  • Status: PROPOSED
  • Date: 2026-04-28

Summary

Fix the Vite library build of @suaveplan/testing-integration so the globalSetup path returned by createIntegrationSetup() resolves to a real file instead of an inlined data:video/mp2t;base64,… URL. Currently the published artifact is unusable as a Vitest globalSetup target — the first downstream consumer (@suaveplan/storage-s3's integration test) had to bypass createIntegrationSetup and write a hand-rolled global-setup module.

Current state

  • packages/dev/testing-integration/src/internal/create-integration-setup-internal.ts:35 does new URL("../setup/global-setup.js", import.meta.url).pathname.
  • Vite library mode treats that pattern as an asset reference and inlines the source as a data: URL during vite build.
  • The compiled artifact at dist/internal/create-integration-setup-internal.js:5 literally contains new URL("data:video/mp2t;base64,LyoqCi…", import.meta.url).pathname, so globalSetup becomes an unparseable string — vitest crashes with ERR_LOAD_URL: Failed to load url …/storage-s3/video/mp2t;base64,….
  • Six downstream packages (testing-integration-redis, -postgres, -mailpit, -typesense, -surrealdb, -garage-s3, -step-ca) all rely on this entrypoint and would hit the same wall the moment they're consumed for real.

What changes

1. Build-config fix

Two viable approaches; pick whichever the testing-integration build owner prefers:

  • Option A (preferred): Mark src/setup/global-setup.ts as a multi-entry rollup lib.entry and replace the runtime resolution with a sibling-path that Vite does not intercept (e.g. path.join(fileURLToPath(import.meta.url), "..", "..", "setup", "global-setup.js")).
  • Option B: Switch the API — return only a symbolic name and have callers wire the globalSetup path themselves in vitest.config.ts. Less elegant but immune to bundler quirks.

2. Runtime parity check

Add a build-output assertion test under packages/dev/testing-integration/tests/dist-asserts.test.ts that loads dist/index.js, calls createIntegrationSetup({ x: stub }), and asserts existsSync(globalSetup) === true. This catches future regressions of the same shape.

3. Audit downstream consumers

Walk every testing-integration-* package and migrate any test that reaches for createIntegrationSetup to the corrected pattern. None today consumes it for real-container starts, so this is a no-op in practice but worth confirming as part of this change.

Impact

  • API change is either zero (Option A) or additive (Option B). No runtime behaviour change once fixed.
  • Unblocks @suaveplan/storage-s3 and any future package wanting Garage-backed integration tests using the standard factory instead of hand-rolled TestEnvironment plumbing.
  • Removes testing-integration from the project's "avoid the published API" list.

Out of scope

  • Bun-runtime compatibility for testcontainers (separate change: testing-integration-bun-runtime-compat).
  • Per-fixture dist/index.js emission for the seven testing-integration-* plugin packages — that is a distinct vite-config bug fixed by the separate change testing-integration-vite-entry-fix. The data-URL emission addressed here lives inside @suaveplan/testing-integration core; the entry-filename emission addressed there lives in each plugin package's own vite.config.ts.
  • Adding new fixtures or capabilities.
  • Changing TestEnvironment semantics.