Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.6 KiB
id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
| id | title | status | type | domain | scope | priority | depends | blocks | related | created | updated | tags | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 56 | Funciones globales del registry para control de navegador (find by text, click by text, scroll, HAR, jsonld, opengraph, ...) | pendiente | epic |
|
cross-stack | media | 2026-05-09 | 2026-05-17 |
Contexto
functions/browser/ (Go) tiene hoy 12 primitivas CDP de bajo nivel: cdp_connect, cdp_navigate, cdp_evaluate, cdp_get_html, cdp_screenshot, cdp_click (por selector CSS), cdp_type_text, cdp_wait_load, cdp_wait_element, cdp_set_cookie, cdp_close, chrome_launch. Todas reutilizables, todas testeadas.
Estas primitivas son suficientes para muchos casos pero siguen siendo bajo nivel: el consumidor (cdp-cli, navegator_dashboard, agentes) tiene que componer manualmente patrones que se repiten una y otra vez. Falta una capa intermedia de funciones de mas alto nivel que resuelvan tareas reales sin que cada caller las re-componga.
Objetivo
Ampliar functions/browser/ (Go preferentemente, Python cuando aplique) con primitivas componibles que resuelvan los patrones recurrentes:
- Localizacion robusta de elementos: por texto visible, por XPath, por aria-label.
- Acciones combinadas: click por texto, fill form, submit, scroll-to, wait-navigation.
- Captura estructurada: HAR, jsonld, opengraph, meta tags, schema.org.
- Navegacion segura: navegacion + wait + retry + screenshot diff.
- Multi-tab / multi-instance: enumerar tabs de N instancias, copiar cookie entre profiles.
Cualquier app del registry que controle browsers (navegator_dashboard, cdp-cli, graph_explorer, futuras) consume esta capa en vez de reimplementar.
Funciones propuestas (lista inicial)
Todas en functions/browser/. Lenguaje preferido entre parentesis. Pureza siempre impure (todas tocan red/IO).
Localizacion / queries
| ID | Que hace |
|---|---|
cdp_find_by_text_go_browser |
Devuelve selector CSS unico del primer elemento cuyo innerText contiene un texto dado. Filtros: tag, case_sensitive, exact. |
cdp_find_all_by_text_go_browser |
Como el anterior pero retorna lista de selectores. |
cdp_find_by_xpath_go_browser |
Equivalente con XPath. |
cdp_find_by_aria_go_browser |
Por aria-label o role. Util en SPAs accesibles. |
cdp_get_attribute_go_browser |
<selector>.getAttribute(name). |
cdp_count_elements_go_browser |
document.querySelectorAll(sel).length. |
Acciones
| ID | Que hace |
|---|---|
cdp_click_text_go_browser |
find_by_text + click. Errores claros si no encuentra. |
cdp_fill_form_go_browser |
Recibe map[selector]value, hace click + type por cada uno. |
cdp_submit_form_go_browser |
Click en boton submit + wait_navigation. |
cdp_scroll_to_go_browser |
selector.scrollIntoView({block:'center'}) + verifica que esta en viewport. |
cdp_press_key_go_browser |
Input.dispatchKeyEvent con tecla nombrada (Enter, Tab, Escape, ArrowDown). |
cdp_hover_go_browser |
Input.dispatchMouseEvent mouseMoved sobre el elemento. |
Esperas robustas
| ID | Que hace |
|---|---|
cdp_wait_navigation_go_browser |
Espera Page.frameNavigated + Page.loadEventFired con timeout. |
cdp_wait_text_go_browser |
Espera a que aparezca un texto en cualquier sitio del DOM. |
cdp_wait_url_go_browser |
Espera a que location.href matchee un regex. |
cdp_wait_idle_go_browser |
Espera a que la red este idle N ms (Network.* events). |
Captura estructurada
| ID | Que hace |
|---|---|
cdp_har_record_go_browser |
Subscribe Network.* durante una accion, retorna HAR JSON estandar. |
extract_jsonld_py_browser |
Parse <script type="application/ld+json"> del HTML. |
extract_opengraph_py_browser |
Parse <meta property="og:*">. |
extract_meta_basic_py_browser |
Title, description, canonical, lang, charset. |
extract_schema_org_py_browser |
Microdata itemtype="https://schema.org/...". |
extract_forms_py_browser |
Lista forms del HTML con campos, action, method. |
cdp_dump_cookies_go_browser |
Network.getAllCookies → JSON. |
cdp_screenshot_element_go_browser |
Screenshot recortado al bounding box del selector. |
Multi-tab / multi-instance
| ID | Que hace |
|---|---|
cdp_list_tabs_go_browser |
GET /json → lista parseada de tabs. |
cdp_focus_tab_go_browser |
POST /json/activate/{id}. |
cdp_close_tab_go_browser |
POST /json/close/{id}. |
cdp_new_tab_go_browser |
POST /json/new?url=.... |
cdp_copy_cookies_go_browser |
Lee cookies de un profile, las pone en otro (ambos via CDP). |
Composiciones (pipelines)
| ID | Que hace |
|---|---|
browser_login_form_pipeline |
navigate + wait + fill_form + submit + wait_navigation + dump_cookies. Util para pre-logins en perfiles aislados. |
browser_screenshot_diff_pipeline |
navigate + screenshot + comparar contra golden + reportar. |
crawl_seeded_pipeline |
navigate seeds + extract links + push a queue + dedup + extract elegido. |
Criterios de calidad para añadir una funcion
Antes de delegar a fn-constructor:
- Patron real recurrente, no especulativo. Si solo lo usa un caller hoy, esperar.
- API simple: max 5 parametros con valores por defecto sensatos.
- Tests obligatorios contra Chrome local (env-gated, no CI default — ver
cdp_*_test.goactuales). - Documentacion
.mdcon ejemplo invocacion + caso de uso real (que app/agente la consume). - Sin estado global: cada llamada recibe
*CDPConn, no asume singleton.
Estrategia de adopcion
Por demanda, no anticipado:
- Cuando una capa del dashboard (navegator/0001) o un enricher de graph_explorer requiera componer un patron, primero buscar si ya existe en el registry.
- Si no existe y se usa dos veces o aparece en TODO, abrir sub-issue de este 0070 con la firma propuesta.
- Delegar a
fn-constructorcon los criterios de arriba. - Migrar a la nueva funcion el caller que la pidio + cualquier otro que estuviera reimplementando lo mismo.
No precrear todas a la vez — riesgo de funciones zombies que nadie usa.
Sub-issues iniciales (los que el dashboard v2 va a pedir)
0070a—cdp_find_by_text_go_browser+cdp_click_text_go_browser. Bloquea Tab Detail y Recipes.0070b—cdp_har_record_go_browser. Bloquea Network panel.0070c—extract_jsonld_py_browser+extract_opengraph_py_browser. Bloquea/extract/structured.0070d—cdp_list_tabs_go_browser+cdp_new_tab_go_browser. Bloquea Tabs panel del dashboard.
Resto se abren cuando se necesiten.
Relacion con cdp-cli
Cuando una funcion nueva se añade al registry, cdp-cli (projects/osint_graph/apps/graph_explorer/cdp-cli/) gana un subcomando que la envuelve. Asi tanto el dashboard (in-process) como agentes/scripts (subprocess) tienen acceso. Patron ya establecido con las 10 funciones actuales.
Riesgos
| Riesgo | Mitigacion |
|---|---|
| Funciones zombies si las pre-creamos | Solo crear cuando hay 2 callers o demanda real. |
| Fragmentacion: tener 50 funciones de queries similares | Revision de overlap antes de delegar a fn-constructor. Preferir parametros sobre nuevas funciones. |
| Tests dependen de Chrome local — flakiness en CI | Tag slow + env-gate. CI nocturno opcional. |
| Diferencias entre Chrome versions (selectores cambian, eventos rebrandean) | Tests cubren la API CDP estable, no el DOM de sitios externos. |
Definicion de hecho
Cuando navegator_dashboard v3 cierre, las funciones invocadas por sus endpoints /extract/*, /crawl, panel Network, panel Tabs y panel Tab Detail viven todas en functions/browser/ o python/functions/browser/ (segun lenguaje), no inline en el dashboard. El dashboard es 100% orquestador.