Cómo manejar popups y alertas en Playwright con Python: guía práctica

Una de las situaciones que más bloquea a la gente cuando empieza con Playwright es encontrarse con un popup o una alerta en medio de un test y no saber cómo manejarlo. El navegador se queda esperando, el test falla y no queda claro por qué. En este artículo te explico cómo manejar todos los tipos de popups y alertas que puedes encontrarte.


Los tipos de popups que puedes encontrar

Antes de ver el código, es importante distinguir los diferentes tipos de elementos emergentes porque cada uno se maneja de forma diferente en Playwright.

Alertas del navegador (dialogs) — son las ventanas nativas del navegador generadas con alert(), confirm() y prompt() de JavaScript. Tienen un aspecto muy básico y no pueden ser estilizadas.

Ventanas emergentes (popups) — son nuevas pestañas o ventanas del navegador que se abren al hacer clic en un enlace o botón. Se comportan como páginas independientes.

Modales — son elementos HTML que aparecen sobre el contenido principal de la página. No son ventanas del navegador sino elementos del DOM que se pueden localizar con locators normales.

Tooltips y dropdowns — son elementos que aparecen al pasar el ratón o hacer clic. También son elementos del DOM y se manejan con locators normales.


Manejar alertas del navegador — alert(), confirm() y prompt()

Las alertas del navegador son las más comunes en tests y las que más confusión generan. Playwright las gestiona con el evento dialog.

alert() — alerta simple

python

from playwright.sync_api import Page

def test_alerta_simple(page: Page):
    # Registrar el handler ANTES de que se dispare la alerta
    page.on("dialog", lambda dialog: dialog.accept())
    
    page.goto("https://miweb.com")
    page.click("#btn-alerta")
    
    # El test continúa después de aceptar la alerta automáticamente
    assert page.locator(".resultado").is_visible()

Lo más importante es registrar el handler antes de que la alerta aparezca. Si lo registras después, el test se quedará bloqueado esperando.

confirm() — diálogo de confirmación

El diálogo confirm() tiene dos botones — Aceptar y Cancelar. Puedes elegir cuál pulsar:

python

def test_confirmacion_aceptar(page: Page):
    # Aceptar el confirm
    page.on("dialog", lambda dialog: dialog.accept())
    
    page.click("#btn-eliminar")
    assert page.locator(".elemento").count() == 0

def test_confirmacion_cancelar(page: Page):
    # Cancelar el confirm
    page.on("dialog", lambda dialog: dialog.dismiss())
    
    page.click("#btn-eliminar")
    assert page.locator(".elemento").count() == 1

prompt() — diálogo con entrada de texto

El diálogo prompt() espera que el usuario introduzca texto. En Playwright puedes pasarle el texto directamente:

python

def test_prompt(page: Page):
    # Introducir texto en el prompt y aceptar
    page.on("dialog", lambda dialog: dialog.accept("Mi texto de prueba"))
    
    page.click("#btn-prompt")
    assert "Mi texto de prueba" in page.locator(".resultado").text_content()

Verificar el mensaje del diálogo

Puedes también verificar el texto del mensaje antes de aceptar o cancelar:

python

def test_verificar_mensaje_alerta(page: Page):
    mensajes_recibidos = []
    
    def manejar_dialog(dialog):
        mensajes_recibidos.append(dialog.message)
        dialog.accept()
    
    page.on("dialog", manejar_dialog)
    page.click("#btn-alerta")
    
    assert "¿Estás seguro?" in mensajes_recibidos[0]

Manejar popups — nuevas ventanas y pestañas

Cuando hacer clic en un enlace o botón abre una nueva pestaña o ventana, necesitas capturar esa nueva página para poder interactuar con ella.

python

def test_nueva_pestana(page: Page):
    # Esperar a que se abra la nueva página
    with page.expect_popup() as popup_info:
        page.click("#btn-abrir-nueva-pestana")
    
    nueva_pagina = popup_info.value
    
    # Esperar a que cargue
    nueva_pagina.wait_for_load_state()
    
    # Interactuar con la nueva página
    assert "Nueva página" in nueva_pagina.title()
    nueva_pagina.click("#btn-cerrar")

El expect_popup() funciona como un contexto que captura la nueva ventana en el momento en que se abre. Todo lo que ocurra dentro del bloque with puede disparar el popup.


Manejar múltiples popups

Si tu aplicación puede abrir varios popups, puedes gestionarlos todos con el evento popup del contexto del navegador:

python

def test_multiples_popups(page: Page):
    paginas_abiertas = []
    
    page.context.on("page", lambda nueva_pagina: paginas_abiertas.append(nueva_pagina))
    
    page.click("#btn-abrir-popup-1")
    page.click("#btn-abrir-popup-2")
    
    # Esperar a que carguen las dos páginas
    for p in paginas_abiertas:
        p.wait_for_load_state()
    
    assert len(paginas_abiertas) == 2

Manejar modales — la forma más sencilla

Los modales son simplemente elementos HTML — no son ventanas del navegador. Se manejan exactamente igual que cualquier otro elemento de la página con locators normales.

python

def test_modal(page: Page):
    # Abrir el modal
    page.click("#btn-abrir-modal")
    
    # Verificar que el modal está visible
    modal = page.locator(".modal")
    assert modal.is_visible()
    
    # Interactuar con el contenido del modal
    page.fill(".modal input#nombre", "Fátima")
    page.click(".modal button#confirmar")
    
    # Verificar que el modal se cerró
    assert not modal.is_visible()

Manejar tooltips y dropdowns

Los tooltips aparecen al pasar el ratón por encima de un elemento. En Playwright puedes simular el hover con hover():

python

def test_tooltip(page: Page):
    # Pasar el ratón por encima del elemento
    page.hover("#icono-ayuda")
    
    # Verificar que el tooltip es visible
    tooltip = page.locator(".tooltip")
    assert tooltip.is_visible()
    assert "Información de ayuda" in tooltip.text_content()

Para dropdowns que se abren al hacer clic:

python

def test_dropdown(page: Page):
    # Abrir el dropdown
    page.click("#menu-usuario")
    
    # Verificar que las opciones son visibles
    assert page.locator(".dropdown-menu").is_visible()
    
    # Hacer clic en una opción
    page.click(".dropdown-menu li:has-text('Mi perfil')")
    
    assert "perfil" in page.url

El error más común — registrar el handler demasiado tarde

El error que comete casi todo el mundo al empezar es intentar registrar el handler después de que la alerta ya se ha disparado.

python

# MAL — el test se bloquea porque la alerta aparece antes del handler
page.click("#btn-alerta")
page.on("dialog", lambda dialog: dialog.accept())  # Demasiado tarde

# BIEN — el handler se registra antes de disparar la alerta
page.on("dialog", lambda dialog: dialog.accept())
page.click("#btn-alerta")

Si quieres profundizar en Playwright puedes leer cómo usar locators en Playwright o cómo eliminar tests flaky.

Y si necesitas implementar automatización con Playwright en tu proyecto puedes ver mis servicios en fatimaqa.com.

Scroll al inicio