[core-fe] canvas: extractReplyText + deriveProvidersFromModels test coverage (FilesToolbar, NotAvailablePanel) #733

Closed
core-fe wants to merge 24 commits from test/settings-tab-coverage into main

24 Commits

Author SHA1 Message Date
b705d62fd1 test(chat): add extractAgentText coverage — 6 cases
Some checks failed
CI / Detect changes (pull_request) Successful in 35s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 38s
E2E API Smoke Test / detect-changes (pull_request) Successful in 49s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 18s
Harness Replays / detect-changes (pull_request) Successful in 35s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 48s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 24s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 38s
gate-check-v3 / gate-check (pull_request) Successful in 30s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 1m26s
qa-review / approved (pull_request) Failing after 17s
security-review / approved (pull_request) Failing after 15s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
CI / Platform (Go) (pull_request) Successful in 8s
sop-checklist-gate / gate (pull_request) Successful in 16s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m25s
sop-tier-check / tier-check (pull_request) Successful in 17s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 7s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m43s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 9s
Harness Replays / Harness Replays (pull_request) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 8s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 6s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 2m1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8m3s
CI / Canvas (Next.js) (pull_request) Successful in 11m29s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
audit-force-merge / audit (pull_request) Has been skipped
Covers the 4 unique branches not exercised by extractTextsFromParts:
artifacts[0].parts fallback, status.message.parts fallback, bare-string
passthrough, and the try/catch sentinel on null input.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 14:48:22 +00:00
b67269aee7 test(FilesTab): add useFilesApi coverage — 7 cases
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 18s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 20s
qa-review / approved (pull_request) Failing after 23s
security-review / approved (pull_request) Failing after 22s
gate-check-v3 / gate-check (pull_request) Successful in 35s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
sop-checklist-gate / gate (pull_request) Successful in 17s
sop-tier-check / tier-check (pull_request) Successful in 18s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m25s
Cherry-picked from test/settings-tab-coverage (commit 46086ef6).
Covers file entry walking and API interactions.

Total: 195 test files, 3047 tests passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 14:41:44 +00:00
ef4426e6b1 test: add components-pure + TestConnectionButton coverage
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 14s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 17s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
security-review / approved (pull_request) Failing after 17s
qa-review / approved (pull_request) Failing after 18s
sop-checklist-gate / gate (pull_request) Successful in 16s
sop-tier-check / tier-check (pull_request) Successful in 16s
gate-check-v3 / gate-check (pull_request) Successful in 25s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m18s
Cherry-picked from test/settings-tab-coverage (commit 226b7679).
- components-pure.test.ts: 184 lines, toMobileAgent + classifyForFilter
- TestConnectionButton.test.tsx: 245 lines, 29 test cases

