Files
fn_registry/functions/browser/cdp_select_dropdown.md
T
Egutierrez 4187f9b6b1 feat(browser): actionability + dropdowns + fill + role locator (estilo Playwright)
Tras estudiar el código de Playwright (sources/playwright), 4 primitivas nuevas y
1 endurecida para que la interacción web sea fiable:

- cdp_wait_actionable: visible + stable (2 rAF) + enabled + hit-test (elementFromPoint
  cruzando shadow DOM) + retry backoff + scroll cycling. Devuelve el punto validado.
  Réplica de _retryAction/_checkElementIsStable/expectHitTarget de Playwright.
- cdp_select_dropdown: desplegables custom (combobox/MUI/select2/headlessui): click real
  en trigger -> espera apertura (aria-expanded/[role=option] visible) -> click real en
  la opción. Resuelve el fallo nº1: clicar antes de que monte el listbox.
- cdp_select_option (endurecida v1.1.0): valida <select> real, match value/label
  normalizado/índice, option.selected para multiple, eventos input{composed}+change.
- cdp_fill: escribir fiable en inputs React/Vue: focus -> select-all -> Input.insertText
  (sin native value setter, como Playwright); native setter solo para inputs especiales.
- cdp_find_by_role: localizar por rol ARIA + accessible name (estilo getByRole),
  reutilizando el AX tree de cdp_get_ax_outline.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 20:49:37 +02:00

5.6 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
cdp_select_dropdown function go browser 1.0.0 impure func CdpSelectDropdown(c *CDPConn, triggerSelector string, optionText string, opts CdpDropdownOpts) error Selecciona una opcion en un DESPLEGABLE CUSTOM (combobox/listbox ARIA, react-select, MUI Select, headlessui, select2) — esos donde un <select> nativo NO aplica. Replica el patron de Playwright (que no tiene API para custom dropdowns): click REAL en el trigger (mousedown, no element.click JS), espera la apertura por polling (aria-expanded=true O [role=listbox]/[role=menu] visible O opciones con rect>0), localiza la opcion por texto normalizado (substring o exacto, case-insensitive) y hace click REAL en su centro, con verificacion suave (aria-expanded vuelve a false o Enter como fallback). Reusa CdpEvaluate, CdpClickXYHuman y CdpPressKey.
browser
chrome
cdp
automation
dropdown
combobox
listbox
aria
select
react-select
mui
headlessui
devtools
cdp_evaluate_go_browser
cdp_click_xy_human_go_browser
cdp_press_key_go_browser
false error_go_core
fmt
strings
time
name desc
c conexion CDP activa (*CDPConn)
name desc
triggerSelector selector CSS del elemento que abre el desplegable (el boton/combobox sobre el que se hace click real)
name desc
optionText texto visible de la opcion a elegir; se normaliza (trim + colapsar espacios) y se compara case-insensitive, por substring si opts.Exact=false o por igualdad si opts.Exact=true
name desc
opts CdpDropdownOpts{Exact bool (igualdad vs substring, default substring); TimeoutMs int (espera apertura+opcion, default 3000); OptionRole string (rol ARIA de las opciones, default 'option' — usar 'menuitem' para menus, 'treeitem' para arboles)}
error si el trigger no existe, si el dropdown no abre dentro del timeout ("el dropdown no abrio"), o si la opcion no aparece ("option %q not found in dropdown"); nil si el click sobre la opcion se realizo (la verificacion de cierre es suave y no falla duro si queda ambigua) false
functions/browser/cdp_select_dropdown.go

Ejemplo

conn, _ := CdpConnect(9222)
CdpNavigate(conn, "https://mui.com/material-ui/react-select/")

// Combobox MUI: el trigger es el div con role=combobox; el listbox monta y
// anima al abrir. CdpSelectDropdown clica el trigger, espera a que el listbox
// este visible y entonces clica la opcion "Twenty".
err := CdpSelectDropdown(conn, "[role=combobox]", "Twenty", CdpDropdownOpts{})
if err != nil {
    log.Fatal(err)
}

// react-select / headlessui: trigger por clase + match exacto + timeout amplio
// para listas que tardan en montar.
err = CdpSelectDropdown(conn, ".select__control", "España", CdpDropdownOpts{
    Exact:     true,
    TimeoutMs: 6000,
})

// Menu tipo dropdown-menu (no listbox): las opciones son role=menuitem.
err = CdpSelectDropdown(conn, "#user-menu-btn", "Cerrar sesion", CdpDropdownOpts{
    OptionRole: "menuitem",
})

Cuando usarla

Usala cuando el desplegable NO es un <select> nativo: comboboxes/listboxes ARIA, react-select, MUI Select, headlessui, select2, Ant Design, o cualquier menu hecho con <div>/<li> + JS donde elegir = clicar el trigger y luego clicar la opcion del menu desplegado. Es el equivalente al patron de Playwright click(trigger) -> getByRole('option', {name}) -> click(option), con la espera de apertura ya resuelta. Para un <select> nativo de HTML usa CdpSelectOption (setea select.value + dispara input/change), que es mas robusto y directo para ese caso.

Gotchas

  • Click real, no element.click(): muchos dropdowns custom escuchan mousedown (no click), por eso esta funcion despacha eventos de raton reales sobre el centro del bbox. Solo cae a element.click() JS si el nodo no tiene geometria.
  • Animaciones de apertura: el fallo nº1 reportado en Playwright es clicar la opcion ANTES de que el listbox monte/anime. Por eso hay polling de apertura (dropdownWaitOpen) que no avanza hasta que hay opciones visibles. Si tu dropdown anima muy lento, sube TimeoutMs.
  • Listas virtualizadas (react-window, virtuoso): solo renderizan las opciones en viewport. Si la opcion buscada esta fuera del scroll inicial, puede que nunca se monte y la funcion devuelva "not found" aunque exista. Mitigacion: escribe en el combobox para filtrar (CdpTypeText) antes de llamar a esta funcion, o haz scroll dentro del listbox primero.
  • Trigger vs contenedor: triggerSelector debe apuntar al elemento que ABRE el menu (el boton/combobox), no al [role=listbox] (que no existe hasta abrir).
  • Match de texto: normaliza espacios y es case-insensitive; por defecto es substring (Exact=false). Si varias opciones comparten substring, elige la primera visible en orden de documento — usa Exact=true para desambiguar.
  • OptionRole: por defecto option ([role=option]). Para menus de acciones usa menuitem; para arboles treeitem. La deteccion de apertura tambien considera [role=menu] y li[role] para cubrir patrones comunes.
  • Verificacion suave: tras clicar, si el dropdown sigue abierto la funcion pulsa Enter como fallback y devuelve nil. No falla duro si la seleccion no se puede confirmar inequivocamente pero el click se hizo — comprueba el estado resultante (texto del trigger, valor del formulario) si necesitas certeza.
  • iframes: opera en el documento principal (via CdpEvaluate). Para un dropdown dentro de un iframe necesitarias el contexto del frame (no cubierto aqui).