Files
fn_registry/functions/browser/cdp_wait_idle_test.go
T
Egutierrez ccfa5bc78b feat(browser): funciones anti-deteccion + perfiles para web_scraping
Funciones nuevas del dominio browser (grupo navegator):
- cdp_move_mouse_human / cdp_click_human: movimiento de raton con curva
  de Bezier cubica, easing y micro-jitter para imitar comportamiento
  humano y reducir deteccion de automatizacion.
- cdp_wait_idle: espera network-idle contando requests en vuelo via
  eventos CDP Network.*; inmune a extensiones que mutan el DOM
  (Dark Reader, uBlock) y a animaciones JS.
- list_chrome_profiles: lista perfiles de un user-data-dir (extensiones,
  nombre legible, preferencias).
- prepare_chrome_profile (bash): clona un user-data-dir conservando solo
  una whitelist de extensiones (default uBlock Origin Lite).

Modificadas:
- chrome_launch: Linux-first (chromium/google-chrome/brave antes que
  chrome.exe), KeepExtensions y Setpgid para matar el arbol con cdp_close.
- cdp_close: kill por grupo de proceso.

Todas con tests verdes (go test ./functions/browser ok).
2026-06-05 16:25:11 +02:00

53 lines
1.5 KiB
Go

package browser
import (
"strings"
"testing"
"time"
)
// TestCdpWaitIdleDefaults verifica el comportamiento observable de CdpWaitIdle
// sin requerir una instancia Chrome real.
func TestCdpWaitIdleDefaults(t *testing.T) {
t.Run("conexion nula retorna error inmediato", func(t *testing.T) {
err := CdpWaitIdle(nil, CdpWaitIdleOpts{})
if err == nil {
t.Fatal("esperaba error para conexion nula, got nil")
}
})
t.Run("opts con ceros aplica defaults antes de usar", func(t *testing.T) {
// Zero-value de CdpWaitIdleOpts debe tener todos los campos en 0
// para que la logica de defaults sea alcanzable.
var opts CdpWaitIdleOpts
if opts.QuietMs != 0 || opts.Timeout != 0 || opts.MaxInflight != 0 || opts.PollMs != 0 {
t.Fatal("zero-value de CdpWaitIdleOpts debe tener todos los campos en 0")
}
})
t.Run("error de conexion nula contiene texto descriptivo", func(t *testing.T) {
err := CdpWaitIdle(nil, CdpWaitIdleOpts{
QuietMs: 100,
Timeout: 500 * time.Millisecond,
PollMs: 50,
})
if err == nil {
t.Fatal("esperaba error, got nil")
}
msg := err.Error()
if len(msg) == 0 {
t.Error("el mensaje de error no debe estar vacio")
}
})
t.Run("mensaje de error nil-conn menciona cdp wait idle", func(t *testing.T) {
err := CdpWaitIdle(nil, CdpWaitIdleOpts{})
if err == nil {
t.Fatal("esperaba error, got nil")
}
if !strings.Contains(err.Error(), "cdp wait idle") {
t.Errorf("mensaje de error %q no contiene 'cdp wait idle'", err.Error())
}
})
}