# Test — Canvas Editor (Bounding-Box + Multi-Select + Zoom + Pan) **Task**: AZ-471_test_canvas_bbox **Name**: CanvasEditor manual draw + 8-handle resize + Ctrl+click multi-select + Ctrl+wheel zoom + Ctrl+drag pan **Description**: Implement the 5 blackbox tests covering the core canvas interactions: draw bbox, resize via 8 handles, multi-select via Ctrl+click, zoom-around-cursor via Ctrl+wheel, pan via Ctrl+drag. **Complexity**: 5 points **Dependencies**: AZ-456_test_infrastructure **Component**: 06_annotations (CanvasEditor) (Blackbox Tests) **Tracker**: AZ-471 **Epic**: AZ-455 ## Problem The canvas editor is the SPA's most-interactive surface; canvas-pixel coordinates introduce floating-point + DPR gotchas that have caused subtle off-by-pixel regressions. The 5 scenarios pin geometry, modifier-key semantics, and viewport transformation. ## Outcome - 5 scenarios pass with deterministic numeric fixtures (no `getBoundingClientRect` flakiness across viewport sizes). ## Scope ### Included | Scenario | Profile | Source file | |----------|---------|-------------| | FT-P-39 — manual bounding-box draw on `` | fast + e2e | blackbox-tests.md | | FT-P-40 — 8-handle bbox resize | fast | blackbox-tests.md | | FT-P-41 — Ctrl+click multi-select on canvas | fast | blackbox-tests.md | | FT-P-42 — Ctrl+wheel zoom-around-cursor | fast | blackbox-tests.md | | FT-P-43 — Ctrl+drag pan on empty canvas | fast | blackbox-tests.md | ### Excluded - Tile-split interaction (covered in 19_test_tile_split_zoom). - Annotation overlay membership (covered in 07_test_overlay_membership). - Save-on-change (covered in 05_test_annotations_endpoint). ## Acceptance Criteria **AC-1: Manual draw geometry** Draw a bbox at `(x1,y1)→(x2,y2)`; resulting annotation carries the canonical canvas-coordinate quad. Floating-point compare within ±0.5 px tolerance. **AC-2: 8-handle resize** Drag each of the 8 handles independently; assert resulting bbox geometry per handle. Each handle's anchor (opposite corner / edge midpoint) is invariant during the drag. **AC-3: Ctrl+click multi-select** Ctrl+click on a second bbox adds it to the selection; selection set contains both bboxes (asserted via DOM rendering — selection ring style). **AC-4: Zoom-around-cursor** Ctrl+wheel at cursor `(cx, cy)`: the canvas pixel under `(cx, cy)` BEFORE the wheel equals the canvas pixel under `(cx, cy)` AFTER (within ±0.5 px). **AC-5: Empty-canvas pan** Ctrl+drag on an empty canvas region: viewport offset shifts by `(dx, dy)`; bbox positions in canvas coords are invariant. ## System Under Test Boundary - System under test: `` + its pointer/mouse handlers + the canvas-coordinate ↔ viewport transform. - Allowed stubs: MSW for annotation load. - Disallowed: stubbing the canvas component or asserting on React state. Pointer events are dispatched via RTL `user-event` (or Playwright `dispatchEvent` for e2e). - Expected observables per `results_report.md` rows 73-78 (Group 16). ## Constraints - Use fixed-size canvas (640×480) so coordinate math is deterministic. ## Risks & Mitigation **Risk 1 — DPR + retina display flakiness** - *Risk*: Test runner on a retina display reports different physical pixels than the e2e Docker container. - *Mitigation*: Playwright config forces `deviceScaleFactor: 1`; Vitest+jsdom defaults to DPR 1.