# Quirks Lab — Product Requirements (v9.1)

Quirks Lab is a practice site of tricky web UI patterns: sign-in and widgets inside open, closed and nested shadow roots, nested same-origin iframes, canvas-only targets and a "dynamic" room with hover menus, late content, rotating identifiers, native dialogs, drag-to-sort and a blocking promo overlay. Each pattern has a visible, checkable outcome.

**Problem.** Interface automation and manual testers need a stable place to practise elements that defeat naive locators, with an unambiguous on-screen result for every interaction.

## Users
- **Automation engineer** — Operate shadow-DOM, iframe, canvas and timing-sensitive controls and confirm the outcome where it really surfaces.
- **Manual tester** — Exercise each pattern by hand and compare against exact messages.

## Goals
- Every interaction produces an exact, observable message or state change.
- Outcomes that cross a boundary (frame to page, element to server) are really delivered, not just claimed locally.
- Values entered by the user are stored and echoed exactly as entered.

## Shadow DOM room: sign-in and vault (SHD)

Sign-in card inside an open shadow root and a vault inside a closed shadow root.

- **FR-SHD-01** (Must) The sign-in card inside the open shadow root accepts the demo user and signs them in.
  - Initial header "Not signed in"
  - After a valid sign-in the card reads "Signed in as Tess Tester" and the header shows "Tess Tester"
  - The password field is masked
- **FR-SHD-02** (Should) Invalid sign-in attempts are rejected with a message rendered inside the card.
  - Both fields empty: "Username and password are required"
  - Wrong password: "Invalid credentials" and the header still says "Not signed in"
- **FR-SHD-03** (Should) The Vault (closed shadow root) reveals its code only to a signed-in user.
  - Signed out, "Reveal code": "Sign in first to reveal the code"
  - Signed in, "Reveal code": shows "QX-7319-ALPHA" and the button becomes "Hide code"
  - "Hide code" masks the code again as dots

## Shadow DOM room: widgets (WID)

Nested counter, slotted tabs and a div-based combobox inside shadow roots.

- **FR-WID-01** (Should) The counter nested three shadow roots deep (panel, card, counter) steps by exactly 1 per click and clamps between 0 and 10.
  - Starts at 0 with "-" disabled
  - Three clicks on "+" read 3; one click on "-" then reads 2
  - At 10 "+" is disabled
- **FR-WID-02** (Could) Slotted tabs switch their light-DOM panels and the shadow combobox selects a value.
  - "Specs" shows "Build channel: stable · Shadow roots: open, closed, nested."
  - "Reviews" shows a quote ending "- 5 stars" and hides the Specs text
  - Choosing "Team" in the combobox shows trigger "Plan: Team" and "Selected plan: Team"

## Feedback with a form-associated rating (FBK)

A star-rating custom element that takes part in a native form and is stored by the server.

- **FR-FBK-01** (Must) Submitting feedback requires a rating of 1 to 5 stars.
  - Submit with no stars: "Pick 1 to 5 stars"
- **FR-FBK-02** (Must) The rating chosen in the custom element is the rating the server stores and echoes.
  - Name "Ada", 4 stars, comment: "Saved FB-NNNN · 4/5 stars from Ada"
  - Five stars are echoed as "5/5 stars"; a rating is never recorded as 0 when stars were chosen
- **FR-FBK-03** (Should) Reset clears name, comment and stars and removes the result line.

## Frames room (FRM)

Inline srcdoc iframe and three-level nested same-origin iframes that report to the top page.

- **FR-FRM-01** (Should) The Greeter inside the srcdoc iframe greets the typed name and validates empty input.
  - Empty name: "Please type a name"
  - Name "Lin": "Hello, Lin!" inside the frame
- **FR-FRM-02** (Must) A delivery choice in the outer frame and a confirmation in the inner frame are delivered to the top page.
  - Confirm is disabled until "I agree to the delivery terms" is ticked
  - After Confirm the inner frame says "Sent to the page"
  - The top page status then reads "Confirmed by inner frame · Express shipping" for the Express choice (Standard shipping by default)
  - The inner frame never claims delivery unless the top page was actually updated

## Canvas room (CNV)

Shape targets and a signature pad drawn on canvases without DOM nodes.

- **FR-CNV-01** (Could) Shape targets must be clicked in the requested order: green circle, red triangle, purple square.
  - Prompt "Target 1 of 3: click the green circle"
  - A wrong shape shows "Missed (clicked the blue square)"
  - Correct hit shows "Hit: green circle" and advances the prompt
  - After all three: "All 3 targets hit"
- **FR-CNV-02** (Could) The signature pad counts each pointer stroke; Save is enabled only when at least one stroke exists.
  - Initially "Strokes: 0" and Save disabled
  - Two strokes: "Strokes: 2", Save enabled, Save shows "Signature saved (2 strokes)"
  - Clear empties the pad, "Strokes: 0", Save disabled

## Dynamic room (DYN)

Hover menu, late content, rotating ids, native dialogs, drag-sort, gated controls and popup.

- **FR-DYN-01** (Should) About 1 s after the room opens a "Join the Lab Pro beta" overlay blocks the page until "No thanks" is clicked; it appears once per browser tab.
- **FR-DYN-02** (Should) File menu opens on hover with a delayed two-level submenu.
  - Hovering "Export" shows CSV and PDF; clicking CSV shows "Exported report.csv"
- **FR-DYN-03** (Should) Generate report renders its result after 1.5 to 3 s; Publish shows a toast for about 2.5 s.
  - While running: spinner "Generating..." and the button disabled
  - Result "Report RPT-NNNN ready · 128 rows"
  - Toast "Changes published" disappears after about 2.5 s
- **FR-DYN-04** (Could) The "Save draft" button changes its id and class every 2 s but always counts each click.
  - Three clicks show "Drafts saved: 3"
- **FR-DYN-05** (Should) Native confirm and prompt dialogs drive the item actions.
  - Delete + Cancel: "Delete cancelled"; Delete + OK: "Item deleted"
  - Rename with "Invoice 42 (final)": "Renamed to Invoice 42 (final)"
- **FR-DYN-06** (Should) Drag-and-drop reorders the step list and Check order evaluates it.
  - Initial order is 3, 1, 5, 2, 4: "Order wrong: 3, 1, 5, 2, 4"
  - After dragging into 1..5: "Order correct"
- **FR-DYN-07** (Could) Consent-gated Continue, a rich-text note and a help popup work.
  - Continue is disabled until "I have read the lab rules" is ticked, then "Continued after consent"
  - Bold text typed as "agenda" saves as "Saved 21 characters (with bold text)"
  - "Open help in a new window" opens a window titled "Help center" with a working "Close window"

## Non-functional requirements

- **NFR-01** (Must) Interactions inside shadow roots and frames report their result to the user and to the top page truthfully; no control shows success that did not happen.
- **NFR-02** (Should) Feedback is scoped to the browser session and identifiers have the form FB-NNNN.

## Glossary and rules

- **Open shadow root** — A shadow tree reachable through element.shadowRoot.
- **Closed shadow root** — A shadow tree not reachable from script; read it from the screen.

## Out of scope

- Cross-origin iframes
- File download contents
- Mobile touch gestures beyond pointer events
