2.4.6 Story E2E — detail page lifecycle (Playwright) + closes Story 2.4
Estimate: 18m · Depends on: 2.4.1, 2.4.2, 2.4.3, 2.4.4, 2.4.5, 2.4.9, 2.4.10
The Story-closing Playwright suite at tests/e2e/issue-detail-flow.spec.ts, driving the real shell. Setup uses the 2.2.7 _test harness + shell-session helpers (create project, create items, link, transition) so it has no ordering dependency on the create-modal/edit-form specs. Mirrors the 1.6.6 lesson — real-stack E2E catches UI↔service seam bugs the unit tests structurally can't.
This is the Story CLOSER, so it covers EVERY Story-2.4 surface end to end — the read + inline-edit surfaces (2.4.1–2.4.5) AND the link-management surface (2.4.9): adding/removing a link through the relationships panel is a real UI↔service seam (Server Action → linkWorkItems/unlinkWorkItems → trigger → revalidate → the panel + readiness banner re-render) exactly the kind of path unit tests can't exercise, so it earns a driven scenario rather than living only in 2.4.9's component/service tests.
Scenarios (single specs):
- Renders the canonical page: navigate to
/issues/PROD-N; assert header (icon + identifier + title + status), the Markdown description (bold/link/code rendered), the core-fields panel, and the "Edit" link →/issues/PROD-N/edit. - Tree navigation: for a subtask under a task under a story, the breadcrumb shows the lineage and a breadcrumb link navigates to the ancestor's detail page; a parent's child list links down to a child.
- Inline status (workflow-aware): change status to a legal next status → pill updates + persists across reload; an illegal target isn't offered (restricted) or is rejected (open boundary) — no silent change.
- Inline assignee: assign to a workspace member, then unassign; both persist across reload.
- Readiness: an item blocked by a non-terminal item reads "Blocked"; transition the blocker to done → the badge reads "Ready".
- Link management — add (2.4.9): from the relationships panel, add a
blocked_bylink to another issue via the combobox → the row appears under "Blocked by" and the readiness banner flips Ready→Blocked (driven through the UI, then asserted to persist across reload). - Link management — remove (2.4.9): remove that link inline (with confirm) → the row disappears and the banner flips back to Ready; removing a
relates_tolink drops both reciprocal rows. - Link management — guardrails (2.4.9): a self-link / duplicate / cycle attempt surfaces an INLINE error in the add form and persists nothing (the typed trigger errors round-tripped to the UI).
- Create with a link (2.4.10): open the create modal, add a pending link via the "Linked issues" combobox, create the issue → the link exists on the new issue's detail relationships panel (written atomically with the issue); removing the pending row before create writes nothing.
- Cross-workspace isolation: a user in workspace-A visiting a workspace-B identifier → 404 (no leak); the link combobox surfaces only own-workspace candidates.
Acceptance criteria
pnpm test:e2e --grep issue-detail-flowpasses locally + in CI against a fresh-DB run; no flake under 10 consecutive CI runs.- All scenarios present as specs with the documented assertions; status/assignee AND link add/remove changes are verified to PERSIST across reload (not just optimistic), each driven through the real UI (combobox, inline controls) — not by calling the service directly.
- The link-management scenarios drive the 2.4.9 add control + per-row remove; the guardrail spec asserts the inline error (self-link/duplicate/cycle) leaves the DB unchanged.
- Uses only the auth + 2.2.7
_testharness helpers for setup (extends them if needed — no parallel helper); selectors target stabledata-testid/role hooks added in 2.4.1–2.4.5 + 2.4.9, not brittle text. - The
/issues/[key]route stays in the STRICT shell-a11y sweep (added in 2.4.1), confirmed populated INCLUDING the open add-link combobox/dialog (reuses the 2.3.4 Combobox a11y).
Context refs
tests/e2e/_helpers/workflow.ts(2.2.7 — createItem/transition/linkBlockedBy) +shell-session.ts(1.5.6)tests/e2e/workflow-delete-reassign.spec.ts(2.3.2) +issue-create-edit-flow.spec.ts(2.3.8) — sibling conventions to mirror- The detail-page
data-testidhooks from 2.4.1–2.4.5 + 2.4.9's add-link control / per-row remove hooks;playwright.config.tswebServer block - 2.4.9's
RelationshipsPaneladd control +createLinkAction/removeLinkAction+ the typed link errors (lib/workItems/linkErrors.ts) the guardrail spec asserts