Files
opencode-mobile/.maestro/flows/demo.yaml
Den 263ef9c4b6 test(demo): full-text regex matches so the demo E2E flow passes (#110)
* test(demo): use full-text regex matches in demo Maestro flow

The demo flow (added in #108, non-blocking lane) rendered correctly in CI
but failed its own assertions: it matched bare substrings ('login button',
'Tests passed') against Maestro's full-text regex matcher, which needs .*…*
to match a phrase inside a longer message. A CI run confirmed the demo
screen renders (S2 screenshot shows the user message, assistant reasoning,
and tool card) — only the assertions were wrong. Exact i18n labels
(Thinking / Permission Required / Allow) already matched. Flow-only; the
app and demo feature are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6

* test(demo): scroll to diff after expanding the tool card

CI got further with the regex fix but then failed asserting diff-view-scroll:
the confirmed cause (failure screenshot) is that the Edit card is scrolled to
the bottom of the viewport to be tapped, so its expanded diff opens below the
fold, and assertVisible does not auto-scroll. Add a scrollUntilVisible for
diff-view-scroll before the assert. Flow-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6

* test(demo): scroll to completion message before asserting it

Same below-the-fold pattern as the diff step: after approving the permission
at the bottom of the viewport, the 'Tests passed' completion renders further
down. Scroll to it before asserting. Preemptive, to avoid another CI cycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6

---------

Co-authored-by: engineer <engineer@macbookpro.lan>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 20:09:50 -07:00

117 lines
4.2 KiB
YAML

appId: cc.agentlabs.opencode
name: Demo mode - offline scripted walkthrough (no server, zero-server activation)
---
# Covers the "Try a demo" activation path added for the ~0% 7-day retention
# problem: an installer with no self-hosted `opencode serve` server used to
# hit a dead end at the no-connection empty state (see activation-positive.yaml
# / activation-negative-401.yaml for the "has a server" paths). This flow
# never starts a mock opencode server and never taps add-connection-button —
# app/demo.tsx (src/lib/demo-script.ts) is fully offline, hardcoded, local
# data rendered through the same chat components a real session uses.
#
# Verifies: the empty-state CTA exists and doesn't disturb the pre-existing
# add-connection-button (same testID, same position — activation-positive.yaml
# still taps it first), the demo screen renders a scripted conversation
# (reasoning -> tool call -> diff -> permission prompt) through the real
# MessageBubble/ToolCallCard/DiffView/PermissionPrompt components, the
# permission step responds locally (no network — there is no server to talk
# to), and the closing CTA actually routes to the real connect form
# (app/connection/add.tsx), not a fake/dead link.
- launchApp:
clearState: true
- assertVisible:
id: "telemetry-consent-card"
- tapOn:
id: "telemetry-decline-button"
- assertVisible:
text: "No Connection"
- takeScreenshot: demo-S1_empty_state
# add-connection-button must still be the first/only thing tapped here — this
# flow only ever taps it in this reachability check (visible, not tapped),
# to lock in that its position wasn't disturbed by the new button.
- assertVisible:
id: "add-connection-button"
- tapOn:
id: "try-demo-button"
- assertVisible:
id: "demo-screen"
- assertVisible:
id: "demo-banner"
- takeScreenshot: demo-S2_demo_screen_opened
# Scripted conversation renders through the real chat components.
# Maestro `text` matches the element's FULL text as a regex, so a phrase
# taken from a longer message must be wrapped in `.*…*` (the user message is
# a full sentence, not the bare phrase). Verified against a CI run where the
# demo screen rendered correctly but this bare-substring assert failed.
- assertVisible:
id: "chat-bubble-user"
- assertVisible:
text: ".*login button.*"
- assertVisible:
id: "chat-bubble-assistant"
- assertVisible:
text: "Thinking"
- takeScreenshot: demo-S3_conversation
# Tool call card is collapsed by default (same behavior as a real session) —
# tapping it expands the card, which renders the diff DOWNWARD below the
# header. Because the card is scrolled to near the bottom of the viewport to
# tap it, the expanded diff opens off-screen — so scroll again to bring the
# diff into view before asserting (assertVisible does not auto-scroll).
# Verified from a CI failure screenshot where the demo rendered correctly but
# diff-view-scroll sat below the fold.
- scrollUntilVisible:
element:
text: ".*Edit src/components/LoginButton.tsx.*"
direction: DOWN
timeout: 10000
- tapOn:
text: ".*Edit src/components/LoginButton.tsx.*"
- scrollUntilVisible:
element:
id: "diff-view-scroll"
direction: DOWN
timeout: 10000
- assertVisible:
id: "diff-view-scroll"
- takeScreenshot: demo-S4_diff_view
# Permission prompt (approve/permission step) — replying only updates local
# demo state, never a real sessionClient.permission.reply() network call.
- scrollUntilVisible:
element:
text: "Permission Required"
direction: DOWN
timeout: 10000
- takeScreenshot: demo-S5_permission_prompt
- tapOn:
text: "Allow"
# Approving swaps the prompt for a completion message that renders below the
# fold; scroll to it (full sentence begins "Tests passed — …", matched as a
# substring regex).
- scrollUntilVisible:
element:
text: ".*Tests passed.*"
direction: DOWN
timeout: 10000
- assertVisible:
text: ".*Tests passed.*"
- takeScreenshot: demo-S6_permission_approved
# Closing CTA routes to the REAL connect form, not a dead link.
- scrollUntilVisible:
element:
id: "demo-connect-button"
direction: DOWN
timeout: 10000
- takeScreenshot: demo-S7_cta
- tapOn:
id: "demo-connect-button"
- assertVisible:
id: "connect-ip-input"
- takeScreenshot: demo-S8_connect_form_reached