Bug: `extractAgentText({ parts: [] })` fell through all three source
checks (parts, artifacts, status.message) and returned the error
string `"(Could not extract response text)"` instead of `""`. Empty tasks
should render as blank bubbles, not error indicators.
Fix: check `typeof task === "string"` first, then walk all three
sources. Return `""` when every source is exhausted rather than
falling through to the catch/error string.
Added 11 dedicated tests for `extractAgentText` covering:
- Normal extraction from parts, artifacts, status.message
- Precedence (parts > artifacts > status.message)
- String fallback
- Empty parts/array/undefined fields returning ""
- Null/undefined status.message toleration
Also merged all fixes from fix/test-declarations (37 previously
failing vitest cases resolved).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move pure-function test cases for extractResponseText and
hasUnresolvedVarRef to their dedicated *_pure_test.go sibling
files. Keep integration/routing tests in the parent *_test.go.
Also add two missing assertions to workspace_crud validators test
(t.Log zeroing and conflict detection).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Key fixes:
- MissingKeysModal: add missing aria-hidden="true" to AllKeysModal
backdrop (ProviderPickerModal had it; AllKeysModal was missing it)
- MissingKeysModal.a11y: use class-based backdrop selector in jsdom
- ContextMenu: fix Tab key test to fire on menu element; offline nodes
use hasAttribute("disabled") instead of queryByRole().toBeNull()
- ConversationTraceModal: correct part-text expectation (joins all parts)
- Legend: fix palette-offset test to use document.querySelector on fixed
panel div, not .closest("div") which found inner text element
- OnboardingWizard: use RTL rerender for auto-advance (second render()
created a new component instance without shared state)
- PurchaseSuccessModal: mock history.replaceState to prevent SecurityError
in jsdom; replace setTimeout-promises with advanceTimersByTime
- Spinner: use getAttribute("class") instead of .className (SVGAnimatedString
in jsdom)
- TestConnectionButton: move Spinner outside <button> to fix accessible
name conflict; use hasAttribute("disabled"); fix error text assertion
- Tooltip: focus first focusable child inside trigger ref, not wrapper div
- TestConnectionButton component: restructure JSX — Spinner as sibling
- createMessage: conditional attachments spread (only include when non-empty)
- BundleDropZone: fix DragEvent in jsdom with createDragOverEvent helper
All 2257 canvas tests pass; npm run build succeeds.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>