--- name: cdp_press_key kind: function lang: py domain: browser version: "1.0.0" purity: impure signature: "def cdp_press_key(key: str, *, port: int = 9222, target_url_substr: str = '', modifiers: int = 0, timeout_s: float = 10.0) -> dict" description: "Pulsa una tecla nombrada (Enter, Escape, Backspace, Tab, ArrowDown, Delete, ...) sobre el elemento enfocado de una pestana de un Chrome con remote debugging, via CDP Input.dispatchKeyEvent (rawKeyDown + keyUp). Primitiva de input CDP reutilizable: enviar mensajes (Enter en el composer de WhatsApp), cerrar overlays (Escape), navegar resultados (ArrowDown), borrar (Backspace) o combos con modificadores (Ctrl+A)." tags: [cdp, browser, automation, python, navegator] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: ["json", "urllib.request", "websocket"] params_schema: params: - name: key desc: "Nombre canonico de la tecla a pulsar. Soportadas: Enter, Escape, Backspace, Tab, Delete, ArrowDown, ArrowUp, ArrowLeft, ArrowRight, Home, End. Una tecla no soportada devuelve ok=False sin tocar la red." - name: port desc: "Puerto de remote debugging de Chrome. Default 9222." - name: target_url_substr desc: "Substring que debe contener la URL del target (pestana). Si vacio, usa el primer target de tipo 'page'." - name: modifiers desc: "Bitmask de modificadores CDP combinables con OR: Alt=1, Ctrl=2, Meta/Cmd=4, Shift=8. Ej. Ctrl+Shift = 2|8 = 10. Default 0." - name: timeout_s desc: "Timeout en segundos para la conexion WebSocket. Default 10.0." output: "dict {ok: bool, error: str}. ok=True si los eventos rawKeyDown+keyUp se emitieron sin error. Nunca lanza: errores de red/conexion/transport y teclas no soportadas se devuelven en 'error' con ok=False." tested: true tests: ["test_golden_enter_emite_rawkeydown_y_keyup_vk13", "test_edge_tecla_no_soportada_ok_false_sin_abrir_ws", "test_error_create_connection_lanza_ok_false"] test_file_path: "python/functions/browser/cdp_press_key_test.py" file_path: "python/functions/browser/cdp_press_key.py" --- ## Ejemplo ```python import sys, os sys.path.insert(0, os.path.join("python", "functions")) from browser.cdp_press_key import cdp_press_key # Requiere un Chrome lanzado con --remote-debugging-port=9222 # y una pestana de WhatsApp Web abierta con el composer enfocado y texto escrito. res = cdp_press_key("Enter", target_url_substr="whatsapp") # envia el mensaje print(res["ok"], res["error"]) # Combo con modificadores (Ctrl+A para seleccionar todo): Ctrl=2. cdp_press_key("Home", target_url_substr="whatsapp", modifiers=2) ``` O directo por CLI: `python3 python/functions/browser/cdp_press_key.py "Enter" "whatsapp"`. ## Cuando usarla Cuando necesites enviar una pulsacion de tecla sobre la pestana **ya abierta** del navegador diario sin abrir ventana nueva ni darle foco al sistema: **Enter** para enviar (composer de WhatsApp), **Escape** para cerrar overlays/dialogos, **ArrowDown/ArrowUp** para navegar resultados de busqueda, **Backspace/Delete** para borrar, o combos con `modifiers` (Ctrl/Shift/Alt/Meta). Tipicamente **despues** de escribir con `cdp_type_chars_py_browser` para confirmar la accion. Es la primitiva de input sobre la que se construyen funciones `whatsapp_*_py_browser` y cualquier script que opere una pestana existente via CDP. ## Gotchas - Actua sobre el elemento **enfocado** de la pagina: CDP `Input.dispatchKeyEvent` no apunta a un selector, va al foco actual. Asegura el foco (clic o `el.focus()` via `cdp_eval_py_browser`) antes de pulsar. - **Enter en WhatsApp Web envia el mensaje** (no inserta salto de linea). Para newline dentro del composer usa Shift+Enter (`modifiers=8`) o no uses esta funcion para eso. - `modifiers` es el bitmask de CDP, no un string: Alt=1, Ctrl=2, Meta/Cmd=4, Shift=8; combina con OR (ej. Ctrl+Shift = 10). - No se emite evento `char` aparte: el par `rawKeyDown`+`keyUp` con el `windowsVirtualKeyCode` correcto (Enter=13) basta para disparar el envio en WhatsApp (validado via `press_key` del MCP del navegador). - 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, transport o tecla no soportada se reportan en el campo `error` con `ok=False`.