Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusAlert Interface y switchTo().alert()
La interfaz Alert de Selenium WebDriver proporciona métodos especializados para interactuar con los diálogos modales de JavaScript que aparecen en las aplicaciones web. Estos diálogos interrumpen el flujo normal de la página y requieren una respuesta del usuario antes de poder continuar con la navegación.
El método driver.switchTo().alert()
es el punto de entrada principal para trabajar con estos diálogos. Este método devuelve una instancia de la interfaz Alert
, que contiene todos los métodos necesarios para gestionar las interacciones con los diferentes tipos de diálogos JavaScript.
Tipos de diálogos JavaScript
Los navegadores modernos soportan tres tipos principales de diálogos modales que podemos encontrar en aplicaciones web:
- Alert simple: Muestra un mensaje informativo con un único botón "Aceptar"
- Confirm: Presenta una pregunta con opciones "Aceptar" y "Cancelar"
- Prompt: Solicita entrada de texto del usuario junto con "Aceptar" y "Cancelar"
Métodos de la interfaz Alert
La interfaz Alert
proporciona cuatro métodos fundamentales para manejar estos diálogos:
Método accept()
Este método simula hacer clic en el botón "Aceptar" o "OK" del diálogo. Es aplicable a todos los tipos de alerts y representa la acción afirmativa del usuario.
@Test
void testSimpleAlert() {
driver.get("https://ejemplo.com/alert-demo");
// Activar el alert
driver.findElement(By.id("show-alert")).click();
// Cambiar al contexto del alert y aceptarlo
Alert alert = driver.switchTo().alert();
alert.accept();
// Verificar que el alert se cerró correctamente
assertTrue(driver.findElements(By.className("alert-closed")).size() > 0);
}
Método dismiss()
Simula hacer clic en "Cancelar" o presionar la tecla Escape. Solo es relevante para diálogos de tipo confirm y prompt, ya que los alerts simples no tienen opción de cancelar.
@Test
void testConfirmDialog() {
driver.get("https://ejemplo.com/confirm-demo");
driver.findElement(By.id("show-confirm")).click();
Alert alert = driver.switchTo().alert();
alert.dismiss(); // Seleccionar "Cancelar"
// Verificar el resultado de la cancelación
String resultado = driver.findElement(By.id("resultado")).getText();
assertEquals("Operación cancelada", resultado);
}
Método getText()
Extrae el contenido textual del mensaje mostrado en el diálogo. Este método es especialmente útil para validar que se muestra el mensaje correcto al usuario.
@Test
void testAlertMessage() {
driver.get("https://ejemplo.com/message-demo");
driver.findElement(By.id("delete-button")).click();
Alert alert = driver.switchTo().alert();
String mensaje = alert.getText();
assertEquals("¿Está seguro de que desea eliminar este elemento?", mensaje);
alert.accept();
}
Método sendKeys(String texto)
Permite introducir texto en diálogos de tipo prompt. Este método debe llamarse antes de aceptar o cancelar el diálogo para que el texto se registre correctamente.
@Test
void testPromptDialog() {
driver.get("https://ejemplo.com/prompt-demo");
driver.findElement(By.id("show-prompt")).click();
Alert alert = driver.switchTo().alert();
alert.sendKeys("Juan Pérez");
alert.accept();
// Verificar que el nombre se procesó correctamente
String saludo = driver.findElement(By.id("greeting")).getText();
assertEquals("Hola, Juan Pérez", saludo);
}
Flujo de trabajo con alerts
El patrón típico para manejar alerts en Selenium sigue una secuencia consistente:
@Test
void testCompleteAlertWorkflow() {
driver.get("https://ejemplo.com/complex-form");
// 1. Ejecutar acción que genera el alert
driver.findElement(By.id("submit-form")).click();
// 2. Cambiar al contexto del alert
Alert alert = driver.switchTo().alert();
// 3. Leer el mensaje (opcional)
String mensaje = alert.getText();
System.out.println("Mensaje del alert: " + mensaje);
// 4. Proporcionar input si es necesario (solo para prompts)
if (mensaje.contains("nombre")) {
alert.sendKeys("Datos del usuario");
}
// 5. Tomar decisión final
alert.accept(); // o alert.dismiss()
}
Manejo de múltiples alerts
Algunas aplicaciones pueden generar alerts en cadena o alerts condicionales. En estos casos, es importante manejar cada diálogo por separado:
@Test
void testMultipleAlerts() {
driver.get("https://ejemplo.com/multi-alert-demo");
driver.findElement(By.id("process-data")).click();
// Primer alert: confirmación
Alert firstAlert = driver.switchTo().alert();
assertEquals("¿Procesar los datos?", firstAlert.getText());
firstAlert.accept();
// Segundo alert: resultado
Alert secondAlert = driver.switchTo().alert();
assertTrue(secondAlert.getText().contains("Procesamiento completado"));
secondAlert.accept();
}
La gestión correcta de alerts requiere entender que una vez que se llama a switchTo().alert()
, el contexto del driver cambia temporalmente al modal. Después de interactuar con el alert mediante accept()
o dismiss()
, el contexto regresa automáticamente a la página principal, permitiendo continuar con las interacciones normales del DOM.
ExpectedConditions.alertIsPresent()
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
La clase ExpectedConditions de Selenium WebDriver proporciona el método alertIsPresent()
como una condición de espera explícita especializada para detectar la presencia de diálogos JavaScript. Este método es fundamental para crear pruebas robustas que manejen la naturaleza asíncrona de los alerts en aplicaciones web modernas.
Importancia de las esperas explícitas con alerts
Los diálogos JavaScript pueden aparecer con retrasos variables dependiendo de factores como la carga del servidor, la velocidad de la red, o la ejecución de código JavaScript complejo. Intentar acceder a un alert que aún no ha aparecido resulta en una NoAlertPresentException
, lo que hace que las pruebas fallen de manera inconsistente.
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.time.Duration;
@Test
void testAlertWithExplicitWait() {
driver.get("https://ejemplo.com/delayed-alert");
// Activar acción que genera alert con retraso
driver.findElement(By.id("async-alert-button")).click();
// Esperar hasta que el alert esté presente
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
assertEquals("Proceso completado", alert.getText());
alert.accept();
}
Sintaxis y uso básico
El método alertIsPresent()
devuelve una instancia de Alert
cuando el diálogo está disponible, permitiendo encadenar directamente las operaciones de interacción sin necesidad de llamar nuevamente a switchTo().alert()
.
@Test
void testAlertPresentCondition() {
driver.get("https://ejemplo.com/form-validation");
// Enviar formulario con datos inválidos
driver.findElement(By.id("email")).sendKeys("email-invalido");
driver.findElement(By.id("submit")).click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
// Esperar y obtener el alert directamente
Alert validationAlert = wait.until(ExpectedConditions.alertIsPresent());
assertTrue(validationAlert.getText().contains("formato de email"));
validationAlert.accept();
}
Manejo de timeouts y excepciones
Cuando el tiempo de espera se agota sin que aparezca un alert, se lanza una TimeoutException
. Este comportamiento permite distinguir entre alerts que tardan en aparecer y situaciones donde no se espera ningún alert.
@Test
void testNoAlertScenario() {
driver.get("https://ejemplo.com/no-alert-form");
driver.findElement(By.id("valid-submit")).click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
// Verificar que NO aparece ningún alert
assertThrows(TimeoutException.class, () -> {
wait.until(ExpectedConditions.alertIsPresent());
});
// Continuar con la verificación normal
assertTrue(driver.getCurrentUrl().contains("success"));
}
Combinación con otras condiciones
ExpectedConditions.alertIsPresent()
puede combinarse con otras condiciones de espera para crear flujos de prueba más complejos que manejen múltiples escenarios posibles.
@Test
void testConditionalAlert() {
driver.get("https://ejemplo.com/conditional-processing");
driver.findElement(By.id("process-data")).click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(8));
try {
// Intentar detectar alert de error
Alert errorAlert = wait.until(ExpectedConditions.alertIsPresent());
if (errorAlert.getText().contains("Error")) {
System.out.println("Procesamiento falló: " + errorAlert.getText());
errorAlert.accept();
// Reintento después del error
driver.findElement(By.id("retry-button")).click();
}
} catch (TimeoutException e) {
// No hay alert, el procesamiento fue exitoso
WebElement successMessage = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("success-message"))
);
assertTrue(successMessage.isDisplayed());
}
}
Patrones de espera reutilizables
Es recomendable crear métodos auxiliares que encapsulen la lógica de espera de alerts para mejorar la reutilización y mantenibilidad del código de pruebas.
private Alert waitForAlert(Duration timeout) {
WebDriverWait wait = new WebDriverWait(driver, timeout);
return wait.until(ExpectedConditions.alertIsPresent());
}
private boolean isAlertPresent(Duration timeout) {
try {
WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.until(ExpectedConditions.alertIsPresent());
return true;
} catch (TimeoutException e) {
return false;
}
}
@Test
void testWithHelperMethods() {
driver.get("https://ejemplo.com/dynamic-alerts");
driver.findElement(By.id("trigger-alert")).click();
if (isAlertPresent(Duration.ofSeconds(5))) {
Alert alert = waitForAlert(Duration.ofSeconds(2));
alert.accept();
} else {
fail("Se esperaba un alert pero no apareció");
}
}
Verificación de alerts inesperadas
En aplicaciones complejas, pueden aparecer alerts no planificados debido a errores o comportamientos inesperados. Es útil implementar verificaciones que detecten estos casos.
@Test
void testUnexpectedAlertDetection() {
driver.get("https://ejemplo.com/complex-workflow");
// Ejecutar flujo normal
driver.findElement(By.id("start-workflow")).click();
// Verificar si aparece algún alert inesperado
WebDriverWait shortWait = new WebDriverWait(driver, Duration.ofSeconds(2));
try {
Alert unexpectedAlert = shortWait.until(ExpectedConditions.alertIsPresent());
// Registrar el alert inesperado para debugging
String alertText = unexpectedAlert.getText();
System.err.println("Alert inesperado detectado: " + alertText);
// Decidir cómo manejar el alert
if (alertText.contains("Error")) {
unexpectedAlert.accept();
fail("El workflow generó un error inesperado: " + alertText);
} else {
unexpectedAlert.accept();
}
} catch (TimeoutException e) {
// No hay alerts inesperados, continuar normalmente
assertTrue(driver.findElement(By.id("workflow-status")).isDisplayed());
}
}
Mejores prácticas para timeouts
La configuración de timeouts apropiados es crucial para el rendimiento de las pruebas. Timeouts muy largos ralentizan las pruebas cuando no hay alerts, mientras que timeouts muy cortos pueden causar fallos en aplicaciones lentas.
@Test
void testOptimalTimeouts() {
driver.get("https://ejemplo.com/variable-timing");
// Timeout corto para alerts rápidos
WebDriverWait quickWait = new WebDriverWait(driver, Duration.ofSeconds(3));
// Timeout largo para operaciones complejas
WebDriverWait longWait = new WebDriverWait(driver, Duration.ofSeconds(15));
driver.findElement(By.id("quick-action")).click();
try {
Alert quickAlert = quickWait.until(ExpectedConditions.alertIsPresent());
quickAlert.accept();
} catch (TimeoutException e) {
// Si no hay alert rápido, intentar operación lenta
driver.findElement(By.id("slow-action")).click();
Alert slowAlert = longWait.until(ExpectedConditions.alertIsPresent());
slowAlert.accept();
}
}
El uso correcto de ExpectedConditions.alertIsPresent()
garantiza que las pruebas sean estables y predecibles, eliminando las condiciones de carrera que pueden causar fallos intermitentes en entornos de integración continua.
Aprendizajes de esta lección de Selenium
- Comprender la interfaz Alert y su método switchTo().alert() para interactuar con diálogos modales.
- Identificar los tipos de diálogos JavaScript: alert, confirm y prompt.
- Aprender a usar los métodos accept(), dismiss(), getText() y sendKeys() para gestionar alerts.
- Implementar esperas explícitas con ExpectedConditions.alertIsPresent() para manejar la asincronía de los alerts.
- Aplicar buenas prácticas en la gestión de múltiples alerts, manejo de excepciones y configuración de timeouts.
Completa este curso de Selenium y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs