¿Cómo puedo esperar de manera confiable las alertas de JavaScript usando Selenium2 / WebDriver?
-
25-10-2019 - |
Pregunta
Actualmente estoy ayudando en una prueba de concepto utilizando Selenium 2 / WebDriver con C# contra una aplicación ASP.NET MVC utilizando InternetexplorerDriver.
La aplicación utiliza un patrón estándar para notificar a los usuarios que ha guardado un registro. Esto funciona mediante configuración tempData para incluir "registro guardado con éxito", y si TempData está presente en la vista, la vista alertará el mensaje.
Mientras trabajamos en las pruebas de selenio para esta funcionalidad, estamos recibiendo un comportamiento inconstitante del siguiente código de prueba C# / selenio:
_driver.Navigate().GoToUrl(_baseUrl + "/Amraam/List");
_driver.FindElement(By.LinkText("Create New")).Click();
_driver.FindElement(By.Id("txtAmraamSerialNumber")).SendKeys("CC12345");
var selectElement = new SelectElement(_driver.FindElement(By.Id("LocationId")));
selectElement.SelectByText("Tamworth");
_driver.FindElement(By.Id("btnSave")).Click();
var wait = new WebDriverWait(_driver, defaultTimeout);
IAlert alert = wait.Until(drv => drv.SwitchTo().Alert());
_alertText = alert.Text;
alert.Accept();
Assert.That(_alertText, Is.EqualTo("Record successfully saved"));
Aproximadamente el 50% del tiempo, Selinium fallará con un
Openqa.Selenium.NoAlertPresentException: ninguna alerta está activa
Me cuesta encontrar una forma exacta de replicar el problema y preocuparme con el aspecto de inconsistencia. Si fallaba constantemente, entonces podríamos depurar y rastrear el problema.
Solución
El manejo de alertas y indicaciones dentro de Selenium 2 es bastante nuevo y todavía está bajo desarrollo activo. Sus fallas probablemente se deban a la sincronización, por lo que sugeriría escribir un método de envoltura alrededor de la llamada a switchto (). Alert () para que atraiga el Openqa.Selenium.NoAlertPresentException e ignore hasta que expire el tiempo de espera.
Algo tan simple como esto debería funcionar:
private IAlert AlertIsPresent(IWebDriver drv)
{
try
{
// Attempt to switch to an alert
return drv.SwitchTo().Alert();
}
catch (OpenQA.Selenium.NoAlertPresentException)
{
// We ignore this execption, as it means there is no alert present...yet.
return null;
}
// Other exceptions will be ignored and up the stack
}
Esta línea
IAlert alert = wait.Until(drv => drv.SwitchTo().Alert());
Entonces se convertiría en
IAlert alert = wait.Until(drv => AlertIsPresent(drv));