3.2.7 Story tests — board UI components + drag/snap-back + keyboard-DnD E2E
Estimate: 20m · Depends on: 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.8
The closing test subtask for the board UI — the same split Story 3.1.7 used: this story ships its OWN component tests + the core drag/snap-back/keyboard E2E, while the cross-cutting Epic-3 journey (drag + WIP + swimlanes at scale) lives in the Epic test story 3.5. The 3.1 API contract is already E2E-proven (3.1.7); this proves the UI on top of it.
Component / unit (vitest). The optimistic-move reducer (apply → confirm on 200 → revert on 409/422, with correct column-count deltas); BoardCard rendering (type hue, key/title/assignee/priority/points, blocked indicator); BoardColumn (count, empty state); the unmapped-tray present/absent branch. The per-column LOAD model — virtualization with NO "Load more"/cursor paging — and its tests are owned by Story 3.8 (3.8.6); this story does not test per-column paging.
E2E (Playwright) tests/e2e/board-ui.spec.ts. Against a freshly seeded project:
- Render —
/boardsshows the default columns in workflow order with cards grouped into the right columns + per-column counts. - Legal move — drag a card across columns under a legal transition → it lands, the count updates, and a re-fetch/quick-view shows the new status (the move-as-transition contract, end-to-end through the UI).
- Snap-back — an illegal cross-column move under a
restrictedworkflow → the card returns to its origin column and the status is unchanged on re-fetch (the 409 path). - In-column reorder — drag within a column → rank changes, status + membership unchanged, order persists on reload.
- Keyboard DnD — move a card to another column using the keyboard alone (pick up / arrow / drop) → the move happens.
Defers to Story 3.5: WIP-limit and swimlane journeys, and the large-scale virtualization E2E (this story's scale proof is the 3.2.5 acceptance check against db:seed:large).
Acceptance criteria
pnpm testcovers the optimistic-move reducer (confirm/revert),BoardCard/BoardColumnrender, and the unmapped-tray branch (the per-column load model is Story 3.8, not tested here).pnpm test:e2e --grep board-uiruns green over the real stack, asserting: column render + grouping + counts, a legal drag move (status persists), an illegal-move snap-back (409, status unchanged), an in-column reorder (rank only), and a keyboard-DnD move.- The E2E reuses the real-Postgres harness (
tests/helpers/db.tstruncation) and the seeded project; it does NOT duplicate the WIP/swimlane/scale journeys (Story 3.5).
Context refs
tests/e2e/board-projection.spec.ts(Story 3.1.7) — the API-level board E2E this builds the UI E2E on top of;tests/e2e/workflow-flow.spec.ts— the closing-E2E patterntests/helpers/db.ts— real-Postgres truncation; the dnd-kit testing notes for driving keyboard/pointer DnD in Playwright- Story 3.5 — the Epic-3 test story this defers WIP/swimlane/scale journeys to;
motir-core/CLAUDE.md— test conventions (real Postgres, no mocks)