feat(e2e): #2261 Gap1 live take-control e2e (acquire→WS upgrade→real frame) #2275
Reference in New Issue
Block a user
Delete Branch "feat/2261-gap1-takecontrol-e2e"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
#2261 Gap 1 — live take-control e2e (real-e2e gate). Closes the "broken display ships green" regression class.
New
canvas/e2e/staging-display.spec.tsexercises the REAL path (no RFB mock): acquire → assertsession_urlcarries the signed#token=→ open the noVNC WebSocket in-page with the production subprotocols → assert it UPGRADES (no pre-open 1006/403) → assert ≥1 binary framebuffer frame arrives. Each failure names the broken hop (edge→ws-proxy→EIC→websockify→x11vnc).Faithful handshake: the WS upgrade is gated by
isSameOriginCanvas(browser can't set Authorization on a WS), so the spec opens the socket viapage.evaluatefrom the tenant origin — the real production path. Acquire POST uses the per-tenant admin bearer.Why the old tests miss it:
staging-tabs.spec.tsTAB_IDS doesn't even includedisplay(only asserts no-crash);DisplayTab.test.tsxmocks RFB → no real WS.Fail-closed + loud-skip: gated on
STAGING_DISPLAY_WORKSPACE_ID; absent → skip with reason; present-but-broken → throw. Does NOT touch Gap 2 (reconciler, needs arch sign-off). NOT made a required context — activating as a real gate needs a standing desktop-capable staging workspace (cost item for CTO).The desktop take-control path (acquire → noVNC WS upgrade → ws-proxy → EIC → websockify → x11vnc → Xvfb) had NO real e2e. staging-tabs.spec.ts only opens the 13 declared panel tabs (TAB_IDS:24-38 omits `display`) and asserts they render — it never acquires control, the noVNC WS never upgrades, and no frame is asserted. DisplayTab.test.tsx mocks the RFB constructor, so no real WebSocket is opened there either. A broken display path ships green. This adds staging-display.spec.ts, which exercises the REAL wire path against a standing desktop-capable staging workspace: - POST .../display/control/acquire → asserts 200 + session_url with the signed token in its #token= fragment (the contract DisplayTab.tsx:459-466 depends on). - Opens the noVNC WebSocket from inside the page (so the browser sends the same-origin Origin header that AdminAuth's isSameOriginCanvas path requires — a browser WS can't set Authorization) with the exact subprotocols the canvas uses (DisplayTab.tsx:339): asserts it UPGRADES (onopen, no pre-open 1006/403 close). - Asserts at least one BINARY framebuffer message arrives (real frame off x11vnc, not a panel mount). No RFB mock. Fail-closed, no "flaky" escape hatch: each failure stage names the broken hop. Gated LOUD on STAGING_DISPLAY_WORKSPACE_ID; skips with a clear message when absent. staging-setup.ts gains a fully env-gated block (no-op unless STAGING_DISPLAY_SLUG is set) that resolves the standing desktop org's tenant URL / admin token / org id, and now always exports STAGING_ORG_ID. It provisions nothing — standing up one always-on desktop EC2 on staging is a CTO cost item to activate this gate as a required check. Does NOT touch the Gap 2 instance-state reconciler (needs CTO arch sign-off). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Reviewed: #2261 Gap1 live take-control e2e — real acquire→WS-upgrade→binary-frame path, faithful same-origin handshake, fail-closed skip. Required contexts green (E2E API Smoke path-filtered out, canvas-only). Approve.
REQUEST_CHANGES: direct Gitea verification does not support approval at head
e7968115ba.Source-of-truth combined CI is pending across 16 contexts at the current head. I cannot post a counting approval while the PR is red/pending, even with an existing CEO Assistant approval. Please re-request CR2 review after CI is success on the current head; I will re-run the normal 5-axis review then.
APPROVED after re-review using branch-protection required contexts rather than combined status.
Required-context check: present required context(s) are green at head e7968115ba7d; absent required contexts are path-filter absent for this PR. 5-axis review found no blocking issue.
Summary: Live display take-control E2E covers acquire, WebSocket upgrade, and real frame/banner path.
Correctness/robustness: change adds targeted regression coverage or fail-closed behavior for the reported bug class. Security: no new secret exposure or auth broadening found. Performance: no concerning runtime cost. Readability: comments/tests are explicit about the incident class and gate semantics.