问题 如何使用Selenium2 / WebDriver可靠地等待JavaScript警报?


我目前正在协助使用Selenium 2 / WebDriver和C#对使用InternetExplorerDriver的ASP.NET MVC应用程序进行概念验证。

应用程序使用标准模式通知用户记录已保存。这可以通过设置TempData来包含“Record saved successcessefully”,如果View中存在TempData,则视图将提醒消息。

在针对此功能进行Selenium测试时,我们从以下C#/ Selenium测试代码中获得了不一致的行为:

        _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")); 

大约50%的时间,Selinium将失败

OpenQA.Selenium.NoAlertPresentException:没有警报处于活动状态

我很难找到复制问题的确切方法,并担心不一致方面。如果它一直失败,那么我们可以调试并跟踪问题。


7812
2017-11-29 12:17


起源



答案:


Selenium 2中警报和提示的处理非常新,并且仍在积极开发中。 你的失败可能是由于时间问题,所以我建议围绕调用SwitchTo()。Alert()编写一个包装器方法,以便捕获OpenQA.Selenium.NoAlertPresentException并忽略它直到超时到期。

像这样简单的东西应该工作:

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
}

这条线

IAlert alert = wait.Until(drv => drv.SwitchTo().Alert());

然后会成为

IAlert alert = wait.Until(drv => AlertIsPresent(drv));

15
2017-11-30 08:18



为此欢呼。实际上,进一步的工作,我们发现这实际上并不是硒的问题,但实际上是我们的应用程序测试,并点击按钮点击javascript事件(不要问...)无论如何,selenium表现自己。 @Naishy,你的回答看起来很棒,而且我们本来会尝试过 - 欢呼。 - Paul Williams
您可以使用方法组语法使最后一行更简洁; IAlert alert = wait.Until(AlertIsPresent);。 - Richard Everett
现在您可以使用ExpectedCondition.AlertIsPresent参见: stackoverflow.com/a/24550934/200824 - Bob Lokerse


答案:


Selenium 2中警报和提示的处理非常新,并且仍在积极开发中。 你的失败可能是由于时间问题,所以我建议围绕调用SwitchTo()。Alert()编写一个包装器方法,以便捕获OpenQA.Selenium.NoAlertPresentException并忽略它直到超时到期。

像这样简单的东西应该工作:

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
}

这条线

IAlert alert = wait.Until(drv => drv.SwitchTo().Alert());

然后会成为

IAlert alert = wait.Until(drv => AlertIsPresent(drv));

15
2017-11-30 08:18



为此欢呼。实际上,进一步的工作,我们发现这实际上并不是硒的问题,但实际上是我们的应用程序测试,并点击按钮点击javascript事件(不要问...)无论如何,selenium表现自己。 @Naishy,你的回答看起来很棒,而且我们本来会尝试过 - 欢呼。 - Paul Williams
您可以使用方法组语法使最后一行更简洁; IAlert alert = wait.Until(AlertIsPresent);。 - Richard Everett
现在您可以使用ExpectedCondition.AlertIsPresent参见: stackoverflow.com/a/24550934/200824 - Bob Lokerse