{"ns":"misc","title":"Quirks Lab","version":"9.1","summary":"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.","personas":[{"name":"Automation engineer","need":"Operate shadow-DOM, iframe, canvas and timing-sensitive controls and confirm the outcome where it really surfaces."},{"name":"Manual tester","need":"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."],"features":[{"id":"SHD","title":"Shadow DOM room: sign-in and vault","summary":"Sign-in card inside an open shadow root and a vault inside a closed shadow root.","reqs":[{"id":"FR-SHD-01","weight":"Must","text":"The sign-in card inside the open shadow root accepts the demo user and signs them in.","accept":["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"]},{"id":"FR-SHD-02","weight":"Should","text":"Invalid sign-in attempts are rejected with a message rendered inside the card.","accept":["Both fields empty: \"Username and password are required\"","Wrong password: \"Invalid credentials\" and the header still says \"Not signed in\""]},{"id":"FR-SHD-03","weight":"Should","text":"The Vault (closed shadow root) reveals its code only to a signed-in user.","accept":["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"]}]},{"id":"WID","title":"Shadow DOM room: widgets","summary":"Nested counter, slotted tabs and a div-based combobox inside shadow roots.","reqs":[{"id":"FR-WID-01","weight":"Should","text":"The counter nested three shadow roots deep (panel, card, counter) steps by exactly 1 per click and clamps between 0 and 10.","accept":["Starts at 0 with \"-\" disabled","Three clicks on \"+\" read 3; one click on \"-\" then reads 2","At 10 \"+\" is disabled"]},{"id":"FR-WID-02","weight":"Could","text":"Slotted tabs switch their light-DOM panels and the shadow combobox selects a value.","accept":["\"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\""]}]},{"id":"FBK","title":"Feedback with a form-associated rating","summary":"A star-rating custom element that takes part in a native form and is stored by the server.","reqs":[{"id":"FR-FBK-01","weight":"Must","text":"Submitting feedback requires a rating of 1 to 5 stars.","accept":["Submit with no stars: \"Pick 1 to 5 stars\""]},{"id":"FR-FBK-02","weight":"Must","text":"The rating chosen in the custom element is the rating the server stores and echoes.","accept":["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"]},{"id":"FR-FBK-03","weight":"Should","text":"Reset clears name, comment and stars and removes the result line."}]},{"id":"FRM","title":"Frames room","summary":"Inline srcdoc iframe and three-level nested same-origin iframes that report to the top page.","reqs":[{"id":"FR-FRM-01","weight":"Should","text":"The Greeter inside the srcdoc iframe greets the typed name and validates empty input.","accept":["Empty name: \"Please type a name\"","Name \"Lin\": \"Hello, Lin!\" inside the frame"]},{"id":"FR-FRM-02","weight":"Must","text":"A delivery choice in the outer frame and a confirmation in the inner frame are delivered to the top page.","accept":["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"]}]},{"id":"CNV","title":"Canvas room","summary":"Shape targets and a signature pad drawn on canvases without DOM nodes.","reqs":[{"id":"FR-CNV-01","weight":"Could","text":"Shape targets must be clicked in the requested order: green circle, red triangle, purple square.","accept":["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\""]},{"id":"FR-CNV-02","weight":"Could","text":"The signature pad counts each pointer stroke; Save is enabled only when at least one stroke exists.","accept":["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"]}]},{"id":"DYN","title":"Dynamic room","summary":"Hover menu, late content, rotating ids, native dialogs, drag-sort, gated controls and popup.","reqs":[{"id":"FR-DYN-01","weight":"Should","text":"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."},{"id":"FR-DYN-02","weight":"Should","text":"File menu opens on hover with a delayed two-level submenu.","accept":["Hovering \"Export\" shows CSV and PDF; clicking CSV shows \"Exported report.csv\""]},{"id":"FR-DYN-03","weight":"Should","text":"Generate report renders its result after 1.5 to 3 s; Publish shows a toast for about 2.5 s.","accept":["While running: spinner \"Generating...\" and the button disabled","Result \"Report RPT-NNNN ready · 128 rows\"","Toast \"Changes published\" disappears after about 2.5 s"]},{"id":"FR-DYN-04","weight":"Could","text":"The \"Save draft\" button changes its id and class every 2 s but always counts each click.","accept":["Three clicks show \"Drafts saved: 3\""]},{"id":"FR-DYN-05","weight":"Should","text":"Native confirm and prompt dialogs drive the item actions.","accept":["Delete + Cancel: \"Delete cancelled\"; Delete + OK: \"Item deleted\"","Rename with \"Invoice 42 (final)\": \"Renamed to Invoice 42 (final)\""]},{"id":"FR-DYN-06","weight":"Should","text":"Drag-and-drop reorders the step list and Check order evaluates it.","accept":["Initial order is 3, 1, 5, 2, 4: \"Order wrong: 3, 1, 5, 2, 4\"","After dragging into 1..5: \"Order correct\""]},{"id":"FR-DYN-07","weight":"Could","text":"Consent-gated Continue, a rich-text note and a help popup work.","accept":["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\""]}]}],"nfr":[{"id":"NFR-01","weight":"Must","text":"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."},{"id":"NFR-02","weight":"Should","text":"Feedback is scoped to the browser session and identifiers have the form FB-NNNN."}],"glossary":[{"term":"Open shadow root","meaning":"A shadow tree reachable through element.shadowRoot."},{"term":"Closed shadow root","meaning":"A shadow tree not reachable from script; read it from the screen."}],"outOfScope":["Cross-origin iframes","File download contents","Mobile touch gestures beyond pointer events"]}