Skip to content

Commit 2595ceb

Browse files
committed
fix: rewrite expect test scenarios to match actual features
The previous test prompt described a non-existent "element properties panel" feature, causing all expect tests to fail. Rewrote with 40 comprehensive scenarios covering the actual feature set: activation, toolbar, selection, copy HTML, copy styles, context menu, arrow navigation, drag selection, disabled elements, hover transitions, scroll tracking, dynamic elements, and clipboard metadata.
1 parent f2d3666 commit 2595ceb

File tree

1 file changed

+229
-34
lines changed

1 file changed

+229
-34
lines changed

.github/workflows/test-expect.yml

Lines changed: 229 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -54,44 +54,239 @@ jobs:
5454
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
5555
run: >-
5656
pnpm dlx expect-cli@latest --verbose -y -m
57-
"Test the arrow-key navigation and selection label feature at http://localhost:5175.
58-
Do not explore unrelated flows. If a step is blocked after one retry, fail with evidence.
59-
60-
react-grab is a browser overlay tool that lets you inspect React elements.
61-
When active, hovering over elements shows a selection label with the element
62-
tag name and component name (e.g. 'h1' or 'MyComponent.div').
63-
64-
Important repo-specific testing notes:
65-
1. This GitHub Actions run is on Linux, so the default activation shortcut is Ctrl+C.
66-
Do not try to activate react-grab by holding only Ctrl.
67-
2. React Grab is in toggle mode by default. Press Ctrl+C once to activate it,
68-
then hover elements and click to select them.
69-
3. If keyboard activation is flaky in CI, you may call window.__REACT_GRAB__.activate()
70-
from a Playwright evaluation instead.
71-
4. For assertions, prefer Playwright evaluation against the app state and shadow DOM
72-
over ARIA snapshots for the overlay UI.
73-
5. The overlay renders inside the shadow root of the element matching [data-react-grab].
74-
Helpful assertions can use window.__REACT_GRAB__.getState() and
75-
document.querySelector('[data-react-grab]')?.shadowRoot, especially
76-
[data-react-grab-selection-label].
77-
6. After activation, hover an element, click it to select it, then use ArrowUp / ArrowDown
78-
to navigate between elements. ArrowUp moves to a parent/stacked element,
79-
ArrowDown reverses that. ArrowLeft navigates to parent, ArrowRight to child.
80-
7. When arrow navigation is active, an arrow navigation menu appears inside the
81-
selection label showing the list of stacked/ancestor elements. Each item shows
82-
the tag name and optionally the React component name. The active item is fully
83-
opaque while inactive items are dimmed.
57+
"Comprehensive test of react-grab at http://localhost:5175.
58+
If a step is blocked after one retry, fail with evidence.
59+
60+
## What is react-grab?
61+
62+
react-grab is a browser overlay tool for inspecting and copying React elements.
63+
When activated, hovering over any element highlights it with a selection box overlay.
64+
Clicking an element selects it and copies its HTML to the clipboard. A floating
65+
selection label displays the element's HTML tag name and React component name
66+
(e.g. 'li' or 'TodoItem.li'). Right-clicking a selected element opens a context
67+
menu with Copy, Copy Styles, and other actions. The overlay UI renders inside a
68+
shadow DOM on the element matching [data-react-grab].
69+
70+
## How to activate and deactivate
71+
72+
This CI run is on Linux, so the activation shortcut is Ctrl+C (not Cmd+C).
73+
React Grab uses toggle mode by default — press Ctrl+C once to activate, press Escape
74+
or Ctrl+C again to deactivate. If keyboard activation is flaky in CI, call
75+
window.__REACT_GRAB__.activate() via Playwright evaluate instead.
76+
77+
## Core behaviors
78+
79+
**Selection:** Hovering highlights elements with a blue selection box that tracks the
80+
element bounds. Clicking copies the element HTML to clipboard and shows a brief
81+
'Copied' feedback animation on the selection label before deactivating (in toggle mode).
82+
83+
**Arrow-key navigation:** After hovering an element (before clicking), arrow keys
84+
navigate the DOM:
85+
- ArrowUp: moves to a parent/overlapping element (selection box grows).
86+
- ArrowDown: reverses ArrowUp (selection box shrinks back).
87+
- ArrowLeft: navigates to the parent element.
88+
- ArrowRight: navigates into a child element.
89+
Arrow navigation freezes selection — mouse movement won't change it until click/Escape.
90+
A navigation menu appears in the selection label listing stacked elements, with the
91+
active item at full opacity and others dimmed.
92+
93+
**Context menu:** Right-clicking a hovered element opens a context menu with actions
94+
including Copy (copies HTML) and Copy Styles (copies computed CSS). The context menu
95+
freezes the selection while open. Pressing Escape closes it.
96+
97+
**Copy feedback:** After copying, the selection label briefly shows 'Copied' status,
98+
then in toggle mode, react-grab deactivates automatically.
99+
100+
**Drag selection:** Click-and-drag across multiple elements to select them all at once.
101+
A drag box appears during the operation. All intersected elements get grabbed.
102+
103+
**Toolbar:** A small floating toolbar is always visible. It has a toggle button to
104+
activate/deactivate react-grab. The toolbar is draggable and snaps to viewport edges.
105+
It can be collapsed to save space. Right-clicking the toolbar toggle opens a menu.
106+
107+
## Assertion tips
108+
109+
Prefer Playwright evaluate over ARIA snapshots. Useful APIs:
110+
- window.__REACT_GRAB__.getState() returns { isActive, targetElement, ... }
111+
- document.querySelector('[data-react-grab]')?.shadowRoot for overlay elements
112+
- Shadow DOM selectors: [data-react-grab-selection-label], [data-react-grab-selection-box]
113+
114+
## Test page layout
115+
116+
The page at localhost:5175 has these sections (all have data-testid attributes):
117+
- Todo List (data-testid='todo-list'): heading + 7 list items
118+
- Deeply Nested Cards: three layers (Outer > Middle > Inner), innermost has
119+
data-testid='deeply-nested-text' and a data-testid='nested-button'
120+
- Form Elements (data-testid='form-section'): text input (data-testid='test-input'),
121+
textarea, Submit button (data-testid='submit-button'), Cancel button
122+
- Various Element Types (data-testid='various-section'): span, strong, em, code,
123+
link, plain button, a 3x2 table (data-testid='table-element' with cells like
124+
data-testid='td-1-1'), image, gradient div, semantic article element
125+
- Scrollable Content (data-testid='scrollable-section'): 50 items in a scroll container
126+
- Dynamic Elements (data-testid='dynamic-section'): elements that can be added/removed
127+
- Animated Elements: pulsing, spinning, bouncing elements
128+
- Edge Case Elements: zero-size, invisible, transparent, overflow elements
129+
- Dropdown: toggle button that shows/hides a menu
130+
- Footer (data-testid='footer'): end of page marker
84131
85132
IMPORTANT: Run every test scenario to completion. If a step fails, record the failure
86133
with evidence (screenshot or error) but continue testing remaining steps. Do not bail early.
87134
88-
Test scenarios:
89-
1. Activate react-grab with Ctrl+C, hover over a list item, click to select it — verify the selection label appears showing the element tag name.
90-
2. Press ArrowUp — verify the selection box moves to a parent or stacked element and the selection label updates to show the new element tag name.
91-
3. Press ArrowDown to reverse the ArrowUp navigation — verify the selection returns to the previous element.
92-
4. Press ArrowLeft from a child element — verify navigation moves to the parent element and the selection box grows larger.
93-
5. Press ArrowRight from a container element — verify navigation moves to a child element.
94-
6. Navigate between multiple elements with arrow keys — verify the selection label updates with the correct tag name each time and the overlay remains visible throughout."
135+
## Test scenarios
136+
137+
### Activation and deactivation
138+
1. Press Ctrl+C to activate react-grab — verify the overlay becomes active by checking
139+
window.__REACT_GRAB__.getState().isActive === true. Hover over the main title
140+
(data-testid='main-title') and confirm a selection box appears around it.
141+
142+
2. With react-grab active, press Escape — verify it deactivates and the selection box
143+
disappears (isActive becomes false).
144+
145+
3. Activate, then press Ctrl+C again — verify it toggles off (isActive === false).
146+
Press Ctrl+C once more to reactivate and confirm isActive === true again.
147+
148+
4. Click on the text input (data-testid='test-input') to focus it, then press Ctrl+C —
149+
verify react-grab still activates even when an input field has focus.
150+
151+
### Toolbar
152+
5. Before activating, verify the toolbar is visible on the page. Look for the
153+
react-grab toolbar element in the shadow DOM.
154+
155+
6. Click the toolbar toggle button — verify react-grab activates. Click it again —
156+
verify it deactivates.
157+
158+
7. Drag the toolbar to the left edge of the viewport — verify it snaps to the left
159+
side and its layout becomes vertical.
160+
161+
8. Collapse the toolbar by clicking its collapse control — verify it shrinks to a
162+
compact size. Expand it again and verify it returns to full size.
163+
164+
### Selection and copy HTML
165+
9. Activate react-grab, hover over a Todo List item to see the selection box, then
166+
click it — verify the clipboard contains HTML (e.g. an <li> tag with text content).
167+
168+
10. After the click-to-copy, verify the selection label briefly showed a 'Copied'
169+
status. In toggle mode, react-grab should auto-deactivate after copy —
170+
confirm isActive becomes false.
171+
172+
11. Activate, hover over the Submit button (data-testid='submit-button') — verify the
173+
selection label displays tag name 'button'. Click to copy and verify clipboard
174+
contains a <button> element.
175+
176+
12. Activate, hover over the deeply nested text (data-testid='deeply-nested-text') —
177+
verify the selection label shows the correct tag. Click to copy and confirm the
178+
clipboard includes the nested text content.
179+
180+
### Context menu and copy styles
181+
13. Activate, hover over the Submit button, then right-click — verify a context menu
182+
appears with menu items including 'Copy' and 'Copy Styles'. The selection should
183+
freeze while the menu is open.
184+
185+
14. Click 'Copy Styles' in the context menu — verify the clipboard is populated with
186+
CSS property-value pairs (e.g. containing 'color', 'font-size', or 'display').
187+
188+
15. Activate again, hover over the main title heading, right-click to open context
189+
menu, then press Escape — verify the context menu closes but react-grab stays
190+
active (isActive remains true).
191+
192+
16. Right-click and use 'Copy' from the context menu on a list item — verify the
193+
clipboard contains the element HTML, same as a left-click copy.
194+
195+
### Arrow-key navigation
196+
17. Activate, hover over a Todo List item (do NOT click). Press ArrowUp — verify the
197+
selection box grows to cover a parent element and the selection label updates to
198+
a different tag name (e.g. from 'li' to 'ul' or a container div).
199+
200+
18. Press ArrowUp repeatedly (3-4 times) — verify each press moves to a larger
201+
ancestor element. The selection box should never shrink when going up.
202+
203+
19. Press ArrowDown to walk back down — verify the selection returns through the same
204+
elements in reverse order, ending back at the original list item.
205+
206+
20. Hover over the deeply nested text (data-testid='deeply-nested-text'), press
207+
ArrowLeft — verify navigation moves to the parent card element and the
208+
selection box is visibly larger.
209+
210+
21. Hover over a container element (e.g. the todo-list ul), press ArrowRight — verify
211+
navigation moves into a child element and the selection box shrinks.
212+
213+
22. After arrow-key navigation freezes the selection, move the mouse to a completely
214+
different part of the page — verify the selection box stays frozen on the
215+
arrow-navigated element and does not follow the mouse.
216+
217+
### Different element types
218+
23. Activate and hover over a table cell (data-testid='td-1-1') — verify the
219+
selection label shows 'td'. Press ArrowLeft and verify it navigates to 'tr'.
220+
221+
24. Hover over the link element (data-testid='link-element') — verify the selection
222+
box highlights it and the label shows tag 'a'.
223+
224+
25. Hover over the image element (data-testid='img-element') — verify it can be
225+
selected and the label shows an image-related tag (e.g. 'svg' or 'img').
226+
227+
26. Hover over the code element (data-testid='code-element') — verify the selection
228+
label shows 'code'. Click to copy and check clipboard contains a <code> tag.
229+
230+
27. Hover over the strong element (data-testid='strong-element') — verify the label
231+
shows 'strong'.
232+
233+
28. Hover over the article element (data-testid='article-element') — verify the label
234+
shows 'article'. Use ArrowRight to navigate into children and verify the label
235+
updates as you move through header, content, and footer sections.
236+
237+
### Nested elements
238+
29. Hover over the innermost nested card (the one containing
239+
data-testid='deeply-nested-text'), click to select. Verify the clipboard contains
240+
HTML with the nested content. Then activate again, hover the same area, and press
241+
ArrowUp multiple times — verify you traverse through Inner > Middle > Outer card
242+
layers, with the selection box growing at each step.
243+
244+
### Drag selection
245+
30. Activate react-grab, then click-and-drag across multiple Todo List items — verify
246+
a drag selection box appears during the drag, and after releasing, multiple
247+
elements are grabbed (check via getState or visual grabbed boxes).
248+
249+
31. Start a drag but press Escape mid-drag — verify the drag cancels and no elements
250+
are grabbed.
251+
252+
### Disabled and edge-case elements
253+
32. Hover over the Submit button's disabled sibling or any disabled form element on
254+
the page — verify react-grab can still select and highlight it with a selection
255+
box despite it being disabled.
256+
257+
33. Hover over the overflow element (data-testid='overflow-element') which has text
258+
overflowing its container — verify the selection box covers the element's actual
259+
bounds.
260+
261+
### Hover transitions and defocus
262+
34. Activate, hover an element to see the selection box, then move the mouse off to
263+
an empty area — verify the selection updates (box moves or disappears).
264+
265+
35. Hover over one element, then quickly move to a completely different element far
266+
away — verify the selection box transitions to the new element without glitching.
267+
268+
36. Rapidly move the mouse across several different elements (todo items, buttons,
269+
headings) — verify the selection label keeps updating to reflect whatever is
270+
under the cursor without lag or stale labels.
271+
272+
### Scroll behavior
273+
37. Activate react-grab, scroll down to the Scrollable Content section
274+
(data-testid='scrollable-section'), hover over a scroll item — verify the
275+
selection box correctly positions over the scrolled element.
276+
277+
38. While hovering an element, scroll the page — verify the selection box tracks
278+
the element position as it moves with the scroll.
279+
280+
### Dynamic elements
281+
39. Activate react-grab. In the Dynamic Elements section (data-testid='dynamic-section'),
282+
click the add button (data-testid='add-element-button') to create a new element.
283+
Hover over the newly added element — verify react-grab can select it and the
284+
selection label shows its tag.
285+
286+
### Clipboard metadata
287+
40. Activate, hover over a React component element (like items in the Todo List which
288+
are rendered by React components), click to copy — inspect the clipboard and
289+
verify it includes the React component name context alongside the HTML."
95290
96291
- name: Upload session recording
97292
if: always()

0 commit comments

Comments
 (0)