Total: 194 test files, 3040 tests passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 14:26:17 +00:00
429111ec81 test(canvas): add TopBar + FileEditor + AttachmentLightbox coverage
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
qa-review / approved (pull_request) Failing after 5s
security-review / approved (pull_request) Failing after 5s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
sop-checklist-gate / gate (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request) Successful in 4s
sop-tier-check / tier-check (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
Cherry-picked from test/settings-tab-coverage (commit 36d93f21).
- canvas/TopBar.test.tsx: 97 lines, canvas header scaffold rendering
- FileEditor.test.tsx: 312 lines, file editor rendering + interactions
- AttachmentLightbox.test.tsx: 247 lines, image lightbox rendering

Total: 192 test files, 3006 tests passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 14:12:06 +00:00
886cc3f152 test(mobile): add MobileHome + MobileMe + MobileChat + MobileDetail coverage
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
qa-review / approved (pull_request) Failing after 5s
security-review / approved (pull_request) Failing after 6s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 55s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
sop-checklist-gate / gate (pull_request) Successful in 9s
sop-tier-check / tier-check (pull_request) Successful in 9s
gate-check-v3 / gate-check (pull_request) Successful in 11s
Cherry-picked from test/settings-tab-coverage (commit fd424dba).
- MobileHome.test.tsx: 245 lines, agent list + filter chips
- MobileMe.test.tsx: 212 lines, Me screen rendering
- MobileChat.test.tsx: 323 lines, chat thread + composer
- MobileDetail.test.tsx: 367 lines, agent detail view

Makes #727 a complete superset of all mobile screen test coverage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:55:59 +00:00
0a81621437 test(canvas): add SidePanel + TemplatePalette coverage
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
qa-review / approved (pull_request) Failing after 6s
security-review / approved (pull_request) Failing after 6s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 51s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
gate-check-v3 / gate-check (pull_request) Successful in 4s
sop-checklist-gate / gate (pull_request) Successful in 3s
sop-tier-check / tier-check (pull_request) Successful in 4s
Cherry-picked from test/settings-tab-coverage (PRs #708/#726).
- SidePanel.general.test.tsx: 390 lines
- TemplatePalette.test.tsx: 260 lines

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:32:55 +00:00
27c5bab2a3 test(settings): add AddKeyForm + OrgTokensTab + SecretRow + SecretsTab coverage
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
security-review / approved (pull_request) Failing after 6s
qa-review / approved (pull_request) Failing after 6s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
sop-checklist-gate / gate (pull_request) Successful in 3s
gate-check-v3 / gate-check (pull_request) Successful in 3s
sop-tier-check / tier-check (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 59s
Cherry-picked from test/settings-tab-coverage (PRs #708/#726).
- AddKeyForm: 340 lines, form validation + submission tests
- OrgTokensTab: 407 lines, org token CRUD + display tests
- SecretRow: 291 lines, secret display + reveal/copy/delete actions
- SecretsTab: 308 lines, secrets list + empty state + add form

Makes #704 a true superset of all settings test coverage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:29:32 +00:00
6d5ce30ff3 test(settings): add SettingsPanel coverage — 14 cases
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 13s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 13s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
qa-review / approved (pull_request) Failing after 16s
security-review / approved (pull_request) Failing after 14s
sop-checklist-gate / gate (pull_request) Successful in 14s
sop-tier-check / tier-check (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request) Successful in 18s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m9s
Covers: closed-by-default, open/close, tab navigation (Secrets/Tokens/Org API Keys),
unsaved guard integration (keep editing, discard), fetchSecrets on open,
aria-label accessibility.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:26:44 +00:00
c16e125617 test(canvas/tabs): add tree.test.ts — 29 cases for FilesTab getIcon + buildTree
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 11s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 17s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
qa-review / approved (pull_request) Failing after 19s
security-review / approved (pull_request) Failing after 19s
sop-tier-check / tier-check (pull_request) Successful in 18s
sop-checklist-gate / gate (pull_request) Successful in 20s
gate-check-v3 / gate-check (pull_request) Successful in 25s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m9s
Cherry-picked from test/settings-tab-coverage (PR #726).
Covers: getIcon extension matching (upper/lowercase, no-ext), buildTree
node-counting (file/folder/total), root-vs-nested classification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 12:55:06 +00:00
e831967ce8 fix(canvas/settings): UnsavedChangesGuard — add aria-description + fix overlay test assertion
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 35s
Harness Replays / detect-changes (pull_request) Successful in 24s
E2E API Smoke Test / detect-changes (pull_request) Successful in 41s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 39s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 41s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 20s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
qa-review / approved (pull_request) Failing after 18s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 36s
security-review / approved (pull_request) Failing after 18s
sop-checklist-gate / gate (pull_request) Successful in 16s
gate-check-v3 / gate-check (pull_request) Successful in 27s
sop-tier-check / tier-check (pull_request) Successful in 18s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m29s
CI / Platform (Go) (pull_request) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 9s
CI / Python Lint & Test (pull_request) Successful in 10s
Harness Replays / Harness Replays (pull_request) Successful in 7s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 10s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 8s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8m52s
CI / Canvas (Next.js) (pull_request) Successful in 18m20s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 4s
- Add AlertDialog.Description with sr-only text to satisfy Radix
  aria-describedby requirement (fixes Radix console warning).
- Add eslint-disable for Discard button (AlertDialog.Action wires
  keyboard events internally; no duplicate onKeyDown needed).
- Add explicit expect() assertion to overlay/ESC dismiss test (was
  missing — test always passed regardless of behavior).
- Remove unnecessary vi.resetModules() from afterEach.
- Rewrite overlay test to click Keep editing button (Cancel) to
  trigger onOpenChange(false) in jsdom, matching PR #708's pragmatic
  pattern for asChild composite components.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 09:23:56 +00:00
adc0643c37 test(canvas/mobile): add RemoteBadge + WorkspacePill render coverage (14 cases)
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 9s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
Harness Replays / detect-changes (pull_request) Successful in 17s
security-review / approved (pull_request) Failing after 12s
qa-review / approved (pull_request) Failing after 13s
sop-tier-check / tier-check (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 16s
sop-checklist-gate / gate (pull_request) Successful in 13s
CI / Detect changes (pull_request) Successful in 21s
E2E API Smoke Test / detect-changes (pull_request) Successful in 22s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 23s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 24s
gate-check-v3 / gate-check (pull_request) Successful in 21s
Harness Replays / Harness Replays (pull_request) Successful in 4s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 23s
CI / Platform (Go) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 5s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m5s
CI / Canvas (Next.js) (pull_request) Successful in 4m43s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 7m51s
Cover RemoteBadge and WorkspacePill — the last two rendering components in
components.tsx that were missing direct tests.

- RemoteBadge: ★ REMOTE badge rendering, span element, border-radius 4px,
  palette color/background application, dark/light difference
- WorkspacePill: brand text, count display, LIVE indicator, string count,
  border-radius pill shape, dark/light background variants

Total mobile test count now: 104 passing (was 90).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
20bf464261 fix(canvas/SearchDialog): split backdrop from dialog for WCAG 4.1.2 compliance
Restructure SearchDialog so the backdrop div is separate from the dialog
container. The outer div previously served as both backdrop and centering
wrapper, which made it impossible to add accessibility attributes
(aria-hidden="true") without hiding the dialog content from screen
readers.

New structure mirrors ConfirmDialog and KeyboardShortcutsDialog:
  - Backdrop: aria-hidden="true", cursor-pointer, click-to-dismiss
  - Dialog: role="dialog", aria-modal, aria-label, relative z-[71]

Also removes the now-unnecessary stopPropagation() on the dialog div.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
24bbfe6d69 fix(canvas): modal dialog guard on Esc/Enter/Cmd+[/]/Z shortcuts
Discovered during WCAG audit: useKeyboardShortcuts.ts had an
isModalOpen() guard for Arrow-key move/resize shortcuts but NOT for
Escape, Enter, Cmd+]/[, or Z. When a modal dialog (role="dialog",
aria-modal="true") is open, pressing Escape cleared the canvas
selection (because the canvas handler fired before the dialog's own
Escape handler), and Enter/Cmd+[/]/Z could interfere with dialog
interactions.

Fix: add isModalOpen() guard to all four shortcut groups, extracted
as a shared helper. Also added 4 new test cases covering the
modal-dialog guard for Esc, Enter, Cmd+[/], and Z.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
21700a1748 test(canvas/mobile): add primitives.test.tsx coverage (19 cases)
Cover StatusDot (size, circle, halo, flexShrink), TierChip (tiers,
size variants, flexShrink), Chip (value, label+value, pill shape,
soft/accent mode), SectionLabel (text, right slot, uppercase).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
908bc00309 feat(mobile): FilterChips + AgentCard WCAG 2.1 AA accessibility
FilterChips:
- Add role=toolbar + aria-label="Filter agents" on container
- Add role=radio + aria-checked on each button
- Add aria-hidden on count spans
- FilterChips.test.tsx: 9 cases

AgentCard:
- Add aria-label composing name, status, tier, remote flag
- AgentCard.test.tsx: 8 cases

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-12 08:49:50 +00:00
0e9bf2b60d feat(mobile): TabBar WCAG 2.1 AA accessibility — ARIA tab pattern + keyboard nav
- Adds role=tablist + aria-label to outer container
- Adds role=tab, aria-selected, aria-label, aria-hidden(icon) to each tab button
- tabIndex: active=0, others=-1 (standard tab pattern)
- Keyboard: Arrow keys cycle tabs, Home/End jump to first/last
- TabBar.test.tsx: 12 cases covering render states and keyboard interaction

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-12 08:49:50 +00:00
2075d282d4 test(canvas): add form-inputs coverage (35 cases) + Section accessibility fix
+ form-inputs.test.tsx: 35 cases across TextInput, NumberInput, Toggle,
  TagList, and Section — pure presentational components in the Config tab.
  Uses vi.hoisted() patterns from established suite; no jest-dom matchers.

+ form-inputs.tsx (Section): add aria-expanded + aria-controls to the
  collapsible toggle button for WCAG 2.1 AA compliance. The content div
  gets a stable id derived from the title; aria-controls links button to
  region. Indicator span gains aria-hidden="true" (decorative only).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
5f3e12d988 test(canvas/settings,chat): add coverage for EmptyState, SearchBar, UnsavedChangesGuard, AttachmentVideo
- EmptyState: 6 cases — icon aria-hidden, title, body text, CTA button
- SearchBar: 14 cases — store binding, onChange, Escape, Ctrl/Cmd+F focus
- UnsavedChangesGuard: 7 cases — dialog states, Keep/Discard actions, backdrop
  FIX: UnsavedChangesGuard now wires onDiscard via pendingDiscard ref so
  clicking Discard correctly calls the callback on dialog close
- AttachmentVideo: 8 cases — loading/ready/error states, tone borders,
  blob URL cleanup, external URI direct href

No breaking changes. 2387 tests passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
2f7910bf8a test(canvas/settings): add DeleteConfirmDialog + SettingsButton coverage (26 cases)
- DeleteConfirmDialog (15 cases): dialog open via secret:delete-request event,
  title/body text, Cancel closes, dependents loading/list/none states,
  deleteSecret call, confirm 1s delay, disabled→enabled button transition
- SettingsButton (11 cases): aria-label, aria-expanded, gear SVG aria-hidden,
  toggle openPanel/closePanel, active class, tooltip Mac/Ctrl shortcut
  ResizeObserver polyfill for Radix Tooltip

No breaking changes. 2413 tests passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
2e42e8c243 test(canvas/settings): add ServiceGroup coverage (10 cases)
- role=group with aria-label containing service label
- Service icon aria-hidden, correct emoji per service name
- Count label: "1 key" vs "N keys"
- Renders SecretRow for each secret
- Header and rows div structure

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
147cc77bab test(canvas/chat): add AttachmentImage coverage (10 cases)
Adds Vitest coverage for AttachmentImage — inline image thumbnail with
click-to-fullscreen lightbox. Covers: loading skeleton (240×180),
ready state with blob URL, tone=user/agent border classes, lightbox
open/close on click and Escape, AttachmentChip error fallback, img
onError transition to chip, external URI direct href (no fetch), and
blob URL cleanup on unmount.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
a593e73784 test(canvas/chat): add AttachmentAudio + AttachmentPDF coverage (18 cases)
Adds Vitest coverage for two missing attachment renderers:

AttachmentAudio (9 cases):
  - Loading skeleton (280x40) with aria-label
  - <audio controls> with blob src when ready
  - Filename label in ready state
  - tone=user -> blue/accent border
  - tone=agent -> neutral border
  - Error -> AttachmentChip fallback
  - audio onError -> chip transition
  - External URI -> direct href, no fetch
  - Blob URL cleanup on unmount

AttachmentPDF (9 cases):
  - Loading skeleton with PdfGlyph + filename
  - Preview button with glyph, filename, "PDF" label
  - Lightbox opens with <embed> on click
  - Lightbox closes on Escape
  - tone=user -> blue/accent classes on button
  - tone=agent -> neutral border
  - Error -> AttachmentChip fallback
  - External URI -> direct href, no fetch
  - Blob URL cleanup on unmount

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
bf02575f34 test(canvas/chat): add AttachmentTextPreview coverage (12 cases)
Adds Vitest coverage for AttachmentTextPreview — inline text/code
preview with streaming fetch and expand/truncate.

Covers:
  - Loading skeleton (320x80) with aria-label
  - Ready state with correct text content
  - Filename shown in header
  - Expand button appears when lines > 10
  - Expand button hidden when all lines shown
  - Expand button updates display to full content
  - Download button calls onDownload
  - tone=user -> blue/accent border
  - tone=agent -> neutral border
  - Truncated notice when file exceeds 256 KB
  - Error -> AttachmentChip fallback
  - Cleanup on unmount

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00
6adc1d8af6 test(settings): add TokensTab coverage (12 cases)
12 passing: loading spinner, empty state, token list rendering,
each token's prefix/age/Revoke button, API URL correctness, revoke
confirm + cancel dialogs, new-token creation + dismiss, create error,
network error banner.

Root bug fixed: confirm button search was unscoped — when the dialog
opened, two "Revoke" buttons existed (tok2's row + dialog confirm);
find() returned tok2's button first. Scoped the search to
document.querySelector('[role="dialog"]') to hit the correct target.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 08:49:50 +00:00