4187f9b6b1
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>
5.7 KiB
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. |
|
|
false | error_go_core |
|
|
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 claroelement is not a <select> .... Dropdowns custom hechos con<div>+ JS (react-select, headlessui, Radix, etc.) NO son<select>reales: para esos usacdp_select_dropdown(cuando exista) o clica el trigger conCdpClickRefy luego la opcion del menu desplegado (CdpFindRefByText+CdpClickRef). NO uses esta funcion para ellos. - Orden de matching del
valuerecibido (se prueba en este orden y para en el primer match):option.valueexacto (===).option.label/textContentexacto (sin normalizar).- 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 quenormalizeWhiteSpacede Playwright. - 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).
- fallback por INDICE: solo si
valuees un entero>= 0valido ("2"→ 3a option). Por eso unvalueque casualmente sea numerico puede caer aqui si no hubo ningun match textual antes — preferi elvaluereal cuando exista. El matching es case-sensitive en todos los pasos (no se hace lowercase).
<select multiple>soportado: seteaoption.selected = truesobre 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 seteabaselect.valuey reseteaba el multiple — corregido.)- Eventos: dispara
inputcon{bubbles:true, composed:true}(elcomposedpermite cruzar shadow DOM, p.ej. web components que envuelven el<select>) y luegochangecon{bubbles:true}, en ese orden. Hacefocus()del select antes. - No hace scroll ni verifica visibilidad/enabled: opera sobre el DOM directamente.
Si el
<select>o la<option>estandisabled, la seleccion se aplica igual pero la UI puede ignorarla segun el framework (Playwright aqui devolveriaoptionnotenabled; esta funcion no chequea enabled — mantiene KISS). - Si el elemento aun no existe (carga dinamica), retorna
element not foundsin esperar — combinar conCdpWaitElementpara 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), usaoption.selecteden vez de soloselect.value(soporta<select multiple>), añadecomposed:trueal eventoinput(cruza shadow DOM) yfocus()previo. Firma intacta (no rompe el caller del MCPdom_select_option).