Appearance
Testing rollout next steps implementation plan
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Finish the remaining high-value SDK test coverage work from the current worktree state, then harden the test system with enforceable coverage and verification gates.
Architecture: Keep the existing Vitest and layered PIXI mock foundation, then expand coverage in ROI order: missing manager logic, missing component logic, browser-specific utilities, and finally coverage ratcheting and CI readiness. Prefer small test files that mirror one source module or one focused behavior area.
Tech Stack: TypeScript, Vitest 4, V8 coverage, PIXI.js 8 mocks, Valtio, ESLint, Vite.
Current state summary
This plan starts from the actual repository state on March 10, 2026, not from the earlier design baseline.
- Test infrastructure is already present in
vitest.config.ts,test/setup.ts,test/mocks/*, andtest/factories/*. - The worktree already has 25 test files and 650 passing tests.
AppService,Interaction,MapApplication,PathManager,ControlsManager,Robot,ChargingStation, and utility algorithms already have meaningful test coverage.- The largest remaining gaps are
MapManager,RoomManager, many untested components,browser.ts, and hardening tasks such as non-zero coverage thresholds.
Constraints and execution rules
This plan follows the current repository rules and the current worktree state.
- Preserve existing user changes in the dirty worktree.
- Keep tests in
test/mirroringsrc/core/paths. - Prefer splitting oversized test files by behavior area when it improves maintainability.
- After each implementation slice, run
npm test,npx tsc --noEmit, andnpm run lint. - Before claiming hardening is complete, also run
npm run test:coverage. - Do not introduce browser or E2E frameworks in this plan.
Task 1: Stabilize the in-progress test file split
This task closes the current dirty-worktree refactor before adding more surface area.
Files:
- Modify:
test/core/application/Interaction.test.ts - Modify:
test/core/components/Robot.test.ts - Modify:
test/core/managers/PathManager.test.ts - Modify:
test/core/utils/algorithm-geometry.test.ts - Modify:
test/core/utils/algorithm-outline.test.ts - Modify:
test/core/utils/algorithm-room.test.ts - Modify:
test/core/utils/algorithm-vector.test.ts - Delete:
test/core/utils/index.test.ts - Create:
test/core/application/Interaction-pointer.test.ts - Create:
test/core/application/Interaction-gesture.test.ts - Create:
test/core/application/Interaction-panzoom.test.ts - Create:
test/core/application/Interaction-detect.test.ts - Create:
test/core/application/interaction-test-setup.ts - Create:
test/core/components/Robot-draw.test.ts - Create:
test/core/components/Robot-movement.test.ts - Create:
test/core/managers/PathManager-draw.test.ts - Create:
test/core/managers/PathManager-operations.test.ts - Create:
test/core/utils/utils-easing.test.ts - Create:
test/core/utils/utils-precision.test.ts - Create:
test/core/utils/utils-room.test.ts
Step 1: Review the split for duplication and ownership
Check that each new file owns one behavior cluster and that no assertions are duplicated across old and new files.
Step 2: Keep helper setup local and reusable
Move repeated Interaction setup into test/core/application/interaction-test-setup.ts only when it reduces noise.
Step 3: Remove the obsolete aggregate utility test file
Finish the migration away from test/core/utils/index.test.ts after its coverage has been preserved by the new focused utility test files.
Step 4: Run verification
Run:
bash
npm test
npx tsc --noEmit
npm run lintExpected: all commands pass with no regression from the split.
Task 2: Add missing manager coverage for RoomManager
This task fills one of the two explicit manager gaps from the original phase plan.
Files:
- Modify:
src/core/managers/RoomManager.ts - Create:
test/core/managers/RoomManager.test.ts
Step 1: Write failing tests for subscription-driven visibility behavior
Cover runtime reactions such as room visibility toggles, label visibility, and cleanup of subscriptions in destroy().
Step 2: Write failing tests for room data synchronization
Cover room collection updates, state-driven redraw decisions, and basic idempotency when repeated room updates arrive.
Step 3: Reuse existing factories and PIXI mocks
Build test fixtures from test/factories/map-data.ts, test/factories/config.ts, and test/factories/runtime.ts before creating new helpers.
Step 4: Implement only minimal test-support changes
If testability gaps exist, keep production edits small and avoid behavior changes beyond exposing stable seams.
Step 5: Run verification
Run:
bash
npm test -- RoomManager
npm test
npx tsc --noEmit
npm run lintExpected: new RoomManager tests pass, and the full suite still passes.
Task 3: Add missing manager coverage for MapManager
This is the largest remaining high-value gap and the best next ROI item after RoomManager.
Files:
- Modify:
src/core/managers/MapManager.ts - Create:
test/core/managers/MapManager.test.ts
Step 1: Identify a narrow first slice
Start with room detection flow, raster versus structured handling, and caching decisions. Do not try to cover every branch in the first pass.
Step 2: Mock robot-protocol decode boundaries deliberately
Use test/mocks/robot-protocol.ts and fixture builders so tests focus on manager orchestration rather than protocol internals.
Step 3: Add tests for cache reuse and redraw triggers
Cover cases where identical inputs skip unnecessary work and changed inputs cause the expected processing path.
Step 4: Add tests for structured versus raster dispatch
Verify that MapManager selects the correct pipeline and populates downstream data consistently.
Step 5: Run verification
Run:
bash
npm test -- MapManager
npm test
npx tsc --noEmit
npm run lintExpected: the first focused MapManager slice lands without destabilizing the existing suite.
Task 4: Expand component coverage by priority
This task broadens Phase 4, but only for components with meaningful state or geometry logic.
Files:
- Create:
test/core/components/Path.test.ts - Create:
test/core/components/RoomInfo.test.ts - Create:
test/core/components/RoomLabel.test.ts - Create:
test/core/components/VirtualWall.test.ts - Create:
test/core/components/Carpet.test.ts - Optional create: additional focused component test files that map to the selected source modules
Step 1: Prioritize data-rich components
Implement coverage in this order: Path first, then room presentation components, then interactive control visuals.
Step 2: Test construction, updates, and destroy cleanup
Focus on input-to-render-state behavior, not PIXI internals.
Step 3: Avoid broad snapshot-style assertions
Use direct assertions on points, visibility, labels, transforms, and child management so failures stay easy to diagnose.
Step 4: Run verification
Run:
bash
npm test
npx tsc --noEmit
npm run lintExpected: component coverage grows without requiring heavier PIXI mocks.
Task 5: Add browser utility coverage
This task closes the small but explicit browser-specific risk called out in the design record.
Files:
- Create:
test/core/utils/browser.test.ts - Modify:
src/core/utils/browser.tsonly if a small test seam is required
Step 1: Stub navigator inputs explicitly
Cover userAgent and deviceMemory branches with vi.stubGlobal() based tests.
Step 2: Verify environment assumptions
Make sure tests reset globals between cases so forked execution is not the only thing protecting isolation.
Step 3: Run verification
Run:
bash
npm test -- browser
npm test
npx tsc --noEmit
npm run lintExpected: browser.ts no longer remains at zero coverage.
Task 6: Harden the test system gates
This task converts the current test suite from permissive to enforceable.
Files:
- Modify:
vitest.config.ts - Modify:
package.json - Modify:
eslint.config.js
Step 1: Set non-zero coverage thresholds
After Tasks 2 through 5 are complete, run npm run test:coverage and set thresholds in vitest.config.ts using the ratchet rule from the design doc.
Step 2: Extend lint coverage to test code
Update lint configuration so test files are included in normal verification. The current lint script only checks src.
Step 3: Keep thresholds realistic
Start with a floor that the current suite can satisfy comfortably, then ratchet up in later iterations rather than blocking progress on an overly aggressive first gate.
Step 4: Run verification
Run:
bash
npm run lint
npx tsc --noEmit
npm test
npm run test:coverageExpected: all four commands pass with enforceable, non-zero thresholds.
Task 7: Update traceability and execution status
This task keeps the docs aligned with reality once implementation catches up.
Files:
- Modify:
docs/records/plans/2026-03-05-testing-infrastructure-design.md - Optional create:
docs/records/bugs/2026-03-10-<topic>-bugfix.mdif non-trivial defects are fixed during the rollout
Step 1: Update status language
Replace outdated statements such as "zero tests" and "Draft — pending approval" once the rollout milestone is complete.
Step 2: Record actual delivered phase status
Document which phases are complete, which are partial, and which hardening items remain open.
Step 3: Keep the record factual
Report actual commands, actual coverage, and actual remaining gaps instead of restating estimates.
Recommended execution order
Use this order to keep momentum and avoid mixing structural cleanup with new surface area.
- Finish Task 1.
- Implement Task 2.
- Implement Task 3.
- Implement Task 4.
- Implement Task 5.
- Implement Task 6.
- Close with Task 7.
Verification checklist
Use this checklist before calling the testing rollout complete.
npm testpasses.npx tsc --noEmitpasses.npm run lintpasses forsrcandtest.npm run test:coveragepasses with non-zero thresholds.MapManager,RoomManager, andbrowser.tsare no longer uncovered.- The design record reflects the actual delivered state.
Next steps
If you want to execute this in the current session, the cleanest next move is to treat Task 1 plus Task 2 as the first batch. That closes the in-flight refactor and lands the smallest missing manager slice before tackling the much larger MapManager surface.