Obtén 100% en el cuestionario para continuar
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 acypress 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:openque 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:
- 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.
- Leer la aplicación real con
aria,domeinspectpara elegir selectores y textos esperados. - Escribir la prueba: actuar y verificar.
- Esperar un veredicto nuevo.
- Leer los resultados y el Command Log.
- 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:
- Antes de ejecutar (o guardar) la spec, anota el
startedAtactual denpx 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ó. - Consulta
npx cypress tap status --jsonmás o menos cada dos segundos, una llamada a la vez. - Acepta solo
passedofailed, para la spec que esperas, con unstartedAtdistinto del que anotaste. - Ríndete después de un número limitado de intentos, y detente de inmediato si
statustermina con1.
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
doneRara 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:
--jsonimprime una salida legible por máquina en lugar de una tabla.--session <pid>(o-s) elige una sesión cuando hay más de uncypress openen ejecución.--timeout <ms>define cuánto espera Tap que la sesión responda (por defecto30000).--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 sessionsEjemplo:
npx cypress tap sessions --jsonstatus
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 --jsonCon --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 specsEjemplo:
npx cypress tap specsrun
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.jsreporter
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 3pin
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 --clearEjemplo:
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 ariadom
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 1inspect
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,ariaeinspectse niegan a adivinar. Terminan con1y listan los candidatos con un índice, y eliges uno con--at <índice>, que aquí empieza en 0.pin --ates 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 🔗
- Referencia de Cypress Tap
- Introducing Cypress Tap (el anuncio)
- El Command Log
- Cypress Básico, si
cy.containsy.shouldnecesitan un repaso
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), luegonpx cypress tap statusynpx cypress tap status --json. La etapa esspec not selected, ystartedAtfalta o esnull. Ejecutanpx 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 specsde nuevo y encuentra tu spec. Anota elstartedAtdenpx cypress tap status --json. Luego ejecutanpx cypress tap run cypress/e2e/explore.cy.jsy consultastatus --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 reportery copia el id de la prueba. Luego ejecutanpx 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 ariay encuentra los botones de la tienda. Algunos tienen un nombre que puedes leer; otros no tienen nombre en absoluto. Anota cuáles. Luego ejecutanpx cypress tap dom --selector '[data-testid="emoji-card"]': se niega, porque coinciden seis tarjetas, y las lista. Ejecútalo de nuevo con--at 1para leer la segunda tarjeta, ynpx cypress tap inspect --selector '[data-testid="emoji-card"]' --at 1para ver sus atributos y su caja. - 7. Busca en esa salida de
ariaun 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 elstartedAtactual, 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 arun: espera el veredicto nuevo. Luego ejecutanpx cypress tap ariay confirma el rol y el texto exacto del control para volver. Escribíbuttonporque 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 delvisity ejecutanpx cypress tap pin --test-id <id> --command-id <fila>. La ventana de Cypress vuelve a mostrar la tienda, antes del clic. Ejecutanpx cypress tap ariay mira los seis productos, aunque la página en vivo muestre el Rocket. Luego ejecutanpx cypress tap pin --clear. - 9. Haz commit de
cypress/e2e/explore.cy.jsy 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
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