如何快速检查是否存在警报?

3

在尝试检查是否存在警报时,我调用了一个名为AlertIsDisplayed的扩展方法,在IWebDriver上,该方法如下:

try
{
    Driver.Instance.SwitchTo().Alert();

    return true;
}
catch (NoAlertPresentException)
{
    return false;
}
finally
{
    Driver.Instance.SwitchTo().DefaultContent();
}

然而,由于我要捕获一个异常,这导致返回结果的时间相当昂贵,需要2-3秒钟。由于在数百个测试中都使用了这种方法,所以额外的执行时间累加起来会达到几分钟。

为了加速处理,我尝试将同样的方法更改为以下内容:

return ExpectedConditions.AlertIsPresent()(driver) != null;

在此,driver是调用扩展方法的IWebDriver

然而,这需要同样的时间。查看源代码ExpectedConditions.AlertIsPresent可以发现原因 - 这正是我以前做的事情,但只是将其封装在一个包装器中。

我已将ImplicitWait设置为0。

这是在Selenium 2.53.1上运行的。我的驱动程序是一个EventFiringWebDriver,其中WrappedDriverFirefoxDriver。运行此程序的Firefox版本为47.0.1。

有没有检查是否存在警报的替代方法,需要更少的时间?


你正在使用哪个驱动程序和版本?某些驱动程序具有切换到警告框的隐式等待时间。 - Florent B.
仅将此行为归因于异常处理是错误的。可能是由于您使用的浏览器驱动程序导致了延迟。例如,在某个时候,开源Firefox驱动程序(驱动程序本身而不是语言绑定)中有一个硬编码的睡眠切换到警报,因为不能保证窗口管理器完全绘制警报。是的,2-3秒的延迟很糟糕,但让我们不要草率地得出结论,错误地将其归咎于异常处理。 - JimEvans
请参考以下内容,了解如何验证警报是否存在:WebDriver如何验证警报是否存在 - Priya P
@JimEvans 我已经更新了原始问题并提供了版本信息,谢谢。 - FLSH
你能否尝试使用JavaScript执行器来检测警告框是否存在?---https://dev59.com/AG445IYBdhLWcg3wapzF - Grasshopper
@FLSH 使用传统的开源Firefox驱动程序,很容易就能看到(https://github.com/SeleniumHQ/selenium/blob/master/javascript/firefox-driver/js/firefoxDriver.js#L51),2秒延迟仍然存在。其他浏览器(Chrome,IE等)可能不会遭受同样的延迟。我已经提供了一个答案来详细说明这个问题,并解释了API设计背后的理论。 - JimEvans
2个回答

1
短答案是:“不,使用传统的Firefox驱动程序时,无法避免在确定警报不存在时出现2秒延迟。”
较长的答案是,WebDriver API的理念是您应该始终知道您正在自动化的页面状态。一旦您要求API以某种方式与浏览器交互,您应该知道该交互后页面的预期状态。因此,只有在期望存在警报的情况下才会切换到警报。尝试切换到没有警报的警报是一个异常情况,因此按照API的哲学,会正确地抛出异常。
在遗留的Firefox驱动程序特定情况下,无法确定窗口管理器是否完全绘制了警报,因此它硬编码了两秒的休眠来定位警报是否存在。请注意,遗留的Firefox驱动程序要求在跨平台工作,因此Windows可能不需要此延迟并不是删除它的理由。此外,这个遗留驱动程序已经被弃用,并且将不再与Firefox 48及更高版本一起使用
好消息是其他浏览器驱动程序不应该有这种限制,因此它们不应该遭受这种类型的延迟。还应指出,Firefox驱动程序的下一个版本(名为Marionette,由Mozilla创建和维护,并且是自动化Firefox 48及以上版本所需的机制)也很可能不会遇到这种类型的延迟。

嗨,吉姆,非常感谢你的回答。我理解的是,在使用Firefox时目前没有避免延迟的方法,我应该等待Marionette驱动程序。这正确吗? - FLSH
要么这样,要么重新构建你的代码,以便不必要地寻找不存在的警报。对此点我的回答不够清楚我感到抱歉。顺带一提,你可以今天就开始使用Marionette,尽管Mozilla还没有实现一些功能。 - JimEvans

0

预期条件显式等待):编写自己的预期条件。

    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(1));
    IWebElement myDynamicElement = wait.Until(ExpectedConditions.AlertIsPresent());

在这里,保留TimeSpan.FromSeconds(1) 只等待一秒钟(或根据您的要求0.5秒)。请根据您的需求更改代码(我不懂C#)。关键是WebDriver等待多长时间来检查期望条件是否为真。

参考资料:

  1. http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp

你从哪里得知 driver.Manage().Timeouts().ImplicitlyWait 对切换到警报有影响的? - Florent B.
虽然我没有实际尝试过,但在某个地方我读到警报是DOM 0级的一部分。所以我认为隐式等待可能会对警报产生影响。https://dev59.com/_mLVa4cB1Zd3GeqPzLlE。如果我错了,请纠正我。 - Naveen Kumar R B
@FLSH,请尝试并告诉我们隐式等待是否在警报的情况下起作用。 - Naveen Kumar R B
1
@FlorentB。我可以确认,隐式等待对切换到警报所需的时间没有影响。 - FLSH
1
@Naveen 很抱歉 - 我已将 PollingInterval 设置为50毫秒,但是在调试时我可以看到它只会轮询一次,然后由于超时参数在1秒后超时(并抛出异常)。 - FLSH
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接