Files
fn_registry/functions/browser/cdp_select_option.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.7 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_option function go browser 1.1.0 impure func CdpSelectOption(c *CDPConn, selector string, value string) error Selecciona una <option> de un <select> nativo (localizado por selector CSS) replicando la semantica de Playwright (injectedScript.selectOptions). Match por value exacto, luego label/texto exacto, luego label normalizado (whitespace-collapse + strip zero-width/soft-hyphen), luego substring normalizado, y por ultimo indice si value es entero. Setea option.selected (soporta <select multiple>), hace focus, y despacha 'input' {bubbles,composed} + 'change' {bubbles}. Valida que el elemento sea <select> (error claro si no) y sigue <label for>. Via Runtime.evaluate, reusa CdpEvaluate.
chrome
cdp
browser
automation
select
dropdown
form
dom
devtools
cdp_evaluate_go_browser
false error_go_core
fmt
strings
name desc
c conexión CDP activa
name desc
selector selector CSS del elemento <select> a modificar
name desc
value criterio de seleccion. Se prueba en orden: value exacto → label/texto exacto → label normalizado (whitespace-collapse + strip U+200B/U+00AD) → label por substring normalizado → indice (si value es un entero)
error si el selector no encuentra elemento ("element not found"), si el elemento no es un <select> ("element is not a <select> ..."), o si ninguna option coincide ("option not found in <select>"); nil si la selección y los eventos se despacharon correctamente false
functions/browser/cdp_select_option.go

Ejemplo

conn, _ := CdpConnect(9222)
CdpNavigate(conn, "https://example.com/form")

// Seleccionar por value
if err := CdpSelectOption(conn, "#country", "ES"); err != nil {
    log.Fatal(err)
}

// Seleccionar por texto visible cuando no se conoce el value interno
if err := CdpSelectOption(conn, "select[name=lang]", "Español"); err != nil {
    log.Fatal(err)
}

// Seleccionar por indice (3a opcion) cuando ni value ni texto son estables
if err := CdpSelectOption(conn, "#size", "2"); err != nil { // index 2 = 3a option
    log.Fatal(err)
}

Cuando usarla

Usala cuando necesites elegir una opcion de un <select> nativo en un formulario web y quieras que un framework (React, Vue, Angular) reaccione al cambio. Es la forma robusta de rellenar dropdowns durante automatizacion/scraping: a diferencia de un click sobre la option, setea option.selected y dispara input+change, que es lo que los frameworks escuchan. Combinala con CdpClick para enviar el formulario despues. Si no conoces el value interno, pasa el texto visible (se normaliza el whitespace) o el indice numerico de la option.

Gotchas

  • Solo <select> nativos. Si el elemento no es un <select> retorna error claro element is not a <select> .... Dropdowns custom hechos con <div> + JS (react-select, headlessui, Radix, etc.) NO son <select> reales: para esos usa cdp_select_dropdown (cuando exista) o clica el trigger con CdpClickRef y luego la opcion del menu desplegado (CdpFindRefByText + CdpClickRef). NO uses esta funcion para ellos.
  • Orden de matching del value recibido (se prueba en este orden y para en el primer match):
    1. option.value exacto (===).
    2. option.label / textContent exacto (sin normalizar).
    3. label/texto NORMALIZADO exacto: se quita zero-width space (U+200B) y soft hyphen (U+00AD), se hace trim, y se colapsa cualquier whitespace (\s+) a un solo espacio — igual que normalizeWhiteSpace de Playwright.
    4. label/texto por SUBSTRING normalizado (primera option cuyo label normalizado contenga el value normalizado). Util para etiquetas largas; cuidado con ambiguedad (gana la primera en orden de documento).
    5. fallback por INDICE: solo si value es un entero >= 0 valido ("2" → 3a option). Por eso un value que casualmente sea numerico puede caer aqui si no hubo ningun match textual antes — preferi el value real cuando exista. El matching es case-sensitive en todos los pasos (no se hace lowercase).
  • <select multiple> soportado: setea option.selected = true sobre la option encontrada sin tocar el resto de selecciones. En un <select> simple deselecciona las demas antes de marcar la elegida. (La version 1.0.0 solo seteaba select.value y reseteaba el multiple — corregido.)
  • Eventos: dispara input con {bubbles:true, composed:true} (el composed permite cruzar shadow DOM, p.ej. web components que envuelven el <select>) y luego change con {bubbles:true}, en ese orden. Hace focus() del select antes.
  • No hace scroll ni verifica visibilidad/enabled: opera sobre el DOM directamente. Si el <select> o la <option> estan disabled, la seleccion se aplica igual pero la UI puede ignorarla segun el framework (Playwright aqui devolveria optionnotenabled; esta funcion no chequea enabled — mantiene KISS).
  • Si el elemento aun no existe (carga dinamica), retorna element not found sin esperar — combinar con CdpWaitElement para elementos diferidos.

Capability growth log

  • v1.1.0 (2026-06-16) — alineada con Playwright injectedScript.selectOptions: valida que el elemento sea <select> (error claro si no, apuntando a dropdowns custom), sigue <label for>, matching multi-criterio (value → label exacto → label normalizado whitespace-collapse → substring → indice), usa option.selected en vez de solo select.value (soporta <select multiple>), añade composed:true al evento input (cruza shadow DOM) y focus() previo. Firma intacta (no rompe el caller del MCP dom_select_option).