【问题标题】:How do I check if an alert is present quickly?如何快速检查警报是否存在?
【发布时间】:2016-11-03 02:55:54
【问题描述】:

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

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

但是,这需要相同的时间。查看source code of ExpectedConditions.AlertIsPresent 揭示了原因 - 这正是我之前所做的,但只是在一个包装中..

我已将我的ImplicitWait 设置为 0。

这是在 Selenium 版本 2.53.1 上运行的。我的驱动程序是EventFiringWebDriverWrappedDriverFirefoxDriver。运行的 Firefox 版本是 47.0.1。

除了检查是否存在警报之外,还有其他方法可以减少花费的时间吗?

【问题讨论】:

  • 您使用的是哪个驱动程序和版本?一些司机有一个隐含的等待时间来切换到警报。
  • 将此行为仅归因于异常处理是错误的。延迟可能是由于您使用的浏览器的驱动程序造成的。例如,有一次,在开源 Firefox 驱动程序(驱动程序本身,而不是语言绑定)中有一个硬编码的睡眠切换到警报,因为不能保证窗口管理器会完全绘制警报.是的,2-3 秒的延迟很糟糕,但我们不要对它的原因妄下结论,错误地将其归咎于异常处理。
  • 你可以参考这个,如果有帮助的话:stackoverflow.com/questions/14737095/…
  • @JimEvans 我已经用版本信息更新了原始问题,谢谢。
  • 您可以尝试使用 javascript 来检测 javascript 执行程序是否存在警报吗? --- stackoverflow.com/questions/4866986/…

标签: c# .net selenium selenium-webdriver


【解决方案1】:

简短的回答是,“不,在使用旧版 Firefox 驱动程序时,无法避免在确定警报不存在时出现 2 秒延迟。”

更长的答案是 WebDriver API 的理念是您应该始终了解您正在自动化的页面的状态。一旦您要求 API 以某种方式与浏览器交互,您应该知道交互后页面的预期状态是什么。因此,只有在您希望出现警报的情况下才需要切换到警报。尝试切换到不存在警报的警报是一种异常情况,因此会正确地抛出异常(根据 API 的原理)。

在旧版 Firefox 驱动程序的特定情况下,无法判断窗口管理器是否已完全绘制警报,因此it hard-codes a two-second sleep 用于定位存在警报。请注意,旧版 Firefox 驱动程序要求它可以跨平台工作,因此 Windows 可能不需要此延迟这一事实并不是删除它的理由。此外,这个旧版驱动程序已被弃用,will not work with any version of Firefox 48 and higher

好消息是其他浏览器驱动程序不应该有这个限制,所以它们不应该遭受这种类型的延迟。还应该指出的是,Firefox 驱动程序的下一次迭代(代号 Marionette,由 Mozilla 创建和维护,以及 Firefox 48 及更高版本自动化所需的机制)也可能不会受到这种延迟的影响.

【讨论】:

  • 嗨,吉姆,非常感谢您的回答。我从中了解到的是,目前没有办法在使用 Firefox 时避免延迟,我应该等待 Marionette 驱动程序。对吗?
  • 要么这样,要么重组你的代码,这样你就不会不必要地寻找不存在的警报。我很抱歉我的回答在这一点上不清楚。附带说明一下,您现在可以使用 Marionette,尽管 Mozilla 还没有实现一些功能。
【解决方案2】:

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

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

在这里,保持 TimeSpan.FromSeconds(1) 仅等待one second(或根据您的要求等待 0.5 秒)。请根据您的要求更改代码(我不了解 C#)。关键是 webdriver 等待多长时间来检查预期条件是否为真。

参考资料:

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

【讨论】:

  • 您从哪里得知driver.Manage().Timeouts().ImplicitlyWait 对切换到警报有影响?
  • 虽然我没有实际尝试过,但我在某处读到的警报是 DOM 级别 0 的一部分。所以认为implicit_wait 可能会对警报产生影响。 stackoverflow.com/questions/10166330/…。如果我错了,请纠正我。
  • @FLSH,请尝试并让我们知道隐式等待是否适合您(在警报的情况下)。
  • @FlorentB。我可以确认隐式等待对切换到警报所用的时间没有影响。
  • @Naveen 害怕 - 我将 PollingInterval 设置为 50ms 但是在调试时我可以看到它会轮询一次,然后由于 timeout 参数在 1 秒后超时(并引发异常)。
猜你喜欢
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2012-07-13
  • 2021-03-08
  • 2021-05-14
  • 1970-01-01
  • 2020-08-27
  • 2013-09-30
相关资源
最近更新 更多