--- name: cdp_click_human kind: function lang: go domain: browser version: "1.0.0" purity: impure signature: "func CdpClickHuman(c *CDPConn, selector string, opts MouseHumanOpts) error" description: "Hace click en el elemento identificado por selector CSS con comportamiento humano: obtiene el bounding box, calcula un destino ligeramente desplazado del centro, mueve el ratón con CdpMoveMouseHuman (curva de Bézier cúbica + easing + jitter) y despacha mousePressed/mouseReleased con micro-pausa de 30-90 ms entre ellos." tags: [cdp, chrome, browser, mouse, human, click, navegator] uses_functions: - cdp_evaluate_go_browser - cdp_move_mouse_human_go_browser uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: - fmt - math/rand - strings - time tested: false tests: [] test_file_path: "" file_path: "functions/browser/cdp_click_human.go" params: - name: c desc: "Conexión CDP activa obtenida con CdpConnect." - name: selector desc: "Selector CSS del elemento a clickear (ej. '#submit-btn', '.nav-item:first-child')." - name: opts desc: "MouseHumanOpts que controla la trayectoria del movimiento previo. Usa opts.FromX/FromY para definir el origen del movimiento (default 0,0)." output: "error si la conexión es nula, el elemento no existe en el DOM, o falla algún evento CDP." --- ## Ejemplo ```go conn, _ := CdpConnect(9222) defer CdpClose(conn, 0) CdpNavigate(conn, "https://example.com/login") CdpWaitElement(conn, "#username", 5*time.Second) // Click humano en el campo usuario desde la esquina superior izquierda err := CdpClickHuman(conn, "#username", MouseHumanOpts{ FromX: 50, FromY: 50, }) // Click en el botón submit viniendo desde donde está el campo usuario err = CdpClickHuman(conn, "#submit-btn", MouseHumanOpts{ FromX: 350, // aproximadamente donde quedó el cursor anterior FromY: 280, DurationMs: 500, Steps: 30, }) ``` ## Cuando usarla Sustituye a `CdpClick` cuando el sitio detecta clicks instantáneos sin movimiento previo o cuando el punto de click exactamente en el centro del elemento activa checks anti-bot. Usar en formularios de login, CAPTCHAs de comportamiento, botones con honeypot invisible en el centro exacto. ## Gotchas - El destino final se desplaza ±15% del tamaño del elemento respecto al centro para evitar siempre clickear en el pixel exacto. En elementos muy pequeños (<5px) el offset puede salir fuera del elemento — usar `CdpClick` en esos casos. - Hace `scrollIntoView` antes del movimiento. Si el elemento está en el fold inferior, el scroll ocurre y las coordenadas de la curva Bézier ya reflejan la posición post-scroll. Sin embargo, si el scroll produce reflow del DOM (lazy-load), puede que el selector cambie de posición durante el movimiento. - La micro-pausa de 30-90 ms entre mousePressed y mouseReleased está codificada en el rango típico humano. No hay opción para ajustarla — si necesitas control total, llama `CdpMoveMouseHuman` + `Input.dispatchMouseEvent` manualmente. - No garantiza indetectabilidad total. Ver `## Gotchas` de `cdp_move_mouse_human_go_browser`. - Requiere que el elemento sea visible (no `display:none` ni `visibility:hidden`). `getBoundingClientRect` retorna todos ceros para elementos ocultos, produciendo click en (0,0). - `opts.FromX` y `opts.FromY` deben ser la posición actual real del cursor para que la trayectoria sea convincente. Si no conoces la posición actual, pasa el centro aproximado de la última acción.