--- name: cdp_move_mouse_human kind: function lang: go domain: browser version: "1.0.0" purity: impure signature: "func CdpMoveMouseHuman(c *CDPConn, toX, toY float64, opts MouseHumanOpts) error" description: "Mueve el ratón desde (opts.FromX, opts.FromY) hasta (toX, toY) siguiendo una curva de Bézier cúbica con easing ease-in-out, micro-jitter perpendicular y pausas variables entre puntos, imitando el movimiento humano para reducir la detección de automatización." tags: [cdp, chrome, browser, mouse, human, navegator] uses_functions: - cdp_evaluate_go_browser uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: - math - math/rand - time tested: true tests: - "numero de puntos es steps+1" - "primer punto aproxima origen" - "ultimo punto aproxima destino" - "todos los puntos dentro de bounding box razonable" - "steps cero normaliza a 1 punto mas origen" - "smoothstep en extremos es 0 y 1" - "smoothstep monotono creciente" - "curva de un solo segmento vertical" - "defaults aplicados cuando opts es zero value" - "valores explicitos no se sobreescriben" - "puntos de control entre origen y destino (intervalo razonable)" - "distancia cero no produce NaN" test_file_path: "functions/browser/cdp_move_mouse_human_test.go" file_path: "functions/browser/cdp_move_mouse_human.go" params: - name: c desc: "Conexión CDP activa obtenida con CdpConnect." - name: toX desc: "Coordenada X del destino en píxeles de viewport." - name: toY desc: "Coordenada Y del destino en píxeles de viewport." - name: opts desc: "MouseHumanOpts: Steps (puntos intermedios, default 25), DurationMs (duración total, default 350-800 ms aleatorio), JitterPx (desviación perpendicular máxima por punto, default 2.0), FromX/FromY (origen, default 0,0 si < 0)." output: "error si la conexión es nula o falla algún Input.dispatchMouseEvent." --- ## Ejemplo ```go conn, _ := CdpConnect(9222) defer CdpClose(conn, 0) // Mover desde (100, 200) hasta (640, 480) con parámetros por defecto err := CdpMoveMouseHuman(conn, 640, 480, MouseHumanOpts{ FromX: 100, FromY: 200, }) // Personalizar curva: 40 pasos, 600 ms, jitter de 4px err = CdpMoveMouseHuman(conn, 300, 200, MouseHumanOpts{ Steps: 40, DurationMs: 600, JitterPx: 4.0, FromX: 640, FromY: 480, }) ``` ## Cuando usarla Antes de `CdpClick` o `CdpClickHuman` cuando necesitas que el movimiento del ratón parezca humano. Útil en scrapers o bots donde la trayectoria rectilínea instantánea dispara detección (Cloudflare, PerimeterX, DataDome). También útil para simular hover antes de un click para activar tooltips o menús desplegables. ## Gotchas - Las coordenadas son relativas al viewport visible, no a la página completa. Si el elemento está fuera del scroll, las coordenadas serán incorrectas — hacer scroll primero con `CdpEvaluate` + `scrollIntoView`. - `time.Sleep` es intencional: simula la duración física del movimiento. En tests headless sin Chrome real no hay efecto visible pero el sleep ocurre igualmente. - No garantiza indetectabilidad total. Sistemas de detección sofisticados analizan más señales (aceleración del dispositivo, patrones de timing a lo largo de la sesión, huellas de Canvas/WebGL). - `math/rand` usa la semilla por defecto (no criptográfica). Para movimientos más impredecibles, considera sembrar con `rand.New(rand.NewSource(time.Now().UnixNano()))`. - El micro-jitter es perpendicular al segmento global origen-destino, no a la tangente local de la curva. Para trayectorias muy curvas, la dirección del jitter puede no ser óptima. - `DurationMs` controla la pausa total pero no tiene en cuenta la latencia de red al Chrome. El movimiento real tarda `DurationMs + latencia_cdp * Steps`.