12k
All articles

Novedades de Cypress 16

Conoce los cambios de Cypress 16: HTTP/2 nativo, pruebas más rápidas, API eliminadas y soluciones de migración. Por qué actualizar a Cypress 16.1.0 o posterior.

OpenReplay Team
OpenReplay Team
Novedades de Cypress 16

Cypress 16 ejecuta Chrome, Chromium y Edge sobre la pila de red nativa del navegador con HTTP/2. Además, por defecto escribe texto y comprueba la visibilidad más rápido, y elimina Cypress.env() y cy.exec(). Actualiza a la versión 16.1.0 o posterior, no a la 16.0.0.

Las actualizaciones de versión mayor suelen fallar en CI, no en local. Una API eliminada lanza una excepción dentro de un archivo de soporte, o una ejecución deja de mostrar salida hasta que el job agota su tiempo de espera.

Este artículo cubre Cypress 16.0.0 (1 de septiembre de 2026) y 16.1.0 (15 de septiembre de 2026): qué se vuelve más rápido, qué cambia en la forma de escribir los tests, qué deja de funcionar y cómo solucionarlo, y qué versión fijar. Para los fundamentos, consulta pruebas end-to-end con Cypress.

Puntos clave

  • En Cypress 16, Chrome, Chromium y Edge usan HTTP/2 o HTTP/3 siempre que el servidor lo admita. Firefox, WebKit y Electron se mantienen en HTTP/1.1.
  • Se elimina Cypress.env(). Usa cy.env() para los secretos, que permanecen en el proceso de Node hasta que un test los solicita, y Cypress.expose() para los valores que es seguro exponer en el navegador.
  • cy.intercept() mantiene la misma API, pero en la red nativa falta req.httpVersion, desaparecen las cabeceras de compresión y las respuestas revalidadas devuelven 200 en lugar de 304.
  • Cypress 16 requiere Node.js 22.x, 24.x o >=26.x. Node 20 y 25 dejan de estar soportados.
  • Usa la 16.1.0 o posterior. La 16.1.0 corrige una regresión de la 16.0.0 por la que las ejecuciones en navegadores de la familia Chrome podían quedarse colgadas sin mostrar salida, y otra por la que blockHosts no se aplicaba.

HTTP/2 es el valor por defecto en Chrome, Chromium y Edge

Chrome, Chromium y Edge interceptan ahora el tráfico de los tests de Cypress 16 en la propia pila de red del navegador, en lugar de hacerlo pasar por el proxy de Cypress. La aplicación bajo prueba se conecta directamente a tu servidor y utiliza el mejor protocolo que admitan ambas partes, incluidos HTTP/2 y HTTP/3. Firefox, WebKit y Electron mantienen la ruta heredada de HTTP/1.1.

El cambio a HTTP/2 nativo es importante porque HTTP/1.1 solo permite unas pocas conexiones paralelas por origen, de modo que una página con cientos de recursos tiene que ponerlos en cola. HTTP/2 multiplexa todas esas peticiones como streams sobre una única conexión. En el benchmark de la propia Cypress, una página que carga 1000 imágenes pasó de 3896 ms con HTTP/1.1 a 1362 ms con HTTP/2. El anuncio no describe la configuración de la prueba, así que interpreta la cifra como una tendencia y no como una predicción para tu suite.

El HTTP/2 nativo también permite probar interfaces con streaming en Cypress 16. Con HTTP/1.1, un navegador solo admite seis conexiones de Server-Sent Events por dominio, lo que dejaba fuera de alcance funcionalidades como las notificaciones en tiempo real. Con HTTP/2, el servidor y el navegador acuerdan cuántos streams pueden ejecutarse simultáneamente, y Cypress sitúa el valor por defecto habitual en 100.

Cypress 16 además deja de terminar TLS para la aplicación bajo prueba, por lo que el navegador verifica el certificado real de tu origen. Para certificados de desarrollo autofirmados o una CA interna, la 16.1.0 añade trustedCertificates.

Cambios en la velocidad de los tests en Cypress 16

Cypress 16 cambia tres valores por defecto que afectan a la velocidad. Cada uno de ellos tiene una forma de revertirlo.

  • El retardo entre pulsaciones es de 0 ms, frente a los 10 ms anteriores. Para los campos que dependen del ritmo de escritura, como los campos de búsqueda con debounce, puedes restaurar el retardo anterior:
Cypress.Keyboard.defaults({ keystrokeDelay: 10 })
cy.get('[data-cy=search]').type('laptop', { delay: 10 })

En la 16.0.0, incluir keystrokeDelay en un archivo de configuración de TypeScript provocaba un error de compilación. La 16.1.0 lo corrige.

  • Las comprobaciones de visibilidad usan el algoritmo moderno. Se basa en el método nativo del navegador Element.checkVisibility(), y visibilityStrategy toma por defecto el valor 'modern'.
  • manageBrowserMemory está activado por defecto. Mientras se ejecutan los tests, Cypress comprueba el uso de memoria a intervalos. Si una lectura supera un límite establecido, ejecuta la recolección de basura antes de que empiece el siguiente test. Esa limpieza consume tiempo, por lo que una suite ligera podría ser más rápida con el ajuste desactivado. Mide los tiempos de tu suite de ambas formas antes de desactivarlo.

