Skip to content

Add post-build tests for the main build targets (ESM and UMD) #8838

Description

@kpal81xd

Summary

We currently have no tests that exercise the built engine artifacts. The mocha
suite runs entirely against src/ (ESM), and CI only builds the bundles + runs
publint on them. This means regressions in the build output itself — UMD/ESM
wrapping, live bindings, export parity, minification — can ship undetected.

This was demonstrated by #8836: since 2.19.0, pc.app was permanently null in the
UMD / global build (playcanvas.js) because the UMD footer used
Object.assign(exports, pc), which snapshots each live getter to its load-time value.
The ESM build was unaffected (live bindings work natively). Fixed in #8837, but the
fix is unguarded — nothing prevents it from regressing again.

Verification of the gap

  • npm testmocha --recursive over test/**. ~91 test files import from src/;
    0 import from build/. The suite tests source, never the bundles.
  • .github/workflows/ci.yml jobs: build (npm run build + npm run publint),
    docs, lint, typescript-declarations, unit-test (npm test), build-examples.
    None loads a built bundle and asserts runtime behavior.
  • publint --level error validates packaging metadata (exports map, file presence,
    format) — it does not catch a frozen null pc.app.

Proposal

Add a lightweight post-build test harness that runs after npm run build and
loads the actual artifacts, asserting a small set of cross-target invariants.

Targets to cover

Format Artifact(s)
UMD build/playcanvas.js (+ .dbg.js, .prf.js, .min.js)
ESM build/playcanvas/src/index.js (+ .dbg/, .prf/)

Suggested checks

  • UMD loads two ways: as a browser global (window.pc via a jsdom/vm sandbox)
    and via CommonJS require().
  • Live-binding regression guard (the pc.app - is not available. Breaking projects. #8836 case): after constructing an AppBase,
    pc.app updates (i.e. pc.app is a live getter, not a frozen null).
  • Export parity: the set of named exports matches between the ESM and UMD builds.
  • Smoke test: import the ESM build, construct AppBase on a (jsdom) canvas, assert
    core public API is present and callable.
  • Minified build: playcanvas.min.js still exposes the expected public surface.

Wiring

Run as a new CI job (or an extra step in the existing build job) after npm run build,
so the artifacts under test are the ones we publish. The PR #8837 already demonstrated a
working manual approach (jsdom + vm sandbox) that can seed this harness.

Acceptance criteria

  • A test command (e.g. npm run test:build) that runs against build/ output.
  • Covers both UMD and ESM main targets.
  • Includes a regression test asserting pc.app live-binding in the UMD build.
  • Runs in CI after the build step.

Notes

Keep it intentionally small and fast — a handful of smoke/invariant checks on the
published artifacts, not a duplication of the full unit suite. Related: #8836, #8837, #8722.

Metadata

Metadata

Assignees

Labels

enhancementRequest for a new feature

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions