Construyendo un Agente de QA con Chrome DevTools
Jul 10, 2026
Una simple refactorización de una clase CSS puede romper decenas de pruebas automatizadas. No porque el flujo de negocio haya cambiado, sino porque los scripts dependen de selectores frágiles. ¿Y si, en lugar de programar cada interacción, pudiéramos describir el objetivo y dejar que un agente decidiera cómo alcanzarlo?
Con la llegada del desarrollo orientado a agentes cognitivos y el ecosistema de Model Context Protocol (MCP), surge una alternativa disruptiva: delegar la ejecución de pruebas a un agente de QA autónomo.
En este artículo, analizamos la arquitectura técnica de web-flow-agent, un motor de pruebas autónomo que utiliza Gemini y el servidor Chrome DevTools MCP para interpretar escenarios en lenguaje natural, navegar por aplicaciones web y generar diagnósticos detallados sin escribir una sola línea de código de automatización tradicional.
Flujo de Ejecución del Agente
El siguiente diagrama de secuencia ilustra el recorrido completo de la ejecución del agente, desde la lectura de la especificación hasta el ciclo interactivo de navegación y toma de decisiones:

¿Qué hace realmente "Autónomo" a este Agente?
Un error común al hablar de agentes de IA es confundir un script secuencial que hace llamadas a APIs con un agente real. Autónomo no significa únicamente que el sistema puede llamar a herramientas externas. Un agente es autónomo porque es capaz de gestionar su estado, tener memoria del objetivo, replanificar y decidir cuándo finalizar.
El agente funciona bajo un bucle de toma de decisiones dinámico:

