test(deploy): opt-in display-device scenarios for the split smoke
Ready for review: Signage CI depends on it (Ekklesia_Signage #7 pins this PR's head commit f50e8f4). Merge with a merge commit, the repository default, and that pin stays valid on main. If this is squashed, Signage #7 needs a re-pin.
No product code changes. Off by default: platform CI never runs it, because several scenarios expect Signage.
starts a second headless Chromium, the "kiosk", whose --user-data-dir is a Docker volume, so it survives a browser restart as a kiosk profile does;
seeds three Signage slides;
pairs the kiosk through the real flow;
closes it cleanly, restarts it on the same profile;
then runs the scenarios in EKKLESIA_SMOKE_DISPLAY_SCENARIOS.
EKKLESIA_SMOKE_WATCH_MS and EKKLESIA_SMOKE_RECYCLE_WATCH_MS change how long the scenarios watch.
Scenario
Checks
two-pages
two pages on one credential: no offline state, no remount
connectivity-blip
an offline/online pair neither remounts nor shows offline
session-blip
one refused viewer-session request is recovered from without a reload
stream-failure
one refused realtime connection is re-established without a reload
caching-probe
storage-origin images reach Cache Storage
stream-recycle
stays live for the whole watch (across a realtime recycle when ≥ 5 min); live object URLs bounded
revoke
an open, revoked display returns to the pairing screen
Hang guards
Every DevTools command and page-side request has a deadline (10 s and 8 s), and each step has a budget.
An overrun prints the exact call or request that never answered, since a call that hangs the driver may be a request that hangs a real display.
timeout is the shell backstop.
The proxy's aborting with incomplete response lines are listed afterwards by UTC time and path only. The proxy log is captured, never printed raw.
Results: platform main + Signage with #4, #5 and #6 merged locally
pair, restart, two-pages, session-blip, stream-failure, stream-recycle (120 s, 3 live object URLs) and caching-probe: pass.
connectivity-blip: fails, as expected. The host's remount-on-online is platform work still to do.
revoke: the guard caught a real hang. After revocation, Runtime.evaluate on the revoked page got no answer within 10 s, so the page's main thread was blocked. Under investigation with the device-lifecycle work.
Commits
The harness. The CI-script redaction rule holds: compose logs are only ever captured.
Check wording that fits any watch length (module CI uses 120 s).
## test(deploy): opt-in display-device scenarios for the split smoke
**Ready for review: Signage CI depends on it** (Ekklesia_Signage #7 pins this PR's head commit `f50e8f4`). Merge with a merge commit, the repository default, and that pin stays valid on `main`. If this is squashed, Signage #7 needs a re-pin.
No product code changes. Off by default: platform CI never runs it, because several scenarios expect Signage.
### What it adds
`EKKLESIA_SMOKE_DISPLAY_DEVICE=1` (split topology only):
- starts a second headless Chromium, the "kiosk", whose `--user-data-dir` is a Docker volume, so it survives a browser restart as a kiosk profile does;
- seeds three Signage slides;
- pairs the kiosk through the real flow;
- closes it cleanly, restarts it on the same profile;
- then runs the scenarios in `EKKLESIA_SMOKE_DISPLAY_SCENARIOS`.
`EKKLESIA_SMOKE_WATCH_MS` and `EKKLESIA_SMOKE_RECYCLE_WATCH_MS` change how long the scenarios watch.
| Scenario | Checks |
|---|---|
| `two-pages` | two pages on one credential: no offline state, no remount |
| `connectivity-blip` | an offline/online pair neither remounts nor shows offline |
| `session-blip` | one refused viewer-session request is recovered from without a reload |
| `stream-failure` | one refused realtime connection is re-established without a reload |
| `caching-probe` | storage-origin images reach Cache Storage |
| `stream-recycle` | stays live for the whole watch (across a realtime recycle when ≥ 5 min); live object URLs bounded |
| `revoke` | an open, revoked display returns to the pairing screen |
### Hang guards
- Every DevTools command and page-side request has a deadline (10 s and 8 s), and each step has a budget.
- An overrun prints **the exact call or request that never answered**, since a call that hangs the driver may be a request that hangs a real display.
- `timeout` is the shell backstop.
- The proxy's `aborting with incomplete response` lines are listed afterwards by UTC time and path only. The proxy log is captured, never printed raw.
### Results: platform `main` + Signage with #4, #5 and #6 merged locally
- pair, restart, `two-pages`, `session-blip`, `stream-failure`, `stream-recycle` (120 s, 3 live object URLs) and `caching-probe`: **pass**.
- `connectivity-blip`: fails, as expected. The host's remount-on-online is platform work still to do.
- `revoke`: **the guard caught a real hang.** After revocation, `Runtime.evaluate` on the revoked page got no answer within 10 s, so the page's main thread was blocked. Under investigation with the device-lifecycle work.
### Commits
1. The harness. The CI-script redaction rule holds: compose logs are only ever captured.
2. Check wording that fits any watch length (module CI uses 120 s).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reproduction harness for what the first production Signage deployment
found. With EKKLESIA_SMOKE_DISPLAY_DEVICE=1, the split smoke starts a
second headless Chromium (the "kiosk") whose profile directory is a
Docker volume. It pairs that kiosk through the real flow, closes it
cleanly, restarts it on the same profile, and then runs injected-failure
scenarios: two pages on one credential, a connectivity blip, one refused
viewer-session request, one refused realtime connection, a cross-origin
image-caching probe, a full realtime recycle, and revocation.
Every DevTools command and page-side request has its own deadline, and
each step has a budget. A step that overruns prints the exact call it
was waiting for. The proxy's "aborting with incomplete response" lines
are listed afterwards by UTC time and path only.
Off by default: several scenarios expect Signage and fail on today's
v0.1.1, by design.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The recycle step's checks spoke of "the realtime recycle" even when
run with a watch shorter than the five-minute connection age, as module
CI does. They now say what they check: live for the whole watch (plus
"across a realtime recycle" when the watch is long enough), and never
remounted.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
ekklesia-bot
marked the pull request as ready for review 2026-10-06 00:18:08 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
test(deploy): opt-in display-device scenarios for the split smoke
Ready for review: Signage CI depends on it (Ekklesia_Signage #7 pins this PR's head commit
f50e8f4). Merge with a merge commit, the repository default, and that pin stays valid onmain. If this is squashed, Signage #7 needs a re-pin.No product code changes. Off by default: platform CI never runs it, because several scenarios expect Signage.
What it adds
EKKLESIA_SMOKE_DISPLAY_DEVICE=1(split topology only):--user-data-diris a Docker volume, so it survives a browser restart as a kiosk profile does;EKKLESIA_SMOKE_DISPLAY_SCENARIOS.EKKLESIA_SMOKE_WATCH_MSandEKKLESIA_SMOKE_RECYCLE_WATCH_MSchange how long the scenarios watch.two-pagesconnectivity-blipsession-blipstream-failurecaching-probestream-recyclerevokeHang guards
timeoutis the shell backstop.aborting with incomplete responselines are listed afterwards by UTC time and path only. The proxy log is captured, never printed raw.Results: platform
main+ Signage with #4, #5 and #6 merged locallytwo-pages,session-blip,stream-failure,stream-recycle(120 s, 3 live object URLs) andcaching-probe: pass.connectivity-blip: fails, as expected. The host's remount-on-online is platform work still to do.revoke: the guard caught a real hang. After revocation,Runtime.evaluateon the revoked page got no answer within 10 s, so the page's main thread was blocked. Under investigation with the device-lifecycle work.Commits
🤖 Generated with Claude Code