Packaged consumer gate #
Run from the repository root with the supported mise tools installed:
mise exec -- node test/consumer/run.mjs
Install Chromium once with cd test/consumer && npm ci && npx playwright install chromium,
or set CHROMIUM_BIN to an installed browser. Node dependencies and the consumer's
Hex dependencies are pinned in lockfiles. CI runs the identical runner over
these two dependency profiles, each with both Nova and Vega:
| Profile | LiveView | Phoenix | Tailwind | Hex lockfile |
|---|---|---|---|---|
minimum |
1.2.9 | 1.8.9 | 4.2.3 | fixture/mix.minimum.lock |
locked |
1.2.11 | 1.8.9 | 4.2.3 | fixture/mix.lock |
minimum exercises the patched LiveView baseline and the documented Tailwind
minimum. It does not mean that every dependency is at its oldest
supported version. The remaining Hex versions are identical across profiles;
mix deps.get --check-locked rejects dependency resolution drift. The npm
lockfile is shared. To debug one profile, use
CONSUMER_PROFILES=minimum mise exec -- node test/consumer/run.mjs.
The package declares Elixir ~> 1.20, LiveView ~> 1.2 and >= 1.2.9, and
Phoenix ~> 1.8.9 in mix.exs.
Local mise pins Elixir 1.20.1 / OTP 29.0.2; the CI recipe uses Elixir 1.20.1 /
OTP 27. These are explicit gate configurations, not an exhaustive supported
Phoenix, LiveView, Elixir, or OTP matrix, nor a recommendation to deploy older
versions without reviewing their security advisories.
Both fixtures pin Bandit 1.12.5, Plug 1.19.5, and HPAX 1.0.4. These versions replace pins affected by the following published advisories; this is a tested dependency baseline, not a guarantee against future advisories:
- LiveView 1.2.9 fixes externally influenced redirect targets containing ASCII control characters (EEF-CVE-2026-64941).
- Phoenix 1.8.9 fixes unbounded channel joins and unsafe Presence keys (transport advisory, Presence advisory).
- Bandit 1.12.5 includes fixes for fragmented WebSocket CPU exhaustion, HTTP/2 flow-control starvation, and HTTP/2 header validation (65623, 74836, 75484).
- Plug 1.19.5 includes fixes for nested parameter decoding, cookie attribute injection, and multipart header limits (54892, 56813, 56814).
- HPAX 1.0.4 bounds HPACK integer decoding (EEF-CVE-2026-58226).
The runner builds a real Hex tarball without regenerating its registry, extracts its publishable payload into a temporary directory, and installs that package in four isolated Phoenix applications. For each profile and style it:
- Runs
shadix.initwithAcme.Designand a custom component directory, then adds every packaged registry entry using persisted configuration. - Repeats installation and checks that customized components, hooks, theme CSS, and configuration remain byte-for-byte intact.
- Compiles all copied modules with warnings as errors, extracts LiveView colocated CSS, builds it with Tailwind, and bundles all copied hooks.
- Opens the real generated app in Chromium and checks computed styling, utility overrides, and a dialog containing a select: change validation, server reset, submission, Escape dismissal, and focus return.
- Repeats that workflow in light/dark at 1280/320 CSS pixels, with 200% root
text sizing, and with forced-colors emulation at both widths: ten browser
scenarios per profile/style, forty total. Checks also cover labeled text
input, native checkbox/switch keyboard state, disabled controls and geometry.
The narrow viewport is a reflow equivalent, not native browser zoom. Known
forced-colors control-visibility findings remain in
docs/ACCESSIBILITY.md; these checks do not claim visual conformance.
Each run creates its own tmp/consumer-* directory, including dependency and
build outputs. A failed run retains its artifacts and prints their location;
successful runs clean up unless CONSUMER_KEEP_WORKSPACE=1 is set. The runner
does not require vendor/, the docs site, or repository stylesheet aggregators.
It needs registry/network access for package dependencies on a clean machine.