Visual regression tests for the moonbase_licensing activation UI. They render
the ActivationComponent in every state to PNGs offscreen (no window, no
network) and upload them to Argos for diffing against a
baseline.
snapshot_main.cpp is a small JUCE console app that, for each
state, constructs an ActivationComponent and uses two module seams to make the
frame deterministic:
ActivationConfig::reduceMotion— transitions/spinner/pop jump straight to their final frame (also a real accessibility option).ActivationController::setPreviewState(screen, license, error)— forces any screen with a synthetic license, no network, no stored state.
It then captures juce::Component::createComponentSnapshot(...) at 2× and writes a
PNG per state:
| File | State |
|---|---|
01-welcome |
Not activated — online / offline |
01b-welcome-error |
Activation request failed (error message) |
02-activating |
Browser activation in progress (spinner + device chip) |
03-success |
Just activated (license card) |
04-offline-empty |
Offline flow, nothing chosen yet |
05-offline-ready |
Offline flow with a response file selected |
05b-offline-error |
Offline flow with an invalid response file (error) |
06-trial |
Valid trial license (days-left, progress, features) |
06b-trial-expired |
Trial that has ended (locked) |
06c-trial-overflow |
Trial with a long feature list (scrollable field) |
07-details |
Valid perpetual license (details, seats, deactivate) |
07b-details-subscription |
Subscription license with an expiry date |
07c-details-error |
Details with a deactivate failure (error) |
07d-details-update-available |
Details with a clickable "Update available" badge |
08-details-offline |
Offline-activated (permanent) license |
09-details-deactivating |
Deactivate in progress (inline spinner) |
10-update-loading |
Update available, fetching release notes (skeleton) |
11-update-ready |
Update available, notes loaded (download button) |
12-update-downloading |
Update installer downloading (progress bar) |
13-update-error |
Update details failed to load (error) |
14-update-gated |
Update the license can't download (Unlock CTA) |
15-theme-ember-welcome |
Welcome, "Ember" theme (warm near-black, amber, monospaced) |
16-theme-ember-activating |
Browser activation, Ember (spinner arc + track) |
17-theme-ember-trial |
Trial, Ember (pill, progress gradient, feature list) |
18-theme-daylight-success |
Just activated, "Daylight" theme (light) |
19-theme-daylight-details |
License details, Daylight (cards, seat pips) |
20-theme-daylight-offline |
Offline flow, Daylight (drop zone, links) |
21-theme-forest-expired |
Trial ended, "Understory" theme (deep green, danger tokens) |
22-theme-forest-update |
Update ready, Understory (notes card + scrollbar) |
Add a state by adding a writeSnapshot(...) call.
15 onwards render the same UI through config.palette + config.fonts, the
module's re-skin seam. They are the regression net for the colour tokens: a
colour still hardcoded in ActivationComponent.cpp shows up here as stock
blue-grey chrome, a cyan glow or a white wash on a panel that has none. The
three themes (emberTheme(), daylightTheme(), forestTheme() in
snapshot_main.cpp) are deliberately unalike, and between them the eight screens
touch every token in ActivationPalette.
Ember also exercises the typeface seam. It routes all three font roles through
fonts.makeFont to the platform's monospaced face rather than bundling a
typeface, so the render stays reproducible on any machine.
./scripts/visual-snapshots.sh # build + render into ./ui-snapshots
./scripts/visual-snapshots.sh --upload # …then upload to Argos (needs ARGOS_TOKEN)On this repo's reference Mac the host toolchain needs an older SDK; pass it through:
MOONBASE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk \
./scripts/visual-snapshots.sh.github/workflows/visual.yml builds + renders
on macOS (which also exercises the Apple crypto backend), stores the PNGs as a build
artifact, and uploads to Argos when the ARGOS_TOKEN repository secret is set.
To enable Argos: create a project at argos-ci.com, connect this repository, and add
its token as the ARGOS_TOKEN Actions secret. Argos records the first run as the
baseline and flags pixel diffs on later runs for approval.