Inicio / Artículos

Tres agentes de Playwright: Planificador, Generador y Corrector en una aplicación de carrito en tiempo real.

Un framework de Playwright en el que un agente planifica la cobertura, otro genera especificaciones a partir de sesiones del navegador en tiempo real y otro corrige los fallos, permitiendo realizar 22 pruebas paralelas en aproximadamente 16 segundos.

Editor: REACTAPP.TOP8 min de lectura1753 palabras

Fuentes: Planner, Generator, Healer: How I Ran a Full Playwright Suite With Three AI Agents And Playwright MCP

La mayoría de las personas han visto la demostración: se le da una instrucción a un modelo, se recibe un script de Playwright, se ejecuta una vez y, poco después, se observa cómo deja de funcionar. Un equipo de pruebas funcional sigue un ciclo diferente que incluye explorar, planificar, automatizar y mantener, y el objetivo aquí era otorgar a un agente la responsabilidad de cada una de esas etapas. El resultado es un framework de Playwright que puede reutilizarse, con tres agentes especializados a su cargo:

  • Planner explora la aplicación en tiempo real y elabora el plan de pruebas.
  • Generator convierte un escenario planificado en una especificación funcional.
  • Healer ejecuta el conjunto de pruebas, determina por qué fallan y corrige la causa subyacente.

El objetivo de la demostración era una aplicación de carrito pequeña con un flujo que iba desde el inicio de sesión hasta los productos, el carrito, la pantalla de pago y una página de agradecimiento. Al final se contaron 22 escenarios automatizados que abarcaban rutas normales, casos negativos y situaciones límite de validación. Estos se ejecutan en paralelo, utilizando objetos de página que los agentes mantienen por sí mismos. El informe HTML de Playwright mostró 22 pruebas superadas, 0 fallidas y 0 inestables, con todo el conjunto completado en 16.2 segundos.

Trabajos previos antes de que ejecute cualquier agente

Primero deben existir tres elementos. La mayoría de las guías los omiten, pero son ellos quienes determinan si el resultado generado es utilizable en absoluto.

El servidor de pruebas MCP de Playwright. Los agentes no deben adivinar cómo es el DOM, por lo que utilizan un navegador real. Un archivo de configuración los conecta entre sí:

{
  "servers": {
    "playwright-test": {
      "type": "stdio",
      "command": "npx",
      "args": ["playwright", "run-test-mcp-server"]
    }
  }
}

Eso proporciona a cada agente herramientas como browser_navigate, browser_snapshot y browser_click, además de test_run y test_debug para el Healer.

Un contrato de framework. Un archivo framework.md define las carpetas y convenciones: los selectores deben estar en pages/, las jornadas del usuario en flows/, y las direcciones junto con las credenciales en .env. Cada agente lo lee antes de realizar cualquier acción, de modo que los resultados parezcan provenir de una única base de código en lugar de tres estilos personales distintos.

Una prueba inicial. Una pequeña especificación abre la página principal real y verifica que algo funcione de manera estable. Cada prueba generada parte de ese estado conocido y funcional.

La calidad de un agente depende únicamente de los cimientos en los que opera, y estos tres son esos cimientos.

El Planificador: decidir qué merece una prueba

El planificador no escribe ningún código. Abre la aplicación, navega como un probador curioso y mapea lo que existe: formularios, autenticación, el carrito, los pasos de pago, mensajes de validación y estados vacíos.

Su rutina:

  1. Llamar a planner_setup_page una vez.
  2. Explorar con las herramientas del navegador, leyendo capturas del DOM en lugar de capturas de pantalla.
  3. Identificar los flujos principales y las formas en que cada uno puede fallar.
  4. Guardar un plan en formato markdown en specs/<feature>-plan.md.

Cada escenario del plan lleva un título, pasos numerados, un resultado esperado, una suposición sobre el estado inicial (una sesión nueva a menos que se indique lo contrario) y la ruta del archivo en el que se guardará.

El plan de pago resultó en 22 escenarios distribuidos en secciones para Inicio de sesión, Carrito, Pago y un recorrido completo de principio a fin. Esta estructura resulta útil más adelante, ya que el Generador convierte cada nombre de sección en un bloque test.describe, lo que mantiene alineados el plan y el código desde su creación.

¿Por qué una etapa separada? La cobertura es un problema de planificación. Cuando se debe planificar y codificar al mismo tiempo, la planificación empeora. La salida solo con el plan puede revisarse y editarse antes de que exista siquiera una línea de código de prueba.

