Qué es Cypress, setup en TypeScript y primer test
Setup de Cypress 15 con TypeScript contra Serenity.is. Electron crasheó, Chrome se colgó, TypeScript rompió. Edge salvó el día. Proceso real.
Contexto
Ya publiqué frameworks completos con Selenium + Java, Playwright + TypeScript y Appium + Java. Cada uno tiene su serie documentada, su repo público y sus errores al descubierto.
Ahora arranco con Cypress.
No porque sea mejor o peor que los otros. Porque es parte del arsenal que necesito para cubrir el espectro de herramientas que el mercado pide. Selenium domina en demanda, Playwright crece rápido, y Cypress ocupa un lugar específico: E2E testing con una arquitectura distinta a las dos anteriores.
Este es el Post 1 de la serie. 17 posts planeados. Todo en TypeScript desde el primer commit.
Repo: github.com/cesarbeassuarez/cypress-typescript-framework
Qué es Cypress (breve)
Cypress es un framework de testing E2E basado en JavaScript/TypeScript. La diferencia fundamental con Selenium y Playwright es arquitectónica: Cypress corre dentro del browser, no por fuera controlándolo con un protocolo externo (WebDriver en Selenium, CDP en Playwright).
Eso tiene implicaciones prácticas que se van a ir viendo a lo largo de la serie. Por ahora, lo relevante es que la experiencia de desarrollo es distinta: el feedback es más inmediato, no hay waits explícitos, y el Test Runner te muestra la app y los pasos del test en la misma ventana.
No voy a hacer una tabla comparativa extensa acá. Las diferencias reales se ven en la práctica, no en teoría.
Decisiones técnicas
TypeScript desde el día 1. Ya trabajé con TypeScript en Playwright. No tiene sentido arrancar en JavaScript para migrar después. El repo se llama cypress-typescript-framework y tiene que ser coherente desde el primer commit.
Serenity.is como AUT. Es una aplicación demo con login, dashboard, formularios, y API. Suficiente para cubrir los escenarios que necesito en la serie. URL: https://demo.serenity.is.

Cursor como IDE. Primera vez usándolo. Es VS Code con AI integrada. Todo lo que funciona en VS Code funciona acá. Lo elegí para practicar con herramientas de AI-assisted coding, que cada vez se piden más en roles de QA.
Setup
Repo y proyecto
Creé cypress-typescript-framework en GitHub. Público, con README y .gitignore de Node. Lo cloné con SourceTree y lo abrí en Cursor.
Inicialicé el proyecto:
npm init -y
Instalación
npm install cypress typescript --save-dev
170 paquetes instalados, 0 vulnerabilidades. Cypress descarga un binario pesado, tardó unos minutos.
Primera apertura de Cypress
npx cypress open
Cypress 15.17.0 se verificó e instaló. Al elegir E2E Testing, generó automáticamente la estructura de archivos:
cypress/
├── e2e/
├── fixtures/
│ └── example.json
└── support/
├── commands.ts
└── e2e.ts
cypress.config.ts

Detalle importante: Cypress detectó que TypeScript estaba instalado y generó todos los archivos como .ts. No tuve que renombrar nada. En versiones anteriores esto requería configuración manual.
Configuración
cypress.config.ts — lo reemplacé con una configuración limpia:
import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
baseUrl: 'https://demo.serenity.is',
supportFile: 'cypress/support/e2e.ts',
specPattern: 'cypress/e2e/**/*.cy.ts',
},
})
tsconfig.json — creado en la raíz:
{
"compilerOptions": {
"target": "ES2021",
"lib": ["ES2021", "DOM", "DOM.Iterable"],
"types": ["cypress"],
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["cypress/**/*.ts", "cypress.config.ts"],
"exclude": ["node_modules"]
}
Un detalle sobre moduleResolution: originalmente puse "node", que es lo que recomiendan la mayoría de los tutoriales. Pero al correr el test, Cypress rompió con un error TS5107 diciendo que esa opción está deprecated. Lo cambié a "bundler" y funcionó.

La solución fue cambiarlo a "bundler".
Primer test
cypress/e2e/login.cy.ts:
describe('Serenity.is Login Page', () => {
it('should load the login page', () => {
cy.visit('/Account/Login')
cy.get('#LoginPanel').should('be.visible')
})
})

Cinco líneas. Abrir la página de login de Serenity.is y verificar que el panel de login sea visible.
Tres errores antes del primer test verde
Error 1: Electron crasheó. Correr npx cypress run (que usa Electron por defecto) dio: "We detected that the Electron Renderer process just crashed." El test falló con 0 segundos de duración y un ERR_FAILED (-2) loading 'about:blank'. No investigué mucho porque Electron no es un browser real — es el fallback de Cypress para cuando no hay otro disponible.

Error 2: Chrome se colgó. npx cypress run --browser chrome mostró el warning de allowCypressEnv y se quedó ahí. Sin output, sin progreso, sin error. Pasaron más de dos minutos y nada. Cancelé con Ctrl+C.

Error 3: TypeScript rompió la compilación. npx cypress run --browser edge por fin arrancó, pero Webpack no pudo compilar el test:
[tsl] ERROR
TS5107: Option 'moduleResolution=node10' is deprecated
and will stop functioning in TypeScript 7.0.

El fix fue cambiar "moduleResolution": "node" a "moduleResolution": "bundler" en tsconfig.json.
Test verde
Después del fix, Edge corrió el test:
npx cypress run --browser edge
Serenity.is Login Page
✓ should load the login page (9146ms)
1 passing (9s)
┌──────────────────────────────────────┐
│ Tests: 1 │
│ Passing: 1 │
│ Failing: 0 │
└──────────────────────────────────────┘
✓ All specs passed!

También lo corrí en modo interactivo:
npx cypress open --browser edge
El Test Runner abrió Edge, hice click en login.cy.ts, y el test pasó. A la izquierda los pasos (visit, get, assert), a la derecha la app de Serenity.is con el formulario de login visible.

La diferencia con npx cypress run (headless, para CI/CD) vs npx cypress open (interactivo, para desarrollo) es la misma que npx playwright test vs npx playwright test --ui. El interactivo te da time-travel: podés hacer hover sobre cada paso y ver el estado del DOM en ese momento.
Versiones
| Herramienta | Versión |
|---|---|
| Cypress | 15.17.0 |
| TypeScript | 5.x (latest) |
| Node.js | v24.14.0 |
| Edge | 149 |
| Cursor | latest |
Estado actual
Tengo:
- Proyecto Cypress + TypeScript configurado
- Primer test E2E corriendo contra Serenity.is
- Ejecución headless (Edge) y modo interactivo funcionando
- Repo público actualizado
Estructura del proyecto
cypress-typescript-framework/
├── cypress/
│ ├── e2e/
│ │ └── login.cy.ts
│ ├── fixtures/
│ │ └── example.json
│ └── support/
│ ├── commands.ts
│ └── e2e.ts
├── .gitignore
├── cypress.config.ts
├── package.json
├── package-lock.json
├── README.md
└── tsconfig.json
Próximo post: selectores, comandos y login completo en Serenity.is.