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>
122 lines
3.9 KiB
YAML
122 lines
3.9 KiB
YAML
appId: cc.agentlabs.opencode
|
|
name: Directory picker - browse server folders and create a session in one
|
|
---
|
|
# New-feature regression coverage for DirectoryBrowserSheet
|
|
# (src/components/chat/DirectoryBrowserSheet.tsx): New Session -> Browse
|
|
# Folders -> the sheet lists the mock server's fake directory tree -> tapping
|
|
# a folder navigates into it -> Up navigation returns to the parent -> tapping
|
|
# "Use this folder" creates a session scoped to the chosen directory.
|
|
#
|
|
# The CI job starts `node tests/fixtures/mock-opencode-server.ts --port 4099`
|
|
# (normal mode, no --fail-auth / --seed-sessions) on the runner host BEFORE
|
|
# this flow runs. Its fake filesystem (FAKE_FILE_TREE in
|
|
# tests/fixtures/mock-opencode-server.ts) is:
|
|
# /mock/project -> frontend/ (dir), backend/ (dir), README.md (file)
|
|
# /mock/project/frontend -> (empty)
|
|
# /mock/project/backend -> (empty)
|
|
# and GET /project (FAKE_SERVER_PROJECTS) additionally lists a "docs-project"
|
|
# server-known project, exercised as a secondary assertion below.
|
|
|
|
- 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:4099"
|
|
- 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: dirpicker-S1_connected
|
|
|
|
# Open the New Session modal (long-press the FAB for the full options sheet)
|
|
- longPressOn:
|
|
id: "new-session-fab"
|
|
- assertVisible:
|
|
text: "New Session"
|
|
# GET /project surfaces "docs-project" under "Server Projects" (excludes the
|
|
# current project, mock-project) — confirms the project-list endpoint wired up.
|
|
# The modal fetches it async on open, so wait rather than assert immediately.
|
|
- extendedWaitUntil:
|
|
visible:
|
|
text: "docs-project"
|
|
timeout: 10000
|
|
- takeScreenshot: dirpicker-S2_new_session_modal
|
|
|
|
# Open the folder browser
|
|
- tapOn:
|
|
id: "browse-folders-button"
|
|
- assertVisible:
|
|
text: "Browse Folders"
|
|
# Diagnostic screenshot before the (previously flaky, see issue #104) wait
|
|
# below — if this ever regresses again, compare this frame against
|
|
# dirpicker-S2 to see whether the sheet actually opened.
|
|
- takeScreenshot: dirpicker-S2b_browser_sheet_opened
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "directory-row-frontend"
|
|
timeout: 10000
|
|
- assertVisible:
|
|
id: "directory-row-backend"
|
|
# README.md is a FILE, not a directory — DirectoryBrowserSheet filters entries
|
|
# to type === "directory", so it must never appear as a row.
|
|
- assertNotVisible:
|
|
text: "README.md"
|
|
- takeScreenshot: dirpicker-S3_root_listing
|
|
|
|
# Navigate into "frontend"
|
|
- tapOn:
|
|
id: "directory-row-frontend"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
text: "No subfolders here"
|
|
timeout: 10000
|
|
- takeScreenshot: dirpicker-S4_inside_frontend
|
|
|
|
# Up navigation must return to the root listing
|
|
- tapOn:
|
|
id: "directory-up-button"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "directory-row-frontend"
|
|
timeout: 10000
|
|
- assertVisible:
|
|
id: "directory-row-backend"
|
|
- takeScreenshot: dirpicker-S5_up_navigation_back_to_root
|
|
|
|
# Navigate into "backend" and select it
|
|
- tapOn:
|
|
id: "directory-row-backend"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
text: "No subfolders here"
|
|
timeout: 10000
|
|
- takeScreenshot: dirpicker-S6_inside_backend
|
|
- tapOn:
|
|
id: "directory-select-button"
|
|
|
|
# The app creates a session scoped to /mock/project/backend (mock POST
|
|
# /session reads x-opencode-directory) and navigates straight to it — the
|
|
# native header's directory badge must show "backend".
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "chat-message-input"
|
|
timeout: 15000
|
|
- assertVisible:
|
|
text: "backend"
|
|
- takeScreenshot: dirpicker-S7_session_created_in_backend
|