chore: auto-commit (13 archivos)
- CAPABILITIES_TODO.md - demo_e2e/RESUMEN.md - demo_e2e/results/prueba_1_quotes.json - demo_e2e/results/prueba_2_perceive.json - demo_e2e/results/prueba_3_search.json - demo_e2e/results/prueba_4_login_session.json - demo_e2e/results/prueba_5_books.json - demo_e2e/results/prueba_6_session_storage.json - demo_e2e/results/prueba_7_find_honesto.json - demo_e2e/results/prueba_8_verificacion.json - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+23
-2
@@ -15,9 +15,9 @@ de simples a complejas. No "compila", sino "funciona".
|
||||
mensajes de golpe falló por una race: el servidor procesa requests de forma concurrente.
|
||||
- **Runner**: `run_demo.py` — ejecuta las 5 pruebas, guarda pasos/respuestas/veredicto en `results/`.
|
||||
|
||||
## Resultado: 8/8 PASS (headless y con ventana visible)
|
||||
## Resultado: 9/9 PASS (headless y con ventana visible)
|
||||
|
||||
Las pruebas 1-5 son la batería inicial; 6-8 se añadieron para validar las tandas de fixes (A/D/E y B).
|
||||
Las pruebas 1-5 son la batería inicial; 6-9 se añadieron para validar las tandas de fixes (A/D/E, B, y gap #1).
|
||||
|
||||
| # | Prueba | Sitio sandbox | Capacidades ejercitadas | Resultado |
|
||||
|---|---|---|---|---|
|
||||
@@ -29,6 +29,7 @@ Las pruebas 1-5 son la batería inicial; 6-8 se añadieron para validar las tand
|
||||
| 6 | sessionStorage en storage_state | the-internet.herokuapp.com | set→save→clear→load→get | PASS — `clear=null`, `restore=demo_v` (fix D) |
|
||||
| 7 | `find_by_text` honesto | quotes.toscrape.com | dom_find_by_text presente vs inexistente | PASS — texto inexistente devuelve error, no vacío (fix E) |
|
||||
| 8 | Verificación post-acción | quotes.toscrape.com | dom_click sobre oculto / dom_type sin foco | PASS — ambos devuelven error en vez de actuar al vacío (fix B) |
|
||||
| 9 | Bucle percibir→actuar por `#ref` | the-internet.herokuapp.com/login | page_perceive → dom_type_ref/dom_click_ref + auto-observe | PASS — login solo por `#ref` (sin selector); cada acción devuelve el outline nuevo (gap #1) |
|
||||
|
||||
Cobertura conjunta: lanzar/atar navegador, navegar, esperar carga, evaluar JS con JSON real, percibir
|
||||
(AX outline), leer texto, teclado, formularios, cookies, estado de sesión, y composición multi-página.
|
||||
@@ -69,6 +70,26 @@ Tras la primera batería se atacaron tres deudas, cada una validada:
|
||||
encontraba (el caller creía que había encontrado algo). Ahora devuelve error explícito. Validado por la
|
||||
prueba 7.
|
||||
|
||||
## Gap #1 — bucle percibir→actuar por `#ref` (lo que cierra el loop del agente)
|
||||
|
||||
El cambio que más sube el nivel del agente. Un solo cambio resolvió tres cosas a la vez:
|
||||
|
||||
- **`#ref` = `backendDOMNodeId`** (no el `nodeId` efímero del AX tree). `render_ax_outline` ahora emite el id
|
||||
del nodo DOM real, estable mientras el nodo viva → el `#ref` que el LLM lee sigue válido cuando actúa un
|
||||
instante después. Resuelve "ref→acción" y "refs estables" de golpe, **sin mantener mapa de estado** en el MCP.
|
||||
- **Funciones por ref** (`cdp_click_ref`, `cdp_type_ref`, `cdp_hover_ref`): resuelven `backendDOMNodeId` →
|
||||
bbox (`DOM.getBoxModel`) → centro → acción humanizada.
|
||||
- **Primitivo único `cdp_click_xy_human`**: click humanizado por coordenadas, compartido por las tres vías
|
||||
(selector, `#ref`, y futura visión OCR/YOLO). `cdp_click_human` se refactorizó para usarlo (un solo camino).
|
||||
- **Auto-observe**: cada tool `_ref` del MCP devuelve el outline AX actualizado tras la acción → el LLM ve el
|
||||
efecto sin pedir otra lectura = verificación implícita (como Playwright MCP).
|
||||
- **Defectos de calidad de `render_ax_outline` corregidos** en la misma edición: guard de ciclo + límite de
|
||||
profundidad (evita `RecursionError`), se quitó el `ljust(60)` (gastaba tokens en relleno), y ahora renderiza
|
||||
el `value` de los inputs (texto escrito, estado).
|
||||
|
||||
Validado por la prueba 9: login completo en the-internet **actuando solo por `#ref`** (sin un solo selector CSS).
|
||||
Pendiente de esta familia: política de humanización por sesión (`human`/`fast`/`instant`) para scraping masivo.
|
||||
|
||||
## Tercera tanda de fix (B) — verificación post-acción
|
||||
|
||||
- **B — fin del "fire-and-forget"** (`cdp_click.go`, `cdp_type_text.go`). `cdp_click` ahora verifica que
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://quotes.toscrape.com"
|
||||
},
|
||||
"ms": 735,
|
||||
"ms": 113,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://quotes.toscrape.com"
|
||||
},
|
||||
@@ -50,7 +50,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 437,
|
||||
"ms": 235,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -60,7 +60,7 @@
|
||||
"port": 9333,
|
||||
"expression": "[...document.querySelectorAll('.quote')].map(q=>({text:q.querySelector('.text').innerText,author:q.querySelector('.author').innerText,tags:[...q.querySelectorAll('.tag')].map(t=>t.innerText)}))"
|
||||
},
|
||||
"ms": 2,
|
||||
"ms": 6,
|
||||
"is_error": false,
|
||||
"response": "[{\"author\":\"Albert Einstein\",\"tags\":[\"change\",\"deep-thoughts\",\"thinking\",\"world\"],\"text\":\"“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”\"},{\"author\":\"J.K. Rowling\",\"tags\":[\"abilities\",\"choices\"],\"text\":\"“It is our choices, Harry, that show what we truly are, far more than our abilities.”\"},{\"author\":\"Albert Einstein\",\"tags\":[\"inspirational\",\"life\",\"live\",\"miracle\",\"miracles\"],\"text\":\"“There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”\"},{\"author\":\"Jane Austen\",\"tags\":[\"aliteracy\",\"books\",\"classic\",\"humor\"],\"text\":\"“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”\"},{\"author\":\"Marilyn Monroe\",\"tags\":[\"be-yourself\",\"inspirational\"],\"text\":\"“Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.”\"},{\"author\":\"Albert Einstein\",\"tags\":[\"adulthood\",\"success\",\"value\"],\"text\":\"“Try not to become a man of success. Rather become a man of value.”\"},{\"author\":\"André Gide\",\"tags\":[\"life\",\"love\"],\"text\":\"“It is better to be hated for what you are than to be loved for what you are not.”\"},{\"author\":\"Thomas A. Edison\",\"tags\":[\"edison\",\"failure\",\"inspirational\",\"paraphrased\"],\"text\":\"“I have not failed. I've just found 10,000 ways that won't work.”\"},{\"author\":\"Eleanor Roosevelt\",\"tags\":[\"misattributed-eleanor-roosevelt\"],\"text\":\"“A woman is like a tea bag; you never know how strong it is until it's in hot water.”\"},{\"author\":\"Steve Martin\",\"tags\":[\"humor\",\"obvious\",\"simile\"],\"text\":\"“A day without sunshine is like, you know, night.”\"}]"
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"verdict": "PASS",
|
||||
"has_refs": true,
|
||||
"has_link": true,
|
||||
"outline_len": 4021,
|
||||
"outline_preview": "RootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=169\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\nlink \"Fork me on GitHub\" #ref=72\n image \"Fork me on GitHub\"\ngeneric\n heading \"Welcome to the-internet\"\n StaticText \"Welcome to the-internet\"\n InlineTextBox \"Welcome to the-internet\"\n heading \"Available Examples\"\n StaticText \"Available Examples\"\n InlineTextBox \"Available Examples\"\n list\n listitem\n link \"A/B Testing\" #ref=79\n StaticText \"A/B Testing\"\n InlineTextBox \"A/B Testing\"\n listitem\n link \"Add/Remove Elements\" #ref=81\n StaticText \"Add/Remove Elements\"\n InlineTextBox \"Add/Remove Elements\"\n listitem\n link \"Basic Auth\" #ref=83\n StaticText \"Basic Auth\"\n InlineTextBox \"Basic Auth\"\n StaticText \" (user and pass: admin)\"\n InlineTextBox \" (user and pass: admin)\"\n listitem\n link \"Broken Images\" #ref=85\n StaticText \"Broken Images\"\n InlineTextBox \"Broken Images\"\n listitem\n link \"Challenging DOM\" #ref=87\n StaticText \"Challenging DOM\"\n ",
|
||||
"outline_len": 4017,
|
||||
"outline_preview": "RootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=169\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\nlink \"Fork me on GitHub\" #ref=74\n image \"Fork me on GitHub\"\ngeneric\n heading \"Welcome to the-internet\"\n StaticText \"Welcome to the-internet\"\n InlineTextBox \"Welcome to the-internet\"\n heading \"Available Examples\"\n StaticText \"Available Examples\"\n InlineTextBox \"Available Examples\"\n list\n listitem\n link \"A/B Testing\" #ref=81\n StaticText \"A/B Testing\"\n InlineTextBox \"A/B Testing\"\n listitem\n link \"Add/Remove Elements\" #ref=83\n StaticText \"Add/Remove Elements\"\n InlineTextBox \"Add/Remove Elements\"\n listitem\n link \"Basic Auth\" #ref=84\n StaticText \"Basic Auth\"\n InlineTextBox \"Basic Auth\"\n StaticText \" (user and pass: admin)\"\n InlineTextBox \" (user and pass: admin)\"\n listitem\n link \"Broken Images\" #ref=86\n StaticText \"Broken Images\"\n InlineTextBox \"Broken Images\"\n listitem\n link \"Challenging DOM\" #ref=88\n StaticText \"Challenging DOM\"\n InlineTextBox \"Challenging DOM\"\n listitem\n link \"Checkboxes\" #ref=90\n StaticText \"Checkboxes\"\n InlineTextBox \"Checkboxes\"\n listitem\n link \"Context Menu\" #ref=92\n StaticTex",
|
||||
"steps": [
|
||||
{
|
||||
"tool": "tab_navigate",
|
||||
@@ -12,7 +12,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://the-internet.herokuapp.com"
|
||||
},
|
||||
"ms": 388,
|
||||
"ms": 404,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://the-internet.herokuapp.com"
|
||||
},
|
||||
@@ -22,7 +22,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 833,
|
||||
"ms": 241,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -32,9 +32,9 @@
|
||||
"port": 9333,
|
||||
"max_chars": 4000
|
||||
},
|
||||
"ms": 125,
|
||||
"ms": 103,
|
||||
"is_error": false,
|
||||
"response": "RootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=169\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\nlink \"Fork me on GitHub\" #ref=72\n image \"Fork me on GitHub\"\ngeneric\n heading \"Welcome to the-internet\"\n StaticText \"Welcome to the-internet\"\n InlineTextBox \"Welcome to the-internet\"\n heading \"Available Examples\"\n StaticText \"Available Examples\"\n InlineTextBox \"Available Examples\"\n list\n listitem\n link \"A/B Testing\" #ref=79\n StaticText \"A/B Testing\"\n InlineTextBox \"A/B Testing\"\n listitem\n link \"Add/Remove Elements\" #ref=81\n StaticText \"Add/Remove Elements\"\n InlineTextBox \"Add/Remove Elements\"\n listitem\n link \"Basic Auth\" #ref=83\n StaticText \"Basic Auth\"\n InlineTextBox \"Basic Auth\"\n StaticText \" (user and pass: admin)\"\n InlineTextBox \" (user and pass: admin)\"\n listitem\n link \"Broken Images\" #ref=85\n StaticText \"Broken Images\"\n InlineTextBox \"Broken Images\"\n listitem\n link \"Challenging DOM\" #ref=87\n StaticText \"Challenging DOM\"\n InlineTextBox \"Challenging DOM\"\n listitem\n link \"Checkboxes\" #ref=89\n StaticText \"Checkboxes\"\n InlineTextBox \"Checkboxes\"\n listitem\n link \"Context Menu\" #ref=91\n StaticText \"Context Menu\"\n InlineTextBox \"Context Menu\"\n listitem\n link \"Digest Authentication\" #ref=93\n StaticText \"Digest Authentication\"\n InlineTextBox \"Digest Au"
|
||||
"response": "RootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=169\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\nlink \"Fork me on GitHub\" #ref=74\n image \"Fork me on GitHub\"\ngeneric\n heading \"Welcome to the-internet\"\n StaticText \"Welcome to the-internet\"\n InlineTextBox \"Welcome to the-internet\"\n heading \"Available Examples\"\n StaticText \"Available Examples\"\n InlineTextBox \"Available Examples\"\n list\n listitem\n link \"A/B Testing\" #ref=81\n StaticText \"A/B Testing\"\n InlineTextBox \"A/B Testing\"\n listitem\n link \"Add/Remove Elements\" #ref=83\n StaticText \"Add/Remove Elements\"\n InlineTextBox \"Add/Remove Elements\"\n listitem\n link \"Basic Auth\" #ref=84\n StaticText \"Basic Auth\"\n InlineTextBox \"Basic Auth\"\n StaticText \" (user and pass: admin)\"\n InlineTextBox \" (user and pass: admin)\"\n listitem\n link \"Broken Images\" #ref=86\n StaticText \"Broken Images\"\n InlineTextBox \"Broken Images\"\n listitem\n link \"Challenging DOM\" #ref=88\n StaticText \"Challenging DOM\"\n InlineTextBox \"Challenging DOM\"\n listitem\n link \"Checkboxes\" #ref=90\n StaticText \"Checkboxes\"\n InlineTextBox \"Checkboxes\"\n listitem\n link \"Context Menu\" #ref=92\n StaticText \"Context Menu\"\n InlineTextBox \"Context Menu\"\n listitem\n link \"Digest Authentication\" #ref=94\n StaticText \"Digest Authentication\"\n InlineTextBox \"Digest Authentication\"\n StaticText \" (user and pass: admin)\"\n InlineTextBox \" (user and pass: admin)\"\n listitem\n link \"Disappearing Elements\" #ref=96\n StaticText \"Disappearing Elements\"\n InlineTextBox \"Disappearing Elements\"\n listitem\n link \"Drag and Drop\" #ref=97\n "
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"args": {
|
||||
"port": 9333
|
||||
},
|
||||
"ms": 1,
|
||||
"ms": 7,
|
||||
"is_error": false,
|
||||
"response": "cookies cleared"
|
||||
},
|
||||
@@ -18,7 +18,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://the-internet.herokuapp.com/login"
|
||||
},
|
||||
"ms": 91,
|
||||
"ms": 94,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://the-internet.herokuapp.com/login"
|
||||
},
|
||||
@@ -28,7 +28,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 249,
|
||||
"ms": 233,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -38,7 +38,7 @@
|
||||
"port": 9333,
|
||||
"selector": "#username"
|
||||
},
|
||||
"ms": 23,
|
||||
"ms": 17,
|
||||
"is_error": false,
|
||||
"response": "clicked #username"
|
||||
},
|
||||
@@ -48,7 +48,7 @@
|
||||
"port": 9333,
|
||||
"text": "tomsmith"
|
||||
},
|
||||
"ms": 115,
|
||||
"ms": 107,
|
||||
"is_error": false,
|
||||
"response": "typed text"
|
||||
},
|
||||
@@ -58,7 +58,7 @@
|
||||
"port": 9333,
|
||||
"selector": "#password"
|
||||
},
|
||||
"ms": 8,
|
||||
"ms": 6,
|
||||
"is_error": false,
|
||||
"response": "clicked #password"
|
||||
},
|
||||
@@ -68,7 +68,7 @@
|
||||
"port": 9333,
|
||||
"text": "SuperSecretPassword!"
|
||||
},
|
||||
"ms": 279,
|
||||
"ms": 265,
|
||||
"is_error": false,
|
||||
"response": "typed text"
|
||||
},
|
||||
@@ -78,7 +78,7 @@
|
||||
"port": 9333,
|
||||
"key": "Enter"
|
||||
},
|
||||
"ms": 4,
|
||||
"ms": 5,
|
||||
"is_error": false,
|
||||
"response": "pressed Enter"
|
||||
},
|
||||
@@ -88,7 +88,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 1,
|
||||
"ms": 2,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -99,7 +99,7 @@
|
||||
"selector": "#flash",
|
||||
"timeout_ms": 8000
|
||||
},
|
||||
"ms": 435,
|
||||
"ms": 208,
|
||||
"is_error": false,
|
||||
"response": "element appeared: #flash"
|
||||
},
|
||||
@@ -110,7 +110,7 @@
|
||||
"selector": "#flash",
|
||||
"max_bytes": 200
|
||||
},
|
||||
"ms": 2,
|
||||
"ms": 0,
|
||||
"is_error": false,
|
||||
"response": " You logged into a secure area!\n×"
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"args": {
|
||||
"port": 9333
|
||||
},
|
||||
"ms": 2,
|
||||
"ms": 1,
|
||||
"is_error": false,
|
||||
"response": "cookies cleared"
|
||||
},
|
||||
@@ -23,7 +23,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://the-internet.herokuapp.com/login"
|
||||
},
|
||||
"ms": 96,
|
||||
"ms": 86,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://the-internet.herokuapp.com/login"
|
||||
},
|
||||
@@ -33,7 +33,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 247,
|
||||
"ms": 222,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
"port": 9333,
|
||||
"selector": "#username"
|
||||
},
|
||||
"ms": 4,
|
||||
"ms": 13,
|
||||
"is_error": false,
|
||||
"response": "clicked #username"
|
||||
},
|
||||
@@ -53,7 +53,7 @@
|
||||
"port": 9333,
|
||||
"text": "tomsmith"
|
||||
},
|
||||
"ms": 93,
|
||||
"ms": 112,
|
||||
"is_error": false,
|
||||
"response": "typed text"
|
||||
},
|
||||
@@ -63,7 +63,7 @@
|
||||
"port": 9333,
|
||||
"selector": "#password"
|
||||
},
|
||||
"ms": 9,
|
||||
"ms": 5,
|
||||
"is_error": false,
|
||||
"response": "clicked #password"
|
||||
},
|
||||
@@ -73,7 +73,7 @@
|
||||
"port": 9333,
|
||||
"text": "SuperSecretPassword!"
|
||||
},
|
||||
"ms": 290,
|
||||
"ms": 271,
|
||||
"is_error": false,
|
||||
"response": "typed text"
|
||||
},
|
||||
@@ -83,7 +83,7 @@
|
||||
"port": 9333,
|
||||
"selector": "button[type=submit]"
|
||||
},
|
||||
"ms": 10,
|
||||
"ms": 9,
|
||||
"is_error": false,
|
||||
"response": "clicked button[type=submit]"
|
||||
},
|
||||
@@ -115,7 +115,7 @@
|
||||
"selector": "#flash",
|
||||
"max_bytes": 300
|
||||
},
|
||||
"ms": 3,
|
||||
"ms": 1,
|
||||
"is_error": false,
|
||||
"response": " You logged into a secure area!\n×"
|
||||
},
|
||||
@@ -125,7 +125,7 @@
|
||||
"port": 9333,
|
||||
"path": "/tmp/demo_session.json"
|
||||
},
|
||||
"ms": 9,
|
||||
"ms": 4,
|
||||
"is_error": false,
|
||||
"response": "storage state saved to /tmp/demo_session.json"
|
||||
},
|
||||
@@ -134,7 +134,7 @@
|
||||
"args": {
|
||||
"port": 9333
|
||||
},
|
||||
"ms": 4,
|
||||
"ms": 1,
|
||||
"is_error": false,
|
||||
"response": "cookies cleared"
|
||||
},
|
||||
@@ -144,7 +144,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://the-internet.herokuapp.com/secure"
|
||||
},
|
||||
"ms": 195,
|
||||
"ms": 183,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://the-internet.herokuapp.com/secure"
|
||||
},
|
||||
@@ -154,7 +154,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 229,
|
||||
"ms": 231,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -165,7 +165,7 @@
|
||||
"selector": "#flash",
|
||||
"max_bytes": 300
|
||||
},
|
||||
"ms": 0,
|
||||
"ms": 1,
|
||||
"is_error": false,
|
||||
"response": " You must login to view the secure area!\n×"
|
||||
},
|
||||
@@ -175,7 +175,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://the-internet.herokuapp.com"
|
||||
},
|
||||
"ms": 92,
|
||||
"ms": 102,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://the-internet.herokuapp.com"
|
||||
},
|
||||
@@ -185,7 +185,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 241,
|
||||
"ms": 238,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -195,7 +195,7 @@
|
||||
"port": 9333,
|
||||
"path": "/tmp/demo_session.json"
|
||||
},
|
||||
"ms": 5,
|
||||
"ms": 7,
|
||||
"is_error": false,
|
||||
"response": "storage state loaded from /tmp/demo_session.json"
|
||||
},
|
||||
@@ -205,7 +205,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://the-internet.herokuapp.com/secure"
|
||||
},
|
||||
"ms": 102,
|
||||
"ms": 98,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://the-internet.herokuapp.com/secure"
|
||||
},
|
||||
@@ -215,7 +215,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 220,
|
||||
"ms": 231,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -225,7 +225,7 @@
|
||||
"port": 9333,
|
||||
"expression": "JSON.stringify({path:location.pathname,secure:document.body.innerText.includes('Secure Area')})"
|
||||
},
|
||||
"ms": 2,
|
||||
"ms": 3,
|
||||
"is_error": false,
|
||||
"response": "{\"path\":\"/secure\",\"secure\":true}"
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://books.toscrape.com/catalogue/page-1.html"
|
||||
},
|
||||
"ms": 164,
|
||||
"ms": 26,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://books.toscrape.com/catalogue/page-1.html"
|
||||
},
|
||||
@@ -37,7 +37,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 659,
|
||||
"ms": 211,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -47,7 +47,7 @@
|
||||
"port": 9333,
|
||||
"expression": "[...document.querySelectorAll('.product_pod')].map(b=>({title:b.querySelector('h3 a').getAttribute('title'),price:b.querySelector('.price_color').innerText,stock:b.querySelector('.availability').innerText.trim()}))"
|
||||
},
|
||||
"ms": 3,
|
||||
"ms": 5,
|
||||
"is_error": false,
|
||||
"response": "[{\"price\":\"£51.77\",\"stock\":\"In stock\",\"title\":\"A Light in the Attic\"},{\"price\":\"£53.74\",\"stock\":\"In stock\",\"title\":\"Tipping the Velvet\"},{\"price\":\"£50.10\",\"stock\":\"In stock\",\"title\":\"Soumission\"},{\"price\":\"£47.82\",\"stock\":\"In stock\",\"title\":\"Sharp Objects\"},{\"price\":\"£54.23\",\"stock\":\"In stock\",\"title\":\"Sapiens: A Brief History of Humankind\"},{\"price\":\"£22.65\",\"stock\":\"In stock\",\"title\":\"The Requiem Red\"},{\"price\":\"£33.34\",\"stock\":\"In stock\",\"title\":\"The Dirty Little Secrets of Getting Your Dream Job\"},{\"price\":\"£17.93\",\"stock\":\"In stock\",\"title\":\"The Coming Woman: A Novel Based on the Life of the Infamous Feminist, Victoria Woodhull\"},{\"price\":\"£22.60\",\"stock\":\"In stock\",\"title\":\"The Boys in the Boat: Nine Americans and Their Epic Quest for Gold at the 1936 Berlin Olympics\"},{\"price\":\"£52.15\",\"stock\":\"In stock\",\"title\":\"The Black Maria\"},{\"price\":\"£13.99\",\"stock\":\"In stock\",\"title\":\"Starving Hearts (Triangular Trade Trilogy, #1)\"},{\"price\":\"£20.66\",\"stock\":\"In stock\",\"title\":\"Shakespeare's Sonnets\"},{\"price\":\"£17.46\",\"stock\":\"In stock\",\"title\":\"Set Me Free\"},{\"price\":\"£52.29\",\"stock\":\"In stock\",\"title\":\"Scott Pilgrim's Precious Little Life (Scott Pilgrim #1)\"},{\"price\":\"£35.02\",\"stock\":\"In stock\",\"title\":\"Rip it Up and Start Again\"},{\"price\":\"£57.25\",\"stock\":\"In stock\",\"title\":\"Our Band Could Be Your Life: Scenes from the American Indie Underground, 1981-1991\"},{\"price\":\"£23.88\",\"stock\":\"In stock\",\"title\":\"Olio\"},{\"price\":\"£37.59\",\"stock\":\"In stock\",\"title\":\"Mesaerion: The Best Science Fiction Stories 1800-1849\"},{\"price\":\"£51.33\",\"stock\":\"In stock\",\"title\":\"Libertarianism for Beginners\"},{\"price\":\"£45.17\",\"stock\":\"In stock\",\"title\":\"It's Only the Himalayas\"}]"
|
||||
},
|
||||
@@ -57,7 +57,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://books.toscrape.com/catalogue/page-2.html"
|
||||
},
|
||||
"ms": 107,
|
||||
"ms": 22,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://books.toscrape.com/catalogue/page-2.html"
|
||||
},
|
||||
@@ -67,7 +67,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 632,
|
||||
"ms": 216,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -87,7 +87,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://books.toscrape.com/catalogue/page-3.html"
|
||||
},
|
||||
"ms": 110,
|
||||
"ms": 18,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://books.toscrape.com/catalogue/page-3.html"
|
||||
},
|
||||
@@ -97,7 +97,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 429,
|
||||
"ms": 222,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
"port": 9333,
|
||||
"expression": "[...document.querySelectorAll('.product_pod')].map(b=>({title:b.querySelector('h3 a').getAttribute('title'),price:b.querySelector('.price_color').innerText,stock:b.querySelector('.availability').innerText.trim()}))"
|
||||
},
|
||||
"ms": 4,
|
||||
"ms": 2,
|
||||
"is_error": false,
|
||||
"response": "[{\"price\":\"£57.31\",\"stock\":\"In stock\",\"title\":\"Slow States of Collapse: Poems\"},{\"price\":\"£26.41\",\"stock\":\"In stock\",\"title\":\"Reasons to Stay Alive\"},{\"price\":\"£47.61\",\"stock\":\"In stock\",\"title\":\"Private Paris (Private #10)\"},{\"price\":\"£23.11\",\"stock\":\"In stock\",\"title\":\"#HigherSelfie: Wake Up Your Life. Free Your Soul. Find Your Tribe.\"},{\"price\":\"£45.07\",\"stock\":\"In stock\",\"title\":\"Without Borders (Wanderlove #1)\"},{\"price\":\"£31.77\",\"stock\":\"In stock\",\"title\":\"When We Collided\"},{\"price\":\"£50.27\",\"stock\":\"In stock\",\"title\":\"We Love You, Charlie Freeman\"},{\"price\":\"£14.27\",\"stock\":\"In stock\",\"title\":\"Untitled Collection: Sabbath Poems 2014\"},{\"price\":\"£44.18\",\"stock\":\"In stock\",\"title\":\"Unseen City: The Majesty of Pigeons, the Discreet Charm of Snails \\u0026 Other Wonders of the Urban Wilderness\"},{\"price\":\"£18.78\",\"stock\":\"In stock\",\"title\":\"Unicorn Tracks\"},{\"price\":\"£25.52\",\"stock\":\"In stock\",\"title\":\"Unbound: How Eight Technologies Made Us Human, Transformed Society, and Brought Our World to the Brink\"},{\"price\":\"£16.28\",\"stock\":\"In stock\",\"title\":\"Tsubasa: WoRLD CHRoNiCLE 2 (Tsubasa WoRLD CHRoNiCLE #2)\"},{\"price\":\"£31.12\",\"stock\":\"In stock\",\"title\":\"Throwing Rocks at the Google Bus: How Growth Became the Enemy of Prosperity\"},{\"price\":\"£19.49\",\"stock\":\"In stock\",\"title\":\"This One Summer\"},{\"price\":\"£17.27\",\"stock\":\"In stock\",\"title\":\"Thirst\"},{\"price\":\"£19.09\",\"stock\":\"In stock\",\"title\":\"The Torch Is Passed: A Harding Family Story\"},{\"price\":\"£56.13\",\"stock\":\"In stock\",\"title\":\"The Secret of Dreadwillow Carse\"},{\"price\":\"£56.41\",\"stock\":\"In stock\",\"title\":\"The Pioneer Woman Cooks: Dinnertime: Comfort Classics, Freezer Food, 16-Minute Meals, and Other Delicious Ways to Solve Supper!\"},{\"price\":\"£56.50\",\"stock\":\"In stock\",\"title\":\"The Past Never Ends\"},{\"price\":\"£45.22\",\"stock\":\"In stock\",\"title\":\"The Natural History of Us (The Fine Art of Pretending #2)\"}]"
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 224,
|
||||
"ms": 239,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -41,7 +41,7 @@
|
||||
"port": 9333,
|
||||
"path": "/tmp/demo_ss.json"
|
||||
},
|
||||
"ms": 10,
|
||||
"ms": 5,
|
||||
"is_error": false,
|
||||
"response": "storage state saved to /tmp/demo_ss.json"
|
||||
},
|
||||
@@ -51,7 +51,7 @@
|
||||
"port": 9333,
|
||||
"expression": "window.sessionStorage.clear(); 'cleared'"
|
||||
},
|
||||
"ms": 2,
|
||||
"ms": 1,
|
||||
"is_error": false,
|
||||
"response": "cleared"
|
||||
},
|
||||
@@ -71,7 +71,7 @@
|
||||
"port": 9333,
|
||||
"path": "/tmp/demo_ss.json"
|
||||
},
|
||||
"ms": 6,
|
||||
"ms": 4,
|
||||
"is_error": false,
|
||||
"response": "storage state loaded from /tmp/demo_ss.json"
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://quotes.toscrape.com"
|
||||
},
|
||||
"ms": 122,
|
||||
"ms": 117,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://quotes.toscrape.com"
|
||||
},
|
||||
@@ -21,7 +21,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 232,
|
||||
"ms": 228,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -31,7 +31,7 @@
|
||||
"port": 9333,
|
||||
"text": "Login"
|
||||
},
|
||||
"ms": 7,
|
||||
"ms": 2,
|
||||
"is_error": false,
|
||||
"response": "body > div > div:nth-of-type(1) > div:nth-of-type(2) > p > a"
|
||||
},
|
||||
@@ -41,7 +41,7 @@
|
||||
"port": 9333,
|
||||
"text": "ZZZ_texto_inexistente_42"
|
||||
},
|
||||
"ms": 5,
|
||||
"ms": 1,
|
||||
"is_error": true,
|
||||
"response": "cdp find by text: no se encontro elemento con texto \"ZZZ_texto_inexistente_42\""
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"port": 9333,
|
||||
"url": "https://quotes.toscrape.com"
|
||||
},
|
||||
"ms": 112,
|
||||
"ms": 103,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://quotes.toscrape.com"
|
||||
},
|
||||
@@ -20,7 +20,7 @@
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 212,
|
||||
"ms": 223,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
@@ -30,7 +30,7 @@
|
||||
"port": 9333,
|
||||
"expression": "var b=document.createElement('button');b.id='hidden_btn';b.textContent='x';b.style.display='none';document.body.appendChild(b);'injected'"
|
||||
},
|
||||
"ms": 2,
|
||||
"ms": 3,
|
||||
"is_error": false,
|
||||
"response": "injected"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"name": "9 - Bucle percibir->actuar por #ref + auto-observe (gap #1)",
|
||||
"verdict": "PASS",
|
||||
"refs": {
|
||||
"username": 5,
|
||||
"password": 6,
|
||||
"login": 7
|
||||
},
|
||||
"logged_in": true,
|
||||
"auto_observed": true,
|
||||
"flash": "You logged into a secure area!\n×",
|
||||
"after_observe_preview": "clicked ref 7\n\nRootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=103\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Sel",
|
||||
"steps": [
|
||||
{
|
||||
"tool": "cookie_clear",
|
||||
"args": {
|
||||
"port": 9333
|
||||
},
|
||||
"ms": 3,
|
||||
"is_error": false,
|
||||
"response": "cookies cleared"
|
||||
},
|
||||
{
|
||||
"tool": "tab_navigate",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"url": "https://the-internet.herokuapp.com/login"
|
||||
},
|
||||
"ms": 109,
|
||||
"is_error": false,
|
||||
"response": "navigated to https://the-internet.herokuapp.com/login"
|
||||
},
|
||||
{
|
||||
"tool": "page_wait_load",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 244,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
{
|
||||
"tool": "page_perceive",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"max_chars": 6000
|
||||
},
|
||||
"ms": 107,
|
||||
"is_error": false,
|
||||
"response": "RootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=51\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\nlink \"Fork me on GitHub\" #ref=31\n image \"Fork me on GitHub\"\ngeneric\nheading \"Login Page\"\n StaticText \"Login Page\"\n InlineTextBox \"Login Page\"\nheading \"This is where you can log into the secure area. Enter tomsmith for the username and SuperSecretPassword! for the password. If the information is wrong you should see error messages.\"\n StaticText \"This is where you can log into the secure area. Enter \"\n InlineTextBox \"This is where you can log into the secure area. Enter \"\n emphasis\n StaticText \"tomsmith\"\n InlineTextBox \"tomsmith\"\n StaticText \" for the username and \"\n InlineTextBox \" for the \"\n InlineTextBox \"username and \"\n emphasis\n StaticText \"SuperSecretPassword!\"\n InlineTextBox \"SuperSecretPassword!\"\n StaticText \" for the password. If the information is wrong you should see error messages.\"\n InlineTextBox \" for the password. If the \"\n InlineTextBox \"information is wrong you should see error messages.\"\ngeneric\n button \" Login\" #ref=7\n generic\n StaticText \" Login\"\n InlineTextBox \" Login\"\ngeneric\n LabelText\n StaticText \"Username\"\n InlineTextBox \"Username\"\n textbox \"Username\" #ref=5\ngeneric\n LabelText\n StaticText \"Password\"\n InlineTextBox \"Password\"\n textbox \"Password\" #ref=6\nStaticText \"\"\n InlineTextBox \"\"\n"
|
||||
},
|
||||
{
|
||||
"tool": "dom_type_ref",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"ref": 5,
|
||||
"text": "tomsmith"
|
||||
},
|
||||
"ms": 618,
|
||||
"is_error": false,
|
||||
"response": "typed into ref 5\n\nRootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=51\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\nlink \"Fork me on GitHub\" #ref=31\n image \"Fork me on GitHub\"\ngeneric\nheading \"Login Page\"\n StaticText \"Login Page\"\n InlineTextBox \"Login Page\"\nheading \"This is where you can log into the secure area. Enter tomsmith for the username and SuperSecretPassword! for the password. If the information is wrong you should see error messages.\"\n StaticText \"This is where you can log into the secure area. Enter \"\n InlineTextBox \"This is where you can log into the secure area. Enter \"\n emphasis\n StaticText \"tomsmith\"\n InlineTextBox \"tomsmith\"\n StaticText \" for the username and \"\n InlineTextBox \" for the \"\n InlineTextBox \"username and \"\n emphasis\n StaticText \"SuperSecretPassword!\"\n InlineTextBox \"SuperSecretPassword!\"\n StaticText \" for the password. If the information is wrong you should see error messages.\"\n InlineTextBox \" for the password. If the \"\n InlineTextBox \"information is wrong you should see error messages.\"\ngeneric\n button \" Login\" #ref=7\n generic\n StaticText \" Login\"\n InlineTextBox \" Login\"\ngeneric\n LabelText\n StaticText \"Username\"\n InlineTextBox \"Username\"\n textbox \"Username\" = 'tomsmith' #ref=5\n generic\n StaticText \"tomsmith\"\n InlineTextBox \"tomsmith\"\ngeneric\n LabelText\n StaticText \"Password\"\n InlineTextBox \"Password\"\n textbox \"Password\" #ref=6\nStaticText \"\"\n InlineTextBox \"\"\n"
|
||||
},
|
||||
{
|
||||
"tool": "dom_type_ref",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"ref": 6,
|
||||
"text": "SuperSecretPassword!"
|
||||
},
|
||||
"ms": 759,
|
||||
"is_error": false,
|
||||
"response": "typed into ref 6\n\nRootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=51\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\nlink \"Fork me on GitHub\" #ref=31\n image \"Fork me on GitHub\"\ngeneric\nheading \"Login Page\"\n StaticText \"Login Page\"\n InlineTextBox \"Login Page\"\nheading \"This is where you can log into the secure area. Enter tomsmith for the username and SuperSecretPassword! for the password. If the information is wrong you should see error messages.\"\n StaticText \"This is where you can log into the secure area. Enter \"\n InlineTextBox \"This is where you can log into the secure area. Enter \"\n emphasis\n StaticText \"tomsmith\"\n InlineTextBox \"tomsmith\"\n StaticText \" for the username and \"\n InlineTextBox \" for the \"\n InlineTextBox \"username and \"\n emphasis\n StaticText \"SuperSecretPassword!\"\n InlineTextBox \"SuperSecretPassword!\"\n StaticText \" for the password. If the information is wrong you should see error messages.\"\n InlineTextBox \" for the password. If the \"\n InlineTextBox \"information is wrong you should see error messages.\"\ngeneric\n button \" Login\" #ref=7\n generic\n StaticText \" Login\"\n InlineTextBox \" Login\"\ngeneric\n LabelText\n StaticText \"Username\"\n InlineTextBox \"Username\"\n textbox \"Username\" = 'tomsmith' #ref=5\n generic\n StaticText \"tomsmith\"\n InlineTextBox \"tomsmith\"\ngeneric\n LabelText\n StaticText \"Password\"\n InlineTextBox \"Password\"\n textbox \"Password\" = '••••••••••••••••••••' #ref=6\n generic\n StaticText \"••••••••••••••••••••\"\n InlineTextBox \"••••••••••••••••••••\"\nStaticText \"\"\n InlineTextBox \"\"\n"
|
||||
},
|
||||
{
|
||||
"tool": "dom_click_ref",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"ref": 7
|
||||
},
|
||||
"ms": 1562,
|
||||
"is_error": false,
|
||||
"response": "clicked ref 7\n\nRootWebArea \"The Internet\"\ngeneric\n generic\n separator\n generic\n StaticText \"Powered by \"\n InlineTextBox \"Powered by \"\n link \"Elemental Selenium\" #ref=103\n StaticText \"Elemental Selenium\"\n InlineTextBox \"Elemental \"\n InlineTextBox \"Selenium\"\ngeneric\n StaticText \" You logged into a secure area!\"\n InlineTextBox \" You logged into a secure area!\"\n link \"×\" #ref=89\n StaticText \"×\"\n InlineTextBox \"×\"\nlink \"Fork me on GitHub\" #ref=91\n image \"Fork me on GitHub\"\ngeneric\nheading \"Secure Area\"\n StaticText \"Secure Area\"\n InlineTextBox \"Secure Area\"\nheading \"Welcome to the Secure Area. When you are done click logout below.\"\n StaticText \"Welcome to the Secure Area. When you are done click logout below.\"\n InlineTextBox \"Welcome to the Secure Area. When you are done click logout below.\"\nlink \"Logout\" #ref=97\n StaticText \"Logout\"\n InlineTextBox \"Logout\"\nStaticText \"\"\n InlineTextBox \"\"\n"
|
||||
},
|
||||
{
|
||||
"tool": "page_wait_load",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"timeout_ms": 12000
|
||||
},
|
||||
"ms": 1,
|
||||
"is_error": false,
|
||||
"response": "page loaded"
|
||||
},
|
||||
{
|
||||
"tool": "page_get_text",
|
||||
"args": {
|
||||
"port": 9333,
|
||||
"selector": "#flash",
|
||||
"max_bytes": 200
|
||||
},
|
||||
"ms": 0,
|
||||
"is_error": false,
|
||||
"response": " You logged into a secure area!\n×"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
{
|
||||
"prueba": "prueba_2_perceive",
|
||||
"verdict": "PASS",
|
||||
"detail": "outline 4021 chars, refs=True"
|
||||
"detail": "outline 4017 chars, refs=True"
|
||||
},
|
||||
{
|
||||
"prueba": "prueba_3_search",
|
||||
@@ -38,5 +38,10 @@
|
||||
"prueba": "prueba_8_verificacion",
|
||||
"verdict": "PASS",
|
||||
"detail": "click_hidden_err=True type_nofocus_err=True"
|
||||
},
|
||||
{
|
||||
"prueba": "prueba_9_ref_loop",
|
||||
"verdict": "PASS",
|
||||
"detail": "refs=True logged=True auto_observe=True"
|
||||
}
|
||||
]
|
||||
+46
-1
@@ -15,6 +15,7 @@ Requisitos:
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
|
||||
from mcp_client import MCPClient
|
||||
@@ -296,6 +297,50 @@ def prueba_8_verificacion(c, log):
|
||||
return verdict, f"click_hidden_err={bool(click_hidden_err)} type_nofocus_err={bool(type_nofocus_err)}"
|
||||
|
||||
|
||||
def prueba_9_ref_loop(c, log):
|
||||
"""Bucle percibir->actuar por #ref: perceive -> type_ref/click_ref (gap #1)."""
|
||||
r = Recorder(c, log)
|
||||
base = "https://the-internet.herokuapp.com"
|
||||
r.step("cookie_clear", {"port": PORT})
|
||||
r.step("tab_navigate", {"port": PORT, "url": base + "/login"})
|
||||
r.step("page_wait_load", {"port": PORT, "timeout_ms": 12000})
|
||||
outline, _ = r.step("page_perceive", {"port": PORT, "max_chars": 6000}, timeout=90)
|
||||
|
||||
def ref_for(pattern):
|
||||
m = re.search(pattern + r'[^\n]*?#ref=(\d+)', outline)
|
||||
return int(m.group(1)) if m else None
|
||||
|
||||
user_ref = ref_for(r'textbox "Username"')
|
||||
pass_ref = ref_for(r'textbox "Password"')
|
||||
# El name del botón incluye un icono FontAwesome antes de "Login" ().
|
||||
login_ref = ref_for(r'button "[^"]*Login"')
|
||||
refs_ok = all(x is not None for x in (user_ref, pass_ref, login_ref))
|
||||
|
||||
after = ""
|
||||
if refs_ok:
|
||||
# Actuar SOLO por #ref del outline — sin selector CSS. Cierra el bucle.
|
||||
r.step("dom_type_ref", {"port": PORT, "ref": user_ref, "text": "tomsmith"})
|
||||
r.step("dom_type_ref", {"port": PORT, "ref": pass_ref, "text": "SuperSecretPassword!"})
|
||||
after, _ = r.step("dom_click_ref", {"port": PORT, "ref": login_ref}) # auto-observe → outline nuevo
|
||||
r.step("page_wait_load", {"port": PORT, "timeout_ms": 12000})
|
||||
|
||||
flash, _ = r.step("page_get_text", {"port": PORT, "selector": "#flash", "max_bytes": 200})
|
||||
logged = "logged into" in flash.lower()
|
||||
# auto-observe: el dom_click_ref devolvió el outline tras la acción.
|
||||
auto_observed = ("#ref=" in after) or ("Logout" in after) or (len(after) > 50)
|
||||
ok = refs_ok and logged and auto_observed
|
||||
verdict = "PASS" if ok else "FAIL"
|
||||
save("prueba_9_ref_loop.json", {
|
||||
"name": "9 - Bucle percibir->actuar por #ref + auto-observe (gap #1)",
|
||||
"verdict": verdict,
|
||||
"refs": {"username": user_ref, "password": pass_ref, "login": login_ref},
|
||||
"logged_in": logged, "auto_observed": auto_observed,
|
||||
"flash": flash.strip(), "after_observe_preview": after[:300],
|
||||
"steps": r.steps,
|
||||
})
|
||||
return verdict, f"refs={refs_ok} logged={logged} auto_observe={auto_observed}"
|
||||
|
||||
|
||||
def main():
|
||||
log = open(os.path.join(RESULTS, "run.log"), "w", encoding="utf-8")
|
||||
log.write(f"=== Demo e2e browser_mcp @ {time.strftime('%d/%m/%Y %H:%M')} ===\n")
|
||||
@@ -307,7 +352,7 @@ def main():
|
||||
pruebas = [prueba_1_quotes, prueba_2_perceive, prueba_3_search,
|
||||
prueba_4_login_session, prueba_5_books,
|
||||
prueba_6_session_storage, prueba_7_find_honesto,
|
||||
prueba_8_verificacion]
|
||||
prueba_8_verificacion, prueba_9_ref_loop]
|
||||
summary = []
|
||||
for fn in pruebas:
|
||||
name = fn.__doc__.split("\n")[0]
|
||||
|
||||
Reference in New Issue
Block a user