Talking About TestingATT</>
Pruebas Agénticas con Cypress Tap

Obtén 100% en el cuestionario para continuar

Lección
Vista previa gratuita

Cypress Tap, a mano

Maneja Cypress Tap tú mismo: ejecuta una spec, espera un veredicto nuevo, lee la aplicación y viaja en el tiempo.

Antes de darle Cypress Tap a un agente, lo vas a manejar tú mismo, una vez, a mano. Todo lo que hace tu agente en este curso lo hace con los comandos de esta lección. Conocerlos es lo que te permite verificar sus afirmaciones en lugar de creerlas.

Qué es Cypress Tap

Cypress Tap es un conjunto de comandos, npx cypress tap <comando>, que manejan desde la terminal una sesión de cypress open que ya está en ejecución. Viene dentro del Cypress App (Cypress 15.21.0 en adelante), así que no hay nada más que instalar. Es gratuito, no necesita una cuenta de Cypress Cloud y corre solo en tu máquina.

Tres cosas que debes saber antes del primer comando:

  • Se conecta a cypress open, nunca a cypress run. Tap lee el mismo Command Log y los mismos snapshots del DOM que ves en la ventana de Cypress, así que la ventana tiene que estar abierta. Las ejecuciones headless, como las de la CI, no son alcanzables.
  • Solo funciona en navegadores basados en Chromium: Chrome, Chromium, Edge y Electron. Por eso el script cy:open que escribiste en la lección de configuración pasa --browser chrome.
  • La terminal y la ventana de Cypress comparten un único frame del navegador, sin bloqueo entre ellos. Si haces clic por la aplicación en la ventana de Cypress mientras Tap (o tu agente) la está leyendo, cada uno ve los cambios del otro. Observa la ventana; no la toques.
👨‍🏫 Cypress Tap está en beta. Sus comandos y su salida todavía pueden cambiar en cualquier release, lo que es un motivo más para que la lección de configuración haya fijado Cypress en una versión exacta.

El flujo de trabajo

Cada prueba de este curso se escribe de la misma manera, la escribas tú o tu agente. Estos seis pasos vienen de la guía de Tap del proyecto, docs/cypress/07-cypress-tap.md:

  1. Preparar el estado de la página con una spec mínima. Tap solo puede leer la aplicación después de que una spec la llevó a algún lugar.
  2. Leer la aplicación real con aria, dom e inspect para elegir selectores y textos esperados.
  3. Escribir la prueba: actuar y verificar.
  4. Esperar un veredicto nuevo.
  5. Leer los resultados y el Command Log.
  6. Refinar las aserciones usando lo que la aplicación realmente muestra.

El paso 4 es el que la gente hace mal, así que tiene su propia sección justo abajo.

Esperar un veredicto nuevo

run vuelve antes de que la spec haya empezado. Y, hasta que empieza la nueva ejecución, status sigue mostrando el veredicto de la ejecución anterior. Así que un passed justo después de un run puede estar describiendo la ejecución de antes.

La única forma segura de esperar es comparar startedAt:

  1. Antes de ejecutar (o guardar) la spec, anota el startedAt actual de npx cypress tap status --json. No después: para entonces la nueva ejecución puede haber empezado, y esperarías para siempre una ejecución que ya ocurrió.
  2. Consulta npx cypress tap status --json más o menos cada dos segundos, una llamada a la vez.
  3. Acepta solo passed o failed, para la spec que esperas, con un startedAt distinto del que anotaste.
  4. Ríndete después de un número limitado de intentos, y detente de inmediato si status termina con 1.

Aquí está ese ciclo como un script de Bash, que usa Node.js para leer el JSON. Ejecútalo en una terminal en la raíz de tu proyecto: en macOS y Linux, sirve la terminal por defecto; en Windows, usa Git Bash, como se recomienda en los requisitos previos. Reemplaza el valor de base por el startedAt que anotaste (o déjalo como null antes de la primera ejecución):