¿Qué cambia en la forma de escribir tests en Cypress 16?

En Cypress 16, las lecturas de cookies y de almacenamiento se reintentan como el resto de queries, y el acceso a las variables de entorno se divide en dos API independientes.

cy.getCookie(), cy.getCookies(), cy.getAllCookies(), cy.getAllLocalStorage() y cy.getAllSessionStorage() son ahora comandos de query con reintento, regidos por defaultCommandTimeout. Ya no usan responseTimeout, aunque cy.setCookie() sí lo sigue haciendo. Si encadenas un .should(), se seguirá reintentando hasta que la aserción se cumpla. Si pones la comprobación dentro de .then(), se ejecuta una sola vez, sin reintentos.

cy.getCookie('auth_token').should('have.property', 'value')

Si tu suite sobrescribe alguno de estos comandos, cámbialo a Cypress.Commands.overwriteQuery(). Cypress.Commands.overwrite() ya no funciona con ellos.

Cypress.env() se marcó como obsoleto en la 15.10.0 y ahora ha desaparecido. cy.env() es asíncrono: obtiene los valores sensibles del proceso de Node y entrega a tu test únicamente las claves que indiques. Cypress.expose() es la opción síncrona para los valores que es seguro mostrar en el navegador.

// Before (Cypress 15)
const token = Cypress.env('STRIPE_KEY')

// After (Cypress 16)
cy.env(['STRIPE_KEY']).then(({ STRIPE_KEY }) => {
  cy.request({ url: '/api/charge', headers: { Authorization: STRIPE_KEY } })
})
const apiBase = Cypress.expose('PUBLIC_API_URL')

cy.env() escribe los nombres de las claves en el Command Log, pero nunca sus valores. Esa protección termina en cuanto te entrega el objeto: .its(), .invoke(), las aserciones o un comando que falle pueden imprimir un valor, así que mantén los secretos dentro de .then(). Las sobrescrituras por test y por suite ahora reciben expose: {...} en lugar de env: {...}, y se ha eliminado allowCypressEnv.

Cambios incompatibles en Cypress 16 y cómo solucionarlos

La mayoría de los cambios incompatibles de Cypress 16 son eliminaciones mecánicas, y la guía de migración ofrece un reemplazo directo para cada una. El que requiere más reflexión es cy.intercept().

La API de cy.intercept() en sí no cambia. Sin embargo, en la red nativa no se informa de req.httpVersion; faltan cabeceras de compresión como content-encoding, porque el cuerpo llega ya decodificado; las respuestas revalidadas devuelven 200 en lugar de 304, y res.statusMessage aparece vacío con HTTP/2 y HTTP/3. Además, responseTimeout ya no limita los manejadores de respuesta. Si no llega ninguna respuesta, Cypress desiste tras un tiempo fijo de 30 segundos, y si necesitas un límite distinto debes configurarlo en cy.wait(). Modifica las aserciones para que verifiquen el comportamiento y no detalles del transporte. Los patrones de mocking y stubbing en Cypress siguen siendo válidos.

// Before: expect(req.httpVersion).to.eq('1.1')
cy.intercept('GET', '/api/cart').as('cart')
cy.visit('/checkout')
cy.wait('@cart', { timeout: 15000 }).its('response.statusCode').should('eq', 200)

La lista completa de cambios incompatibles de la 16.0.0, con lo que ocurre si dejas cada uno sin corregir:

CambioSi no se corrigeSolución
Se eliminan cy.exec() / execTimeoutcy.exec() lanza un error; execTimeout genera un aviso y se ignoraTraslada la lógica a un cy.task() y usa taskTimeout
Se elimina cy.end()El comando da errorElimina las llamadas
viewportWidth/viewportHeight/blockHosts mediante Cypress.config()Ya no se permite en tiempo de ejecución (antes se aplicaba al siguiente test)Configúralos en la configuración de describe/it o llama a cy.viewport()
experimentalMemoryManagementGenera un aviso y se ignoraElimínalo; usa manageBrowserMemory: false para desactivarlo
experimentalFastVisibilityReemplazadoElimínalo; ahora lo controla visibilityStrategy
Se elimina experimentalSourceRewritingLa opción no tiene efectoElimínala; para errores de SRI usa removeSRIAttributes
CoffeeScriptLos archivos .coffee ya no se resuelvenUsa JS/TS o @cypress/webpack-preprocessor
Node.jsNode 20 y 25 sin soporteNode 22.x, 24.x o >=26.x
Component testingLas toolchains antiguas dejan de estar soportadasAngular 21.0.0+, Vite 8.0.0+, Next.js 15.0.4+ o 16+
ElectronObsoleto, pero sigue funcionandoCambia la CI a Chrome u otro navegador instalado

