.claude/skills/pinchtab-react-click-fix/SKILL.md
Fix Pinchtab/headless browser JavaScript .click() not triggering React event handlers. Use when: (1) pinchtab eval element.click() runs but React app doesn't respond, (2) clicking links/buttons on React SPAs via headless browser automation has no effect, (3) OpenTable or other React sites ignore programmatic clicks but work with real user clicks. Solution: use dispatchEvent with full MouseEvent sequence (mousedown/mouseup/click) with real coordinates from getBoundingClientRect().
npx skillsauth add Dbochman/dotfiles pinchtab-react-click-fixInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
When automating React-based websites with Pinchtab (or any headless browser tool that uses
element.click() via JavaScript eval), React's synthetic event system may not process the
click. The element's native click fires but React's event delegation doesn't pick it up,
so no navigation or state change occurs.
pinchtab eval "element.click()" runs successfully (no error) but nothing happenspinchtab snap -i -c may not show the target elements in the accessibility tree
(e.g., <a href="" role="button"> elements with empty href)Replace element.click() with a full MouseEvent dispatch sequence using real coordinates:
const rect = element.getBoundingClientRect();
const x = rect.x + rect.width / 2;
const y = rect.y + rect.height / 2;
const opts = { bubbles: true, cancelable: true, clientX: x, clientY: y, button: 0 };
element.dispatchEvent(new MouseEvent('mousedown', opts));
element.dispatchEvent(new MouseEvent('mouseup', opts));
element.dispatchEvent(new MouseEvent('click', opts));
Key requirements:
clientX/clientY from getBoundingClientRect() (React uses these for event delegation)bubbles: true: Events must bubble up to React's root event listenerReact uses event delegation — it attaches a single event listener at the root DOM node and
dispatches synthetic events based on the event target and coordinates. A simple .click()
call creates a click event but may not include the coordinates or preceding mousedown/mouseup
events that React's event system expects.
After dispatching, check that the page navigated or state changed:
// Wait a few seconds, then check
const url = window.location.href;
const title = document.title;
From the OpenTable booking script (opentable-book.sh):
// Find the best timeslot
const els = Array.from(document.querySelectorAll('a[role=button]'));
const timeEls = els.filter(e => /\d:\d\d [AP]M/.test(e.textContent.trim()));
// ... find closest to target time ...
// Click with full MouseEvent sequence
const rect = best.getBoundingClientRect();
const x = rect.x + rect.width/2;
const y = rect.y + rect.height/2;
const opts = {bubbles:true, cancelable:true, clientX:x, clientY:y, button:0};
best.dispatchEvent(new MouseEvent('mousedown', opts));
best.dispatchEvent(new MouseEvent('mouseup', opts));
best.dispatchEvent(new MouseEvent('click', opts));
click <ref> command should work correctly (it dispatches real
CDP input events), but some elements don't appear in pinchtab's accessibility tree snapshot
(e.g., <a href="" role="button"> with empty href), making native click unusablepinchtab click <ref> when the element IS in the snap tree.click() usually works finedevelopment
Search the web for current information, news, facts, and answers. Use when asked questions about current events, needing to look something up, finding websites, researching topics, or when you need up-to-date information beyond your training data.
development
Summarize any URL, YouTube video, podcast, PDF, or file into concise text. Use when asked to read an article, summarize a link, get the gist of a video or podcast, extract content from a URL, or when you need to understand what a web page or document contains.
development
Play music via Spotify and control Google Home speakers. Use when asked to play music, songs, artists, playlists, podcasts, or control speakers/volume/audio.
testing
Create new OpenClaw skills, modify and improve existing skills, and measure skill performance with evals. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy. Also use when asked to "make a skill", "turn this into a skill", "improve this skill", or "test this skill".