Implement CE-WP-0010 Annotate & Attributes UX.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Rename Review→Annotate; Capture keeps Evidence and adds Attributes column
(no bottom strip); evidence/attribute filters; card→citation connectors via
shared Overlay bridges; finish workplan T01–T07.
This commit is contained in:
tegwick 2026-07-30 19:41:42 +02:00
parent dc7d8f7ce8
commit e9f7676a1a
15 changed files with 241 additions and 437 deletions

View file

@ -147,22 +147,21 @@ describe("CE-WP-0003-T08 — PRD scenario steps 5-9 end-to-end", () => {
// CE-WP-0005: route is now session-scoped.
expect(window.location.hash).toMatch(/^#\/s\/sess_[^/]+\/forms\/demo$/);
// Step 6: focus summary, then click the strip card to link directly.
const summaryField = screen.getByLabelText("Summary of the matter");
// Step 6: focus summary attribute, then click the Evidence card to link.
const summaryField = screen.getByRole("textbox", { name: /Summary of the matter/ });
await user.click(summaryField);
const stripCard = await screen.findByRole("button", {
const evidenceCard = await screen.findByRole("button", {
name: /Overlay E2E evidence/,
});
await user.click(stripCard);
await user.click(evidenceCard);
// Move focus elsewhere and back to re-fire focus on summary so that
// ActiveStateProvider triggers focus-target (the previous click that
// created the link consumed the staged state).
await user.click(screen.getByLabelText("Disputed amount"));
await user.click(screen.getByRole("textbox", { name: /Disputed amount/ }));
await user.click(summaryField);
// Step 8: aria-current on field row, chip, and (via the active
// state) the strip card.
// Step 8: aria-current on attribute row and active evidence card.
await waitFor(() => {
const fieldRow = document.querySelector(
'[data-field-id="summary"][aria-current="true"]',
@ -173,7 +172,7 @@ describe("CE-WP-0003-T08 — PRD scenario steps 5-9 end-to-end", () => {
expect(activeCard).not.toBeNull();
expect(activeCard!.textContent).toMatch(/Overlay E2E evidence/);
// Step 9: SVG overlay renders 2 paths (field→card + card→highlight).
// Step 9: SVG overlay renders 2 paths (attribute→card + card→highlight).
// HighlightRectBridge registers via the mocked getHighlightClientRects.
await waitFor(() => {
const svg = document.querySelector('[data-testid="visual-guide-overlay"]');