Para el viewport, traslada la configuración al bloque:

describe('mobile nav', { viewportWidth: 375, viewportHeight: 667 }, () => {
  it('opens the menu', () => { /* ... */ })
})

Las vías de escape de Cypress 16 son temporales

Cypress 16 incluye dos opciones para desactivar los nuevos comportamientos, y el changelog marca ambas como obsoletas. forceHttp1: true devuelve todos los navegadores a la ruta del proxy heredado. Cypress la marcó como obsoleta en la misma versión en que la añadió, y tiene previsto eliminarla cuando la ruta nativa cuente con soporte a largo plazo tanto en Chrome como en Firefox. visibilityStrategy: 'legacy' restaura el algoritmo de visibilidad anterior. La opción en sí está obsoleta, y el changelog indica que el valor legacy debe tratarse como una solución provisional mientras migras.

Usa forceHttp1 y visibilityStrategy: 'legacy' para diagnosticar fallos, no como configuración permanente. Si un fallo desaparece con el flag activado, compáralo con las diferencias documentadas de la red nativa, reescribe la aserción y, después, elimina el flag.

Veredicto: actualiza a Cypress 16.1.0 o posterior, no a la 16.0.0

Actualiza y fija la 16.1.0 o una versión 16.x más reciente, nunca la 16.0.0. La 16.1.0 corrige una regresión de la 16.0.0 por la que las ejecuciones en Chrome, Chromium y Edge podían quedarse en silencio a mitad de camino y no terminar nunca. También corrige que blockHosts no se aplicara en esos navegadores: las peticiones a un host bloqueado salían a la red cuando deberían haber fallado con un 503. Una suite que dependa de hosts bloqueados podría pasar en la 16.0.0 sin probar realmente lo que dice probar. La 16.1.0 corrige además el error de TypeScript de keystrokeDelay y una fuga de memoria en los service workers.

Ejecuta tu primera build en verde con la 16 en Chrome, no solo en Electron. Electron se mantiene en la ruta heredada, por lo que una ejecución solo con Electron nunca pasa por la red nativa. Después, revisa tu suite según las buenas prácticas de Cypress. Tus ejecuciones en Firefox y WebKit siguen usando HTTP/1.1, mientras que los usuarios reales de Firefox y Safari reciben HTTP/2 en producción, por lo que el session replay de usuarios reales es una forma útil de descubrir los flujos y navegadores que tu suite E2E nunca cubre.

Conclusión

La mayor parte de lo que Cypress 16 acelera no requiere ningún trabajo por tu parte. La mayor parte de lo que rompe se puede localizar con una búsqueda en tu repositorio. Busca Cypress.env, cy.exec, cy.end, las llamadas a Cypress.config() en tiempo de ejecución y las claves experimentales eliminadas. Sustituye cada coincidencia usando la tabla anterior, migra la CI a Node 22 o posterior con Chrome e instala directamente la 16.1.0 o una versión posterior.

Preguntas frecuentes

¿Cómo ejecuto un comando de shell en Cypress 16 ahora que se ha eliminado cy.exec()?

Registra una tarea en setupNodeEvents que llame al módulo child_process de Node, por ejemplo con execFileSync, y luego invócala desde el test con cy.task('resetDatabase'). Toda tarea debe devolver un valor o null. Por defecto, una tarea desiste tras 60 segundos, y taskTimeout permite cambiar ese límite. cy.task() no puede ejecutar procesos que nunca terminan, como arrancar un servidor. cy.exec() se marcó como obsoleto en Cypress 15.21.0 y se eliminó en la 16.0.0.

¿Cuál es la diferencia entre trustedCertificates y clientCertificates en Cypress?

trustedCertificates, añadido en Cypress 16.1.0, hace que el navegador confíe en un certificado que presenta tu servidor, como un certificado de desarrollo autofirmado o emitido por una CA interna. clientCertificates sirve para TLS mutuo, en el que Cypress presenta un certificado al servidor. Cada entrada de trustedCertificates admite exactamente una de las opciones filePath, pem o spki, y se aplica en la ruta de red nativa de Chrome, Chromium y Edge. Los orígenes declarados pueden entonces usar la caché HTTP del navegador.

¿Puedo ejecutar tests de componentes de Angular 20 en Cypress 16?

No con el harness integrado. El component testing de Cypress 16 ya no es compatible con Angular 18, 19 ni 20, y la versión mínima soportada es Angular 21.0.0. Como solución provisional, puedes instalar desde npm el paquete obsoleto @cypress/angular 4.x e importar mount desde él en lugar de cypress/angular, pero Cypress ya no da soporte a ese harness, así que planifica la migración a Angular 21. La misma versión elimina también el soporte integrado para CoffeeScript, por lo que los specs, archivos de soporte y fixtures .coffee ya no se resuelven.

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.