El Generador: haciendo realidad un escenario

El Generador maneja exactamente un escenario a la vez, nunca todo el plan. Para cada uno de ellos:

  1. Ejecuta generator_setup_page para llegar al estado inicial.
  2. Ejecuta cada paso en tiempo real en el navegador, tratando el texto del paso como la intención correspondiente.
  • Lee de vuelta el registro de ejecución con generator_read_log, que contiene los localizadores y aquellos que realmente funcionaron.
  • Llama a generator_write_test para generar un único archivo de especificaciones.
  • En el tercer paso es donde proviene el valor. No se recuerda nada de los datos de entrenamiento. Lo que queda en el archivo es un registro de una sesión que acaba de realizarse con la interfaz real.

    La salida sigue automáticamente las reglas del framework:

    // spec: specs/checkout-e2e-plan.md
    // seed: tests/web/seed.spec.js
    
    import { test, expect } from '../../../fixtures';
    import { users } from '../../../testdata';test.describe.configure({ mode: 'parallel' });test.describe('E2E checkout journey', () => {
      test('positive: login → add product → checkout → thank you → home', async ({ flow }) => {
        await flow.completeHappyPathPurchase();
      });
    });
    

    Notablemente, faltan en el resultado los selectores CSS, una contraseña literal y cadenas de URL. Los selectores se trasladan a los objetos de página, y los procesos de varias etapas se convierten en métodos de una clase de flujo:

    async completeHappyPathPurchase(user = users.standard, info = checkout.valid) {
      await this.goToCheckoutInformation(user);
      await this.fillValidInformation(info);
      await this.continueToOverview();
      await this.app.checkoutOverview.expectProductVisible(products.first.name);
      await this.finishOrder();
      await this.backHomeToProducts();
    }
    

    Cada prueba también recibe su propio contexto del navegador, gráfico de objetos de página e instancia de flujo a través de los fixtures. Al no haber estado mutable compartido, el conjunto de pruebas es seguro para ejecutarse en paralelo desde el principio y no como algo añadido posteriormente. Eso es lo que diferencia a un script de un framework.

    El reparador: solucionar la capa correcta

    Generar pruebas es una ventaja puntual. El mantenimiento representa el costo permanente, y ahí es donde el tercer agente cobra importancia. Su ciclo es el siguiente:

    1. test_run ejecuta el conjunto de pruebas y recopila los fallos.
    2. test_debug se detiene en cada fallo.
    3. Inspecciona la captura en tiempo real, la consola, el tráfico de red y la afirmación que falló.
    4. Diagnostica la causa: un localizador modificado, un cambio en el timing, un contrato alterado o un verdadero error del producto.
  • Repara la causa raíz y no solo el síntoma, actualizando pages/ cuando la interfaz de usuario se mueve y api/endpoints/ cuando un contrato cambia.
  • Vuelve a ejecutar esa prueba y pasa al siguiente fallo.
  • Dos medidas de seguridad garantizan su fiabilidad. Nunca debilita una afirmación solo para obtener un resultado positivo. Si el producto está incorrecto pero la prueba es correcta, marca la prueba con test.fixme() y un comentario que describe el comportamiento real, de modo que el fallo permanezca visible y no quede oculto. También evita APIs problemáticas como networkidle como solución temporal ante problemas de concurrencia.

    La ventaja radica en la concentración de los cambios. Al renombrar un botón, solo se modifica un método del objeto de página, y a continuación todos los tests que lo utilizan vuelven a funcionar. Dado que 22 tests comparten 325 líneas de objetos de página distribuidas en 10 clases, un rediseño no afecta negativamente a todo el conjunto de tests. En conjunto, cada componente tiene una función clara dentro del repositorio, y la capa compartida de objetos de página es lo que mantiene todo funcionando.

    Ejecutarlo de principio a fin

    Los comandos de configuración:

    1. Copy .env.example → .env, set BASE_URL (+ credentials)
    2. npm install && npx playwright install
    

    Y el agente se ejecuta, en orden:

    3. Run the Planner
          → specs/checkout-e2e-plan.md   (22 scenarios, reviewed by me)4. Run the Generator, scenario by scenario
          → tests/web/login/login.spec.js
          → tests/web/cart/cart.spec.js
          → tests/web/checkout/checkout.spec.js
          → tests/web/e2e/checkout-journey.spec.js5. npm test        (4 workers, fully parallel)6. Any red? Run the Healer → re-run → green
    

    Cambiar a otro producto no afecta a los agentes. Establezca BASE_URL en el nuevo producto, vuelva a crear los objetos de la página y los datos de prueba, y luego ejecute nuevamente las mismas tres instrucciones. Dado que los agentes leen framework.md y .env en lugar de un nombre de producto codificado de forma fija, el proceso es portable y no está diseñado exclusivamente para un caso concreto.

    ¿Cuánto más rápido es realmente?

    Afirmaciones como “La IA lo hizo diez veces más rápido” no deberían aceptarse sin un desglose detallado. Escribir pruebas de extremo a extremo a mano rara vez se trata solo de escribir texto; implica abrir DevTools, buscar un selector estable, encontrar el botón dentro de un contenedor extraño, volver a ejecutar para ver si la verificación se activa demasiado pronto, y empezar de nuevo. La mayor parte del esfuerzo se concentra en ese ciclo de descubrimiento, y el Generador lo absorbe al ejecutar los pasos en tiempo real e informar qué funcionó.

    Las ventajas se manifiestan en varias etapas:

    • Toma de decisiones sobre el alcance. De forma manual es ad hoc y a menudo omite casos negativos. El planificador enumera de antemano escenarios positivos, negativos y límite.
    • Búsqueda de localizadores. La búsqueda manual en los DevTools por elemento da paso a localizadores obtenidos de una sesión ya completada.
    • Primer test exitoso. El ciclo de escribir, ejecutar, corregir y repetir se convierte en una generación a partir de un transcript verificado.
    • Mantener el conjunto de pruebas activo. Buscar en cada especificación un selector defectuoso da paso a una sola corrección de objeto de página que soluciona todas las pruebas dependientes.

    Los mayores ahorros se obtienen en el segundo hasta el vigésimo test. El primero implica un costo real de configuración para los objetos de página, los fixtures y los datos iniciales. A partir de ahí, un nuevo escenario consiste principalmente en combinar partes existentes, y el costo por test disminuye rápidamente.

    La velocidad de ejecución proviene de otra fuente completamente distinta. El paralelismo no es una característica de la IA; es una regla de diseño que los agentes deben respetar. Cada prueba recibe un contexto nuevo a partir de los fixtures y ninguno modifica el estado del módulo compartido, por lo que la configuración se ejecuta de forma totalmente paralela: cuatro trabajadores localmente, dos en CI con dos intentos de reintentar, y se registran trazas y videos solo cuando falla una prueba. Cualquier suite que reutilice una sesión de inicio de sesión no puede funcionar de esa manera sin riesgo. Esta sí puede, porque la regla de que un escenario equivale a una prueba independiente era algo que el Generador debía seguir en cada archivo.

    Cuatro lecciones valiosas

    • Mantén los roles específicos. Un único prompt extenso que planifica, programa y depura genera resultados confusos. Tres roles enfocados, cada uno con sus propias herramientas, dejan algo revisable en cada etapa.
  • Ejecutar la confianza sobre la memoria. Los localizadores confirmados en un navegador en ejecución son más fiables que aquellos deducidos de los documentos.
  • Construir el esqueleto antes que los agentes. Los objetos de página, los fixtures, el manejo del entorno y las reglas paralelas son lo que convierte la salida de la IA en un marco y no en un montón de scripts. Escribir framework.md mejoró la calidad más que cualquier ajuste en los prompts.
  • La reparación es el verdadero resultado. Es fácil crear una prueba una sola vez. Un agente que mantiene 22 pruebas funcionando después de una actualización de la interfaz es lo que justifica adoptar este enfoque.
  • Para quién es adecuado

    Los ingenieros de QA que pasan más tiempo reparando localizadores que diseñando la cobertura verán los beneficios. Lo mismo ocurrirá con los equipos que adoptan Playwright y desean contar con inteligencia artificial dentro de una estructura disciplinada, no que esta reemplace al equipo humano, así como con quienes comparan los agentes Copilot o Cursor con el servidor de pruebas MCP de Playwright.

    Nada de esto reemplaza al QA. La decisión sobre qué es importante, qué se considera un verdadero error y qué cobertura falta sigue en manos de una persona. Los agentes se encargan de la exploración, del código genérico y del trabajo repetitivo de reparación, lo que permite seguir el ciclo de planificar, generar, ejecutar, corregir y volver a ejecutar.