Cypress Alert Handling: guía completa para manejar alert, confirm y prompt
Uno de los errores más comunes en artículos sobre Cypress es meter en el mismo saco cualquier popup, modal o diálogo y decir que “todo se maneja igual”. No es verdad. En Cypress hay una diferencia importante entre los diálogos nativos del navegador —como alert, confirm, prompt o beforeunload— y los modales que renderiza tu propia aplicación con HTML, CSS y JavaScript. Cypress trata estos casos de forma distinta, y entender esa diferencia es lo que separa un test fiable de uno improvisado.
La documentación oficial lo deja bastante claro al documentar eventos específicos como window:alert, window:confirm, window:before:load y window:before:unload.
La buena noticia es que Cypress tiene una historia muy buena para este tipo de escenarios. Puedes escuchar eventos del navegador, controlar el comportamiento de un cypress confirm dialog, stubear prompt antes de que cargue la aplicación y depurar stubs y spies visualmente desde la propia Cypress App. Si necesitas localizar elementos específicos para disparar estos diálogos, XPath es una herramienta excelente para navegar el DOM cuando los selectores CSS se quedan cortos.
En esta guía vas a ver cómo manejar correctamente alert, confirm, prompt y beforeunload en Cypress, con ejemplos limpios, buenas prácticas, errores típicos y una estructura lista para proyectos reales. Comparado con Playwright, Cypress ofrece una experiencia de ejecución mucho más visual y orientada al navegador. Integrar estos flujos dentro de una estrategia moderna de QA con IA permite una cobertura aún más amplia. Y si necesitas ayuda implementando una estrategia de QA completa en tu empresa, no dudes en contactarme.
Qué tipos de diálogos puedes encontrarte en Cypress
Cuando hablamos de “cypress alert handling” en Cypress, en realidad solemos hablar de cuatro escenarios:
window.alert()window.confirm()window.prompt()- avisos de navegación como
beforeunload
Cypress documenta explícitamente window:alert, window:confirm, window:before:load, window:before:unload y window:unload dentro de su catálogo oficial de eventos.
Cómo instalar Cypress y dejar lista la base del proyecto
npm install cypress --save-dev
npx cypress open
Una configuración base razonable en TypeScript sería esta:
import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
supportFile: 'cypress/support/e2e.ts',
},
})
Cómo funciona alert en Cypress
Con window.alert(), Cypress hace algo muy concreto: acepta automáticamente el alert.
Ejemplo básico con window:alert
describe('Cypress alert handling', () => {
it('asserts alert text', () => {
cy.on('window:alert', (text) => {
expect(text).to.equal('User saved successfully')
})
cy.visit('/profile')
cy.get('[data-cy="save-button"]').click()
})
})
Cómo manejar confirm en Cypress
Con window.confirm(), Cypress también autoacepta por defecto, pero aquí sí hay una diferencia clave: puedes devolver false desde el evento para cancelar la confirmación.
Caso 1: aceptar el confirm
describe('Confirm dialog', () => {
it('accepts the confirm by default', () => {
cy.on('window:confirm', (text) => {
expect(text).to.equal('Do you want to delete this record?')
})
cy.visit('/records')
cy.get('[data-cy="delete-button"]').click()
})
})
Caso 2: cancelar el confirm
describe('Confirm cancellation', () => {
it('cancels the confirm when returning false', () => {
cy.on('window:confirm', (text) => {
expect(text).to.equal('Do you want to delete this record?')
return false
})
cy.visit('/records')
cy.get('[data-cy="delete-button"]').click()
})
})
Cómo manejar prompt en Cypress
Lo que sí documenta oficialmente es la forma correcta de controlar prompt: stubear window.prompt.
describe('Prompt dialog', () => {
it('stubs window.prompt and returns a custom value', () => {
cy.visit('/profile', {
onBeforeLoad(win) {
cy.stub(win, 'prompt').returns('Néstor')
},
})
cy.get('[data-cy="edit-name"]').click()
cy.window().its('prompt').should('be.called')
})
})
Cómo validar navegación con beforeunload
Cypress documenta los eventos window:before:unload y permite inspeccionarlo.
describe('Before unload warning', () => {
it('asserts unsaved changes protection', () => {
cy.on('window:before:unload', (e) => {
expect(e.returnValue).to.exist
})
cy.visit('/editor')
cy.get('[data-cy="title"]').type('Draft article')
cy.get('a[href="/dashboard"]').click()
})
})
cy.on() vs Cypress.on(): diferencia importante
Para alerts y confirms de un test concreto, normalmente conviene esto:
cy.on('window:confirm', handler)
Y no esto:
Cypress.on('window:confirm', handler) // Riesgo: Contaminación global de suite
Errores típicos al manejar dialogs en Cypress
- Registrar el listener demasiado tarde: Si haces el click() y luego registras el listener, llegaste tarde.
- Intentar “hacer click” en un alert nativo: Cypress lo acepta automáticamente, no busques el botón en el DOM.
- Stubear prompt demasiado tarde: Hazlo dentro de
onBeforeLoad. - Mezclar dialogs nativos con modales HTML: Componentes de React/Vue *no* son window.alert().
Conclusión
La forma profesional de manejar alerts en Cypress no consiste en “forzar clicks” sobre popups del navegador, sino en entender el contrato correcto de cada diálogo. Todo esto está respaldado por la documentación oficial. Cuando lo haces así, los tests quedan robustos, más claros y mucho más mantenibles.