base="null"
for i in $(seq 1 60); do
  out=$(npx cypress tap status --json 2>/dev/null) || { echo "status failed"; break; }
  s=$(echo "$out" | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>{try{const j=JSON.parse(d);console.log(j.status+"|"+j.startedAt)}catch{console.log("?|?")}})')
  st=${s%%|*}; sa=${s#*|}
  if { [ "$st" = passed ] || [ "$st" = failed ]; } && [ "$sa" != null ] && [ "$sa" != undefined ] && [ "$sa" != "?" ] && [ "$sa" != "$base" ]; then
    echo "$st $sa"; break
  fi
  sleep 2
done

Rara vez lo vas a escribir tú: es lo que ejecuta tu agente, y la guía de Tap del proyecto lo incluye. Pero debes poder leerlo, porque cuando un agente dice "la prueba pasó", así es como debería saberlo.

Guardar una spec la ejecuta

Una vez que hay una spec seleccionada (la que muestra status), Cypress la observa: guardarla inicia una nueva ejecución por sí sola, exactamente como cuando trabajas en la ventana de Cypress. Así que, después de editar la spec seleccionada, no llames también a run, o pones dos ejecuciones en curso al mismo tiempo. Anota el startedAt, guarda y espera.

👨‍🏫 El observador solo vuelve a ejecutar la spec seleccionada. Guardar otra spec no la ejecuta; para eso, usa npx cypress tap run <spec>.

Resumen de comandos 📖

Todos los comandos aceptan estas opciones compartidas:

  • --json imprime una salida legible por máquina en lugar de una tabla.
  • --session <pid> (o -s) elige una sesión cuando hay más de un cypress open en ejecución.
  • --timeout <ms> define cuánto espera Tap que la sesión responda (por defecto 30000).
  • --help (o -h) imprime cómo usar el comando.

Todos los comandos terminan con 0 en caso de éxito y 1 en caso de fallo, para que un agente (o un script) note la diferencia sin leer la salida.

sessions

Lista las sesiones de cypress open en ejecución: id del proceso (PID), carpeta del proyecto, tipo de prueba y navegador.

Sintaxis:

npx cypress tap sessions

Ejemplo:

npx cypress tap sessions --json

status

Informa en qué punto de su ciclo de vida está la sesión, qué spec está seleccionada y los conteos de la última ejecución. Las etapas son not connected, browser not selected, spec not selected, loading, running, passed y failed. Solo passed y failed son veredictos; todo lo demás significa "no terminó".

Sintaxis:

npx cypress tap status [--json]

Ejemplo:

npx cypress tap status --json

Con --json, busca status, spec, startedAt (cuándo empezó la ejecución actual, null hasta que empieza una ejecución), totalTests y results (los conteos de passed, failed, pending y skipped).

specs

Lista las specs que la sesión puede ejecutar, de las modificadas más recientemente a las más antiguas.

Sintaxis:

npx cypress tap specs

Ejemplo:

npx cypress tap specs

run

Inicia una spec y vuelve de inmediato, antes de que haya corrido una sola prueba. No espera el veredicto, ni lo imprime.

Sintaxis:

npx cypress tap run <ruta-de-la-spec>

Ejemplo:

npx cypress tap run cypress/e2e/explore.cy.js

reporter

Sin --test-id, imprime el resumen de la spec, como el panel del reporter de la ventana de Cypress: cada prueba con su resultado y un id de prueba (como r2). Con --test-id, imprime el Command Log completo de esa prueba: hooks, cada comando, las solicitudes de red y el error, si lo hay. --attempt elige un reintento (desde 1).

Sintaxis:

npx cypress tap reporter [--test-id <id>] [--attempt <n>]

Ejemplo:

npx cypress tap reporter --test-id r2
👨‍🏫 Copia los ids de prueba de la salida de reporter. Nunca los deduzcas del orden de las pruebas en la spec.

command

Imprime en detalle una fila del Command Log de una prueba: sus snapshots y sus propiedades de consola. --command-id es el número de fila de reporter --test-id.

Sintaxis:

npx cypress tap command --test-id <id> --command-id <fila> [--depth <n|all>]

Ejemplo:

npx cypress tap command --test-id r2 --command-id 3

pin

Viaje en el tiempo. Carga el snapshot del DOM de un comando en el frame de la aplicación, para que el siguiente aria, dom o inspect lea la página como estaba en ese momento. --at elige el snapshot: before, after o un índice desde 1. --clear libera el pin y vuelve a la aplicación en vivo.

Sintaxis:

npx cypress tap pin --test-id <id> --command-id <fila> [--at <before|after|n>]
npx cypress tap pin --clear

Ejemplo:

npx cypress tap pin --test-id r2 --command-id 1
👨‍🏫 Ejecuta siempre pin --clear cuando termines de leer un snapshot fijado. Hasta que lo hagas, cada lectura muestra el pasado.

aria

Imprime el árbol de accesibilidad de la página: el rol, el nombre accesible y el estado de cada elemento, como los ve un lector de pantalla. Es la mejor primera mirada a una página: muestra qué hay y cómo está etiquetado, en pocas líneas. Lee hasta 200 nodos por defecto (--max-nodes, o -m).

Sintaxis:

npx cypress tap aria [--selector <css>] [--at <índice>]

Ejemplo:

npx cypress tap aria

dom

Imprime el markup de toda la página, o del elemento que encuentra un selector CSS. Úsalo para textos y atributos exactos, como data-testid, id, type y placeholder. Imprime hasta 30000 caracteres por defecto (--max-chars, o -m).

Sintaxis:

npx cypress tap dom [--selector <css>] [--at <índice>]

Ejemplo:

npx cypress tap dom --selector '[data-testid="emoji-card"]' --at 1

inspect

Imprime la etiqueta, los atributos, el nodo de accesibilidad, el box model y los estilos computados más relevantes de un elemento. --selector es obligatorio.

Sintaxis:

npx cypress tap inspect --selector <css> [--at <índice>]

Ejemplo:

npx cypress tap inspect --selector '[data-testid="emoji-card"]' --at 1
👨‍🏫 Cuando un selector encuentra más de un elemento, dom, aria e inspect se niegan a adivinar. Terminan con 1 y listan los candidatos con un índice, y eliges uno con --at <índice>, que aquí empieza en 0. pin --at es distinto: ahí un número empieza en 1, porque cuenta los snapshots de un comando, no elementos. Un selector deliberadamente amplio es una buena forma de descubrir qué hay en la página.

Telemetría

Cypress Tap registra qué comando ejecutaste, con qué opciones, y si falló. La referencia de Cypress documenta cómo desactivarla con la variable de entorno CYPRESS_DISABLE_GUEST_TELEMETRY=0. Sí, un 0 que desactiva algo: revisa la referencia antes de confiar en eso, ya que Tap está en beta.

Contenido sugerido 📚 y enlaces a la documentación 🔗

Ejercicio 🎯

Vas a manejar Cypress Tap a mano, desde un primer cy.visit hasta una prueba que abre un producto, leyendo la aplicación en cada paso.

  • 1. En una terminal, en la raíz de tu proyecto, ejecuta npm run cy:open. Cuando el navegador se abra en la lista de specs, déjalo ahí: no selecciones nada. Mantén esta terminal en ejecución durante todo el curso; Tap la necesita.
  • 2. En una segunda terminal, ejecuta npx cypress tap sessions (una fila, tu proyecto), luego npx cypress tap status y npx cypress tap status --json. La etapa es spec not selected, y startedAt falta o es null. Ejecuta npx cypress tap specs: todavía no hay ninguna.
  • 3. Crea el archivo cypress/e2e/explore.cy.js. Su único trabajo, por ahora, es el paso 1 del flujo, preparar el estado:
describe('Exploring Emoji Mart', () => {
  it('opens the store', () => {
    cy.visit('/')
  })
})
  • 4. Ejecuta npx cypress tap specs de nuevo y encuentra tu spec. Anota el startedAt de npx cypress tap status --json. Luego ejecuta npx cypress tap run cypress/e2e/explore.cy.js y consulta status --json (o corre el script de Bash de la sección "Esperar un veredicto nuevo") hasta tener un veredicto nuevo. Observa la ventana de Cypress mientras corre, sin tocarla.
  • 5. Ejecuta npx cypress tap reporter y copia el id de la prueba. Luego ejecuta npx cypress tap reporter --test-id <id> y lee su Command Log. Busca filas de red (solicitudes que hizo la aplicación mientras corría la prueba): no hay ninguna. Emoji Mart carga todo lo que necesita junto con la página y no hace solicitudes después de eso, así que no habrá nada que interceptar en este curso.
  • 6. Ahora lee la aplicación. Ejecuta npx cypress tap aria y encuentra los botones de la tienda. Algunos tienen un nombre que puedes leer; otros no tienen nombre en absoluto. Anota cuáles. Luego ejecuta npx cypress tap dom --selector '[data-testid="emoji-card"]': se niega, porque coinciden seis tarjetas, y las lista. Ejecútalo de nuevo con --at 1 para leer la segunda tarjeta, y npx cypress tap inspect --selector '[data-testid="emoji-card"]' --at 1 para ver sus atributos y su caja.
  • 7. Busca en esa salida de aria un control que te lleve de vuelta desde la página de un producto. No hay ninguno, porque no hay ninguna página de producto abierta: la prueba se detuvo en la tienda. Es el paso 1 otra vez: para leer un estado, una prueba tiene que llegar a él. Anota el startedAt actual, cambia la prueba para que abra el Rocket y verifique que su página se está mostrando, y guarda:
describe('Exploring Emoji Mart', () => {
  it('opens the Rocket', () => {
    cy.visit('/')

    cy.contains('[data-testid="emoji-card"]', 'Rocket').click()

    cy.contains('button', '← Back to all emojis').should('be.visible')
  })
})
👨‍🏫 Guardar la spec seleccionada la ejecuta, así que esta vez no llames a run: espera el veredicto nuevo. Luego ejecuta npx cypress tap aria y confirma el rol y el texto exacto del control para volver. Escribí button porque ese es el rol que me mostró aria. Si el tuyo muestra otra cosa, la aserción sigue a la aplicación, no a mi ejemplo.
  • 8. Viaje en el tiempo: ejecuta npx cypress tap reporter --test-id <id> (el id puede haber cambiado, así que cópialo de nuevo), encuentra el número de fila del visit y ejecuta npx cypress tap pin --test-id <id> --command-id <fila>. La ventana de Cypress vuelve a mostrar la tienda, antes del clic. Ejecuta npx cypress tap aria y mira los seis productos, aunque la página en vivo muestre el Rocket. Luego ejecuta npx cypress tap pin --clear.
  • 9. Haz commit de cypress/e2e/explore.cy.js y push.
🙊 La solución del instructor se enlazará aquí pronto.

Muéstrale al mundo lo que aprendiste 🌎

Para mostrarle a tu red profesional lo que aprendiste en esta lección, publica lo siguiente en LinkedIn.

Estoy haciendo el curso "Pruebas Agénticas con Cypress Tap" con @Walmyr Lima e Silva Filho en la @Talking About Testing School, y acabo de manejar Cypress Tap a mano: ejecuté una spec desde la terminal, esperé un veredicto nuevo en lugar de confiar en uno viejo, leí el Command Log, el árbol de accesibilidad y el DOM, y viajé en el tiempo hasta un snapshot anterior. #TalkingAboutTesting #TATSchool #AgenticTestingWithCypressTap #CypressTap #AgenticTesting

👨‍🏫 No olvides mencionarme en tu publicación. Aquí está mi perfil de LinkedIn.

Cuestionario

Pregunta 1 de 2
Puntuación: 0

Ejecutas una spec con npx cypress tap run e inmediatamente lees status --json. Dice passed. Antes de confiar en eso, ¿qué debes verificar y por qué?

Obtén 100% en el cuestionario para continuar