test(dashboard): browser smoke tests for agents CRUD UI (#117) #121
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!121
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/117"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
src/dashboard-browser.test.tswith 5 happy-dom smoke tests covering all AC from issue #117jsdom(incompatible with Bun's vm Proxy restriction) forhappy-domas the single DOM devDependencyGlobalWindow(not the plainWindowclass) — happy-dom'sWindowhas nowindow.evalin v18 so inline scripts are silently skipped;GlobalWindowinheritseval/SyntaxErrorfrom Bun's global scopeKey bridging pattern discovered
Three steps are required around
document.write()to make dashboard scripts work:globalThis.locationbeforedocument.writesoconst API_BASE = location.origininitialises (otherwise it hits TDZ and all fetches silently fail)globalThis.fetch/EventSourcebefore write so init calls use stubsglobalThis.document = win.documentafter write so dashboard functions resolvedocumentwhen called from outside the eval scopeTests covered
loadAgents()resolves+ New agentopens the create modalPOST /agentsTest plan
bun test src/dashboard-browser.test.ts→ 5 pass, 0 failbun run typecheck→ no errorsbun x biome check src/→ no errors🤖 Generated with Claude Code
Review — APPROVED ✅
CI is green (run #1685, 4 m, success). Round 1 full review.
Acceptance criteria
loadAgents()resolvesPOST /agentsAll five ACs are functionally covered. No logic bugs or security issues.
Nit — AC5: button
disabledstate not asserted (src/dashboard-browser.test.ts, test 5)The issue says "keeps the Delete button disabled". Test 5 verifies the error element appears and no DELETE request fires, but it calls
submitDelete()directly rather than clicking a (potentially disabled) submit button. It never asserts the button's.disabledDOM property. If the dashboard ever stopped disabling the button but kept the JS guard insidesubmitDelete, this test would still pass.Consider adding:
(adjust the id to match the actual submit button in
dashboard.html)Not a blocker — the functional "delete cannot fire with wrong name" invariant is verified.
Nit —
globalThisnot cleaned up (src/dashboard-browser.test.ts,makeWin)makeWin()assignsglobalThis.location,globalThis.EventSource,globalThis.fetch,globalThis.document, andglobalThis.windowbut never restores them. Bun runs each test file in an isolated worker and every test re-callsmakeWin()so there is no actual cross-test bug today. However, a future test in this file that skipsmakeWin()would inherit a staleglobalThis.documentpointing at an aborted window. AnafterEachthat deletes or restores these properties would guard against that drift.Also not a blocker.
Both nits are improvements for a follow-up; nothing here blocks merge.
bunx tsc --noEmitpasses on main #130claude-hooks-dev-defaultcontainer disappears silently #132bunx tsc --noEmitpasses on main #130