A diferencia de un script que falla si el botón no es clicable en el milisegundo exacto, este agente:
- Mantiene memoria de los turnos previos (historial de pasos realizados y pensamientos pasados).
- Replantea la estrategia si una acción no tiene el efecto deseado (por ejemplo, si al hacer clic no cambia la URL, busca formas alternativas de interacción).
- Decide cuándo abortar si detecta excepciones graves en la consola de JavaScript o respuestas de red con errores 500 que bloqueen la continuidad del flujo de negocio.
La Especificación en Markdown
Muchos frameworks de automatización obligan a los equipos a aprender un lenguaje específico o escribir extensos archivos Cucumber. En este proyecto, la especificación se escribe en Markdown estándar y limpio:
# Scenario: Validate Complete Purchase Flow
- **Objective:** Visit the home page, select a product from the main showcase to go to its PDP, select size/color options, add it to the cart, proceed to checkout, and complete the shipping and payment details to validate the purchase.
- **Action:** Visit /
- **Action:** Choose the first available product from the main showcase and enter its PDP
- **Action:** Validate that the PDP loads correctly (showing the price and purchase button)
- **Action:** Select a color/size option if required to enable the purchase button
- **Action:** Click the "Agregar al carrito" button
- **Action:** In the confirmation modal, click the "Ir al checkout" button
- **Action:** Validate that the checkout page loads correctly and the product is displayed in the Order Summary
- **Action:** Complete the shipping information: Email "hi@lperezp.dev", Full Name "Luis Eduardo", Shipping Address "Calle Principal 123", City "Lima", Postal Code "15001"
- **Action:** Complete the payment information: Card Number "1111222233334444", Expiration "12/28", CVV "123"
- **Action:** Click the "Pagar" button and wait for the payment to process and the confirmation page to appear
- **Action:** Validate that the payment confirmation page loads successfully
El parser del agente parse_spec utiliza expresiones regulares sencillas para extraer dinámicamente tanto el objetivo como las acciones. Esto reduce la curva de aprendizaje: cualquier miembro del equipo (incluyendo Product Managers) puede escribir o modificar flujos de prueba sin necesidad de saber programar.
El Prompt del Agente: El Motor Cognitivo
El núcleo del agente radica en sus instrucciones de sistema (System Prompt). A través de ellas, definimos su rol de auditor técnico y el formato JSON estricto con el que debe interactuar. Aquí se muestra una versión simplificada de las directrices principales provistas al modelo:
You are an Autonomous QA Agent. Your mission is to validate a test flow on a web application by interpreting a Markdown specification file.
You interact with the page by calling tools from the Chrome DevTools MCP server.
At each turn, you will receive:
- The Objective of the test flow.
- The Steps/Actions to validate.
- The current URL and accessibility snapshot of the DOM.
- Recent JS console logs and network requests.
- The history of actions you have already performed.
Your response MUST be a valid JSON object complying with this structure:
{
"thought": "Detailed explanation of what you observe on the page and what you decide to do next.",
"action": "call_tool" | "success" | "fail",
"tool_name": "navigate_page" | "click" | "fill" | "wait_for" | "evaluate_script",
"tool_arguments": { … },
"message": "Reason for success or failure (only if action is 'success' or 'fail')."
Critical Rules:
1. Only use elements and UIDs that exist in the most recent snapshot provided.
2. If you see a severe console error or a network request with status >= 400/500 that prevents completing the flow, select "action": "fail".
3. Once all actions in the spec are verified, select "action": "success".
El Bucle de Ejecución
Para entender cómo se realiza la toma de decisiones e interactúa con el protocolo MCP, veamos el bucle principal de ejecución de antigravity_agent.py:
# Get page state
pages_text = client.call_tool_text("list_pages", {})
pages = parse_pages(pages_text)
current_url = "unknown"
for p in pages:
if p["selected"]:
current_url = p["url"]
break
# Take DOM snapshot
dom_snapshot = client.call_tool_text("take_snapshot", {})
# Get diagnostics (console and network)
try:
console_logs = client.call_tool_text("list_console_messages", {"pageSize": 20})
except Exception:
console_logs = "Not available"
try:
network_requests = client.call_tool_text("list_network_requests", {"pageSize": 20})
except Exception:
network_requests = "Not available"
# Compile content prompt
user_content = {
"objective": objective,
"actions": actions,
"current_url": current_url,
"dom_snapshot": dom_snapshot,
"console_logs": console_logs,
"network_requests": network_requests,
"history": history
}
contents = [
{"role": "user", "parts": [{"text": json.dumps(user_content, indent=2)}]}
]
print("Querying Gemini...", flush=True)
response = call_gemini(api_key, system_instruction, contents)
thought = response.get("thought", "")
action = response.get("action", "")
print(f"Agent Thought: {thought}", flush=True)
El Ecosistema MCP de Chrome DevTools
Alimentar a un LLM con código HTML crudo suele ser ineficiente por el alto consumo de tokens y el ruido visual. A través de la integración de MCP, el agente consume el árbol de accesibilidad (A11y tree) mediante la herramienta take_snapshot.
Esto le proporciona al agente una lista simplificada y lógica de los elementos semánticos e interactivos en pantalla:
[2_9] link "Acme Cap"
[3_7] button "Black"
[3_11] button "Agregar al carrito"
[7_4] textbox "Email"
El modelo asocia directamente el UID de accesibilidad con su intención lógica, permitiendo hacer clics (click con uid) o rellenar campos (fill con uid y value) sin requerir búsquedas complejas de XPath o selectores CSS frágiles.
Un Caso de Prueba en Acción
Para ilustrar al agente interactuando en tiempo real, veamos su comportamiento sobre un flujo de validación de compra en localhost:3000:
Historial de Ejecución Autónoma
El agente sigue flujos similares a los de un usuario real, pero con acceso simultáneo a información técnica del navegador:
- Navegación Inicial: El agente navega a
localhost:3000. - Selección de Producto: Gemini identifica semánticamente el enlace del producto "Acme Cap" basándose en el árbol A11y y realiza una acción de
clicksobre su UID. - Variación de Talla/Color: Hace clic en el botón de color "Black" para habilitar el checkout.
- Checkout: Agrega el artículo al carrito, abre el panel lateral y avanza al checkout.
- Formulario de Envío: Rellena campos como email, nombre completo y dirección mediante llamadas secuenciales a
fill. - Pago: Introduce la información de tarjeta de prueba y confirma la transacción de forma exitosa, validando visualmente que aparezca el mensaje de éxito.
Al terminar, el agente evalúa la respuesta visual y técnica y autodetecta el éxito del flujo, cerrando con código de salida y exportando toda la documentación a la carpeta de reportes.

Limitaciones Actuales
Como todo enfoque de vanguardia, esta arquitectura de agente tiene ciertas limitaciones que es importante contemplar para mantener un equilibrio realista:
- Consumo de Tokens: En flujos de prueba extremadamente largos, acumular snapshots de accesibilidad históricos, logs de red y mensajes de consola en el contexto puede elevar significativamente el consumo de tokens.
- Autenticación Compleja y CAPTCHAs: Las aplicaciones que requieren Single Sign-On (SSO) de terceros, autenticación multifactor (MFA) o resolución de CAPTCHAs representan barreras que el agente no puede resolver de forma autónoma sin intervención previa.
- Pruebas de Bajo Nivel: El uso de agentes cognitivos no reemplaza las pruebas unitarias o de integración de bajo nivel.
Código fuente
El código fuente completo está disponible en GitHub: web-flow-agent
Para arrancar el agente localmente contra tu entorno de desarrollo, solo necesitas exportar tu API Key y correr el orquestador:
./run.sh - url [url]
Conclusión
El uso combinado de Chrome DevTools MCP y agentes basados en LLM cambia las reglas del juego en las pruebas de software. No significa que las suites de prueba tengan coste de mantenimiento cero (siempre habrá mantenimiento cuando cambie el producto o los flujos del negocio), pero reduce drásticamente el mantenimiento asociado a selectores y scripts imperativos.
