Files
opencode-mobile/.maestro/flows/diff-scroll.yaml
Den 2285f80e81 fix(e2e): harden activation-e2e newer flows (issue #104) (#105)
Root-caused directory-picker's directory-row-frontend failure: all four
in-app @gorhom/bottom-sheet sheets (DirectoryBrowserSheet, DirectorySwitcher,
ModelPicker, VariantPicker) provide static percentage snapPoints but rely on
v5's enableDynamicSizing default (true), which never resolves without content
wrapped in a size-reporting component — so useAnimatedDetents() permanently
early-exits and the sheets can never actually open. Set
enableDynamicSizing={false} on all four (they already have explicit
snapPoints, so dynamic sizing was never needed).

variant-picker's chip failure was a stale test assumption: src/lib/
model-selection.ts's chooseModelSelection() deliberately returns null for a
fresh session (issue #37/#35 — the provider registry default is unreliable),
so a brand-new session has no model selected and the reasoning-effort chip
has nothing to key off of. Added testIDs (model-chip, model-option-*) and
updated the flow to explicitly pick a model first, matching real usage.

diff-scroll's missing markdown text: switched src/components/markdown/
Markdown.tsx from react-native-marked's FlatList-based default export to its
useMarkdown() hook rendered into a plain View. The chat screen already nests
this inside its own *inverted* FlatList (one row per message) — a nested
VirtualizedList inside an inverted outer list is a known RN footgun where the
inner content can render at zero height instead of just warning. We already
forced scrollEnabled:false + a large initialNumToRender, defeating
virtualization anyway, so rendering the parsed blocks directly loses nothing.
Extended the existing react-native-marked .d.ts shim (added for a React
18/19 ReactNode mismatch) to also declare useMarkdown/useMarkdownHookOptions.

Added diagnostic screenshots to directory-picker.yaml and diff-scroll.yaml
at the previously-failing steps for faster triage if these regress again.

Closes #104.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 15:41:28 -07:00

129 lines
5.1 KiB
YAML

appId: cc.agentlabs.opencode
name: "DiffView + CodeBlock horizontal scroll - wide diff/code line reachable by swipe (closes #21)"
---
# GitHub issue #21 ("QA: verify DiffView + CodeBlock horizontal-scroll
# on-device with a populated diff"). Two rendering fixes shipped earlier were
# code-audited but never verified with real, wide content on a real
# (emulated) device:
# - src/components/chat/DiffView.tsx: diff lines render inside a horizontal
# ScrollView (previously truncated with numberOfLines={1}).
# - src/components/markdown/CodeBlock.tsx: code renders inside a horizontal
# ScrollView (previously long lines wrapped/mangled).
#
# The CI job starts `node tests/fixtures/mock-opencode-server.ts --port 4100
# --seed-diff` on the runner host BEFORE this flow runs. --seed-diff
# pre-populates ONE session (id "seed-diff", directory /mock/project — the
# default connection's directory) whose single assistant message already
# contains:
# - a completed `edit` tool part with a wide "add" diff line (renders via
# ToolCallCard -> EditDetail -> DiffView once the card is expanded)
# - a text part with a wide fenced code block (renders via Markdown ->
# CodeBlock)
# Both wide lines are ~220 filler characters (no spaces, so they can't
# word-wrap) followed by a distinct marker token. This is loaded via GET
# /session/seed-diff/message when the session is opened (selectSession),
# NOT delivered over SSE — issue #90 (a separate SSE-render bug) is being
# fixed independently, and this flow must not depend on it landing first.
#
# Caveat for whoever debugs a flake here: assertVisible/assertNotVisible on
# a substring deep inside ONE very wide, unwrapped Text node is coarser than
# it looks — Maestro (like most accessibility-tree-based mobile test
# frameworks) determines visibility per ELEMENT, not per glyph, and there are
# open Maestro issues about partially-visible elements being reported as
# fully visible (mobile-dev-inc/maestro #1275, #2411). The filler is made
# very wide (~220 chars, comfortably wider than any emulator screen at this
# monospace font size) specifically to keep the marker's actual rendered
# position off past the right edge at rest. Screenshots are taken at every
# step so a flake here can be diagnosed visually, not just from the
# assertion's pass/fail.
- launchApp:
clearState: true
- assertVisible:
id: "telemetry-consent-card"
- tapOn:
id: "telemetry-decline-button"
- assertVisible:
text: "No Connection"
- tapOn:
id: "add-connection-button"
- tapOn:
id: "connect-ip-input"
- inputText: "127.0.0.1:4100"
- hideKeyboard
- tapOn:
id: "connect-submit-button"
# 40s margin: see activation-positive.yaml — the connect handshake's own
# fetches are individually capped at 30s (src/lib/sdk.ts REQUEST_TIMEOUT_MS).
- extendedWaitUntil:
visible:
id: "connection-status-dot"
timeout: 40000
- takeScreenshot: diffscroll-S1_connected
# The seeded session must appear on the home tab's own-directory list (no
# SSE, no roots=true — this is the plain GET /session directory-scoped path).
- extendedWaitUntil:
visible:
text: "Wide Diff Session"
timeout: 15000
- tapOn:
id: "session-item-seed-diff"
- extendedWaitUntil:
visible:
id: "chat-message-input"
timeout: 15000
# History loaded via GET /session/seed-diff/message (not SSE) must already
# render both the tool card and the markdown code block.
- assertVisible:
text: "Edit wide_diff_target.ts"
# Diagnostic screenshot (issue #104): the tool-card title above renders via
# plain Text, while the paragraph below renders via react-native-marked's
# nested FlatList inside this screen's own *inverted* FlatList. If this ever
# regresses again, check whether this frame shows blank space between the
# message header and the tool card (nested-FlatList-in-inverted-list content
# not laying out) vs. genuinely missing/incorrect text.
- takeScreenshot: diffscroll-S1b_before_markdown_text_check
- extendedWaitUntil:
visible:
text: "Here is a wide code sample"
timeout: 20000
- takeScreenshot: diffscroll-S2_history_loaded
# --- CodeBlock: the wide fenced code block is already expanded (no tap
# needed — Markdown renders it immediately, unlike the collapsible tool card).
- assertVisible:
id: "code-block-scroll"
- assertNotVisible:
text: "ZZZ_CODE_SCROLL_TARGET_ZZZ"
- takeScreenshot: diffscroll-S3_codeblock_marker_offscreen
- swipe:
from:
id: "code-block-scroll"
direction: LEFT
- assertVisible:
text: "ZZZ_CODE_SCROLL_TARGET_ZZZ"
- takeScreenshot: diffscroll-S4_codeblock_marker_revealed
# --- DiffView: lives inside the collapsible tool card's detail section, so
# expand it first.
- tapOn:
text: "Edit wide_diff_target.ts"
- assertVisible:
text: "src/wide_diff_target.ts"
- assertVisible:
id: "diff-view-scroll"
- assertNotVisible:
text: "ZZZ_DIFF_SCROLL_TARGET_ZZZ"
- takeScreenshot: diffscroll-S5_diffview_marker_offscreen
- swipe:
from:
id: "diff-view-scroll"
direction: LEFT
- assertVisible:
text: "ZZZ_DIFF_SCROLL_TARGET_ZZZ"
- takeScreenshot: diffscroll-S6_diffview_marker_revealed