Port the harness fixes from test/e2e-new-features to main so the
Activation E2E workflow stops failing before any flow executes:
- Run everything through scripts/run-e2e-flows.sh as a single script
invocation: android-emulator-runner executes each 'script:' line in
its own shell, so the previous 'cd artifacts/screenshots' never
persisted and maestro failed with 'Flow path does not exist' on
every run (19/19 red since the workflow landed).
- adb reverse + 127.0.0.1 instead of 10.0.2.2 (unreliable headless),
emulator->mock reachability probe, logcat + maestro debug capture.
- Trim the flow list to the two flows that exist on main; the three
newer flows land with the test/e2e-new-features PR.
- continue-on-error until the suite's first green: the positive flow
still fails its final reply assertion (mode B in #90), and a
never-green suite should not block unrelated PRs or pollute the
product-intelligence failure metrics (#89).
Refs #90. Refs #89.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Review fixes (REQUEST_CHANGES round 1):
1. HIGH activation-negative-401.yaml: after dismissing the "Connection
Failed" alert the app stays on the Add-Connection modal
(handleQuickConnect's failure branch never calls router.back()), so the
old `text: "No Connection"` assertion (Sessions-tab empty state) could
never pass. Now asserts connect-submit-button is still visible instead.
2. MEDIUM mock-opencode-server.ts: prompt_async now parses the request
body, persists the USER's message, and broadcasts it (message.updated +
message.part.updated) BEFORE the canned assistant reply — matching real
server behavior. Without this, the app's handleEvent strips the
optimistic temp- user message when the assistant's message.updated
arrives and the sent message vanishes from the transcript.
activation-positive.yaml now also asserts chat-bubble-user and the
user's message text are visible after the reply lands, so that
regression class is actually covered.
3. MEDIUM activation-e2e.yml: timeout-minutes 15 -> 60. The job runs the
same npm install + prebuild + assembleRelease + emulator pipeline that
cua-smoke.yml budgets 60 min for (emulator-boot-timeout alone is 10 min).
4. MEDIUM activation-e2e.yml: replicated cua-smoke.yml's "Purge stale
generated sources" step — the Gradle cache key/restore-keys are shared
with that workflow, so the stale-autolinking-tree failure mode
(compileReleaseJavaWithJavac against the old package id) applies here too.
Verified locally: tsc --noEmit clean; npm test 81/81 pass; all three
touched YAML files parse valid; mock server exercised standalone —
full prompt cycle confirms GET /session/:id/message returns BOTH user
and assistant messages, SSE order is message.updated(user) ->
message.part.updated(user) -> busy -> message.updated(assistant) ->
message.part.updated(assistant) -> idle, user events carry the
sessionID/messageID fields handleEvent filters on, and --fail-auth
mode returns 401. Still no emulator run in this environment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJKAQ6HAikWGQK7PGZ5Y4E
Adds deterministic end-to-end coverage for first-open -> telemetry consent
-> server URL entry -> connect -> send first message -> receive reply,
targeting the 0%-7-day-retention investigation (GitHub issue #76).
- tests/fixtures/mock-opencode-server.ts: dependency-free HTTP+SSE stub
matching the REAL client protocol (src/lib/sdk.ts) — REST + a single
long-lived GET /global/event SSE stream, no WebSocket. Supports a
--fail-auth mode that 401s every request to exercise the connect-time
auth-failure class.
- .maestro/flows/activation-positive.yaml: consent -> quick connect ->
new session -> send message -> assert streamed reply renders, with a
screenshot at every step (positive-S1..S8).
- .maestro/flows/activation-negative-401.yaml: same setup against the
--fail-auth server, asserts Quick Connect's existing "Connection Failed"
alert is shown (not silently swallowed) and that the connection is not
saved. Flags in comments that Advanced-mode Save (handleAdvancedSave)
still has no testConnection() check and is a known, uncovered gap.
- testID props added (no restructuring) to the screens/components the
flows drive: TelemetryConsentModal, connection/add.tsx, tabs/index.tsx,
session/[id].tsx, MessageBubble.
- .github/workflows/activation-e2e.yml: new CI job — Android emulator via
reactivecircus/android-emulator-runner, builds the debug-signed APK,
starts both mock server instances, runs both Maestro flows, uploads
screenshots via actions/upload-artifact. Kept separate from the existing
vision-driven cua-smoke.yml, which needs a live server + LLM and isn't
suited to tight deterministic regression assertions.
- .gitignore: Maestro takeScreenshot output is never committed.
Verified locally: mock server exercised standalone via curl (health,
project/current, path, session create, SSE event ordering, message
persistence) in both normal and --fail-auth modes; both Maestro flow
files validated as well-formed YAML; tsc --noEmit clean on all changed
files. No lint script exists in this repo (N/A). Full emulator execution
was not run — no Android SDK/emulator available in this environment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJKAQ6HAikWGQK7PGZ5Y4E