--- id: "9ee101c4-7df7-4d0d-bbbf-4f1a2cc71c5d" name: "Clicking by Visible Text" micro_summary: "Read this if you see any button you need to click." status: "in_progress" see_also: [] scope: "Text-matching click pattern: queryAll → filter by textContent.trim() → getBoundingClientRect() center → click_at_xy()" --- ## Clicking Elements by Visible Text When `querySelector('.some-class')` matches multiple elements (e.g., a header button collides with the target), iterate all matches and filter by `textContent.trim()`: ```python result = js("""(function() { const els = document.querySelectorAll(".btn-primary"); for (const el of els) { if (el.textContent.trim() === "Open SIMbook") { const rect = el.getBoundingClientRect(); return JSON.stringify({ x: rect.x + rect.width/2, y: rect.y + rect.height/2, text: el.textContent.trim(), href: el.href }); } } return JSON.stringify({error: "not found"}); })()""") print(result) # Then click the center: click_at_xy(600, 596) wait_for_load() wait(2) ``` **Pattern:** query all candidates → match by visible text → get `getBoundingClientRect()` center → `click_at_xy()`. This works for any element where a simple selector hits collisions. Never use `querySelector('.class')` alone when multiple elements share the class.