--- name: cdp_pick_element_js kind: function lang: js domain: browser version: "1.0.0" purity: pure signature: "(self-executing IIFE injected via CDP Runtime.evaluate)" description: "Snippet JS inyectable que activa modo click-to-pick en una pagina Chrome remota: hover muestra overlay rojo, click captura CSS selector + XPath + tag + texto + bbox y los emite por console.log con prefijo '__fn_picked__'. El caller (navegator_dashboard) lee via CDP Runtime.consoleAPICalled." tags: [navegator, cdp, browser, picker, scraping, js] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "" file_path: "functions/browser/cdp_pick_element_js.js" params: - name: (none — IIFE, sin argumentos) desc: "Snippet stand-alone. Se inyecta el fichero entero como `expression` de Runtime.evaluate." output: "Mensaje en console.log con prefijo `__fn_picked__` seguido de JSON {selector,xpath,tag,text,attrs,rect}. Si user pulsa Escape: {cancelled: true}." example: | # En navegator_dashboard, al pulsar boton "Pick": # 1. Lee el archivo cdp_pick_element_js.js (string). # 2. Envia via WebSocket CDP al tab activo: # {"id": N, "method": "Runtime.evaluate", "params": {"expression": ""}} # 3. Escucha eventos "Runtime.consoleAPICalled" filtrando args[0].value == "__fn_picked__". # 4. Parsea args[1].value como JSON -> dict con selector/xpath/tag/text/attrs/rect. --- ## Cuando usarla Cuando un user pulsa "Pick element" en un tab de Chrome remoto para capturar un selector robusto sin abrir DevTools. Salida usable en recipes YAML o tests. ## Gotchas - Idempotente: re-inyectar limpia overlay anterior. - Path CSS truncado a 6 niveles para evitar selectores fragiles cross-rerender. - Filtra clases dinamicas comunes (`active`, `hover`, `selected`...) que rotan. - No funciona sobre iframes anidados — solo top frame. - Escape cancela y emite `{cancelled: true}`. - El listener captura events en fase capture para preceder a handlers de la pagina. ## Notas Reutilizable en otras apps C++/Python que hablen CDP. La salida via `console.log` es preferible a `Runtime.evaluate` con `returnByValue=true` porque el pick es asincrono (espera click del user) y no encaja en una sola RPC.