--- id: cdp_handle_dialog_go_browser name: cdp_handle_dialog kind: function lang: go domain: browser purity: impure version: 1.0.0 tested: false tests: [] test_file_path: "" description: "Instala un auto-handler que responde automaticamente a dialogos JS (alert/confirm/prompt/beforeunload) via Page.javascriptDialogOpening CDP hasta que se llame el cancel devuelto." tags: [cdp, browser, dialog, input, navegator] signature: "func CdpHandleDialog(c *CDPConn, accept bool, promptText string) (func(), error)" uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: error_go_core imports: [] file_path: "functions/browser/cdp_handle_dialog.go" example: | // Aceptar automaticamente confirm() antes de navegar cancel, _ := CdpHandleDialog(c, true, "") defer cancel() _ = CdpClick(c, "#delete-account-btn") _ = CdpWaitIdle(c, 2000) params: - name: c desc: "Conexion CDP activa obtenida con CdpConnect." - name: accept desc: "true para aceptar/OK el dialogo; false para rechazar/Cancel. Para alert() el valor no importa (siempre se cierra), para confirm() determina el valor de retorno, para prompt() determina si se devuelve el texto o null." - name: promptText desc: "Texto a inyectar en dialogos prompt(). Vacio string para no inyectar texto. Ignorado en alert() y confirm()." output: "cancel func() para des-registrar el handler cuando ya no se necesite, y error si la conexion es nula o Page.enable falla. El cancel devuelto es seguro llamarlo multiples veces." --- ## Ejemplo ```go conn, _ := CdpConnect(9222) _ = CdpNavigate(conn, "https://example.com/admin") _ = CdpWaitLoad(conn, 3000) // Instalar handler antes de la accion que dispara el dialogo cancel, err := CdpHandleDialog(conn, true, "") if err != nil { log.Fatal(err) } defer cancel() // Este boton dispara confirm("¿Seguro que quieres borrar?") // El handler lo acepta automaticamente sin bloquear _ = CdpClick(conn, "#btn-delete-all") _ = CdpWaitIdle(conn, 2000) // Ejemplo con prompt(): responder con texto especifico cancelPrompt, _ := CdpHandleDialog(conn, true, "mi-respuesta-secreta") defer cancelPrompt() _ = CdpClick(conn, "#btn-ask-password") _ = CdpWaitIdle(conn, 1000) ``` ## Cuando usarla Instalar antes de cualquier accion que pueda disparar `alert()`, `confirm()`, `prompt()` o `beforeunload` en la pagina. Sin este handler, el dialogo bloquea el tab del navegador indefinidamente y todas las llamadas CDP siguientes se quedan colgadas esperando. Imprescindible en scraping de paneles de administracion, flujos de borrado con confirmacion, y paginas con `beforeunload` que pregunta si quieres salir. ## Gotchas - DEADLOCK GARANTIZADO si se llama `sendCDP` de forma sincrona dentro del handler de evento. El handler corre en la goroutine de lectura del WebSocket; `sendCDP` espera una respuesta que esa misma goroutine deberia leer. La implementacion ya usa `go c.sendCDP(...)` para evitarlo — no modificar este patron. - El handler se instala de forma permanente hasta que se llame `cancel()`. Si la pagina dispara multiples dialogos, todos seran respondidos con los mismos parametros `accept` y `promptText`. - `Page.enable` es idempotente pero tiene coste de red; no llamar CdpHandleDialog en bucles tight. - Para `beforeunload` (cuando el usuario cierra/navega fuera), `accept: true` permite la navegacion y `accept: false` la bloquea. - Llamar `cancel()` no cierra dialogos ya abiertos; solo evita que los futuros sean respondidos automaticamente.