Files
fn_registry/python/functions/browser/cdp_click_xy.md
T
egutierrez 8742cb25be feat(browser): auto-commit con 60 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-07 11:42:31 +02:00

4.9 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params_schema, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params_schema tested tests test_file_path file_path
cdp_click_xy function py browser 1.0.0 impure def cdp_click_xy(x: int, y: int, *, port: int = 9222, target_url_substr: str = '', move_first: bool = True, timeout_s: float = 10.0) -> dict Hace un click izquierdo de raton REAL en coordenadas (x, y) del viewport de una pestana de un Chrome con remote debugging, via CDP Input.dispatchMouseEvent (mouseMoved opcional + mousePressed + mouseReleased). Primitiva de input CDP reutilizable: necesaria cuando element.click() de JavaScript NO dispara los handlers de React de SPAs (WhatsApp Web): abrir un chat de la lista o un resultado de busqueda requiere un click de raton sintetico real. El caller resuelve las coordenadas con cdp_eval (getBoundingClientRect -> centro) y las pasa aqui.
cdp
browser
automation
python
navegator
false error_go_core
json
time
urllib.request
websocket
params output
name desc
x Coordenada X en CSS px del viewport donde hacer click. Normalmente el centro del elemento (getBoundingClientRect via cdp_eval).
name desc
y Coordenada Y en CSS px del viewport donde hacer click. Normalmente el centro del elemento (getBoundingClientRect via cdp_eval).
name desc
port Puerto de remote debugging de Chrome. Default 9222.
name desc
target_url_substr Substring que debe contener la URL del target (pestana). Si vacio, usa el primer target de tipo 'page'.
name desc
move_first Si True, emite un mouseMoved a (x, y) antes del click para que la SPA registre el hover. Default True.
name desc
timeout_s Timeout en segundos para la conexion WebSocket. Default 10.0.
dict {ok: bool, error: str, x: int, y: int}. ok=True si los eventos de raton (mouseMoved opcional, mousePressed, mouseReleased) se emitieron sin error; x/y son eco de los argumentos. Nunca lanza: errores de red/conexion/transport se devuelven en 'error' con ok=False.
true
test_golden_click_emite_movido_pressed_released_left
test_edge_move_first_false_omite_mousemoved
test_error_create_connection_lanza_ok_false
python/functions/browser/cdp_click_xy_test.py python/functions/browser/cdp_click_xy.py

Ejemplo

import sys, os, json
sys.path.insert(0, os.path.join("python", "functions"))
from browser.cdp_eval import cdp_eval
from browser.cdp_click_xy import cdp_click_xy

# Requiere un Chrome lanzado con --remote-debugging-port=9222
# y una pestana de WhatsApp Web abierta.
# Localizar el row de un chat por nombre exacto y abrirlo con click REAL.
r = cdp_eval(r'''(() => {
  const row = [...document.querySelectorAll('#side [role="row"]')]
    .find(x => /^NOTAS WASAP\b/.test(x.innerText.replace(/\s+/g,' ').trim()));
  if(!row) return null;
  const b = row.getBoundingClientRect();
  return JSON.stringify({x: Math.round(b.x+b.width/2), y: Math.round(b.y+b.height/2)});
})()''', target_url_substr="whatsapp")

c = json.loads(r["value"])
res = cdp_click_xy(c["x"], c["y"], target_url_substr="whatsapp")  # abre el chat
print(res["ok"], res["error"])

O directo por CLI: python3 python/functions/browser/cdp_click_xy.py 100 200 "whatsapp".

Cuando usarla

Cuando necesites clickar un elemento y element.click() de JavaScript NO dispara sus handlers (SPAs React como WhatsApp Web): abrir un chat de la lista, abrir un resultado de busqueda, pulsar un boton que React renderiza con listeners propios. Resuelve primero las coordenadas del elemento con cdp_eval_py_browser (getBoundingClientRect -> centro) y pasa x, y aqui. Es la primitiva de input de raton sobre la que se construyen funciones whatsapp_*_py_browser y cualquier script que opere una pestana existente via CDP. Para teclas usa cdp_press_key_py_browser; para escribir texto, cdp_type_chars_py_browser.

Gotchas

  • Coordenadas en CSS px del viewport: getBoundingClientRect() ya las devuelve en ese sistema, por eso encaja directo. No uses pageX/pageY ni coords absolutas de documento.
  • El elemento debe estar VISIBLE en el viewport: si esta fuera de pantalla por scroll, las coords del rect son invalidas (negativas o fuera de rango) y el click cae en el lugar equivocado. Haz scroll al elemento primero (via cdp_eval con scrollIntoView) y vuelve a leer el rect.
  • Es un click izquierdo simple (clickCount=1, button=left). No hace doble click, click derecho ni drag.
  • move_first=True (default) emite un mouseMoved previo para que la SPA registre el hover; algunas UIs solo muestran/activan controles tras hover. Ponlo en False si no lo necesitas.
  • Requiere un Chrome lanzado con --remote-debugging-port=9222 (o el puerto que pases). Sin remote debugging, GET /json falla y devuelve ok=False.
  • Nunca lanza: errores de red, conexion WS o transport se reportan en el campo error con ok=False.