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:
2026-06-06 13:20:36 +02:00
parent 23f9aa90e8
commit 618e3b0295
13 changed files with 363 additions and 64 deletions
+46 -1
View File
@@ -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]