【问题标题】:Is there a change in the handling of unhandled alert in ChromeDriver and Chrome with Selenium?ChromeDriver 和 Chrome with Selenium 中未处理警报的处理是否有变化?
【发布时间】:2023-03-08 23:46:01
【问题描述】:

我有一个测试已经运行好几个月了。它所做的一件事是引发警报,然后验证警报文本。这是使用 Selenium、Java 和 Chrome 驱动程序 76.0.3809.68 运行的。

最近它一直给我错误:

“没有这样的警报”。

发生的情况是它单击一个按钮并等待警报(如果有):

 try {
    button.click();
 } catch (UnhandledAlertException ex) {
   // nothing
 }

 // then here goes code to accept the alert and get the text

在单步执行时,我看到了警报。当我运行它时,我看到了警报,但它消失了。我确实在(Chrome 驱动程序)发行说明中阅读了一些关于意外警报的内容,但有点含糊。

我们有一个为 Chrome 设置选项的全局页面,但每个人都在使用它,我不想为其他人搞砸。我在本地做了(没有 git push),当我在创建驱动程序之前设置选项时它工作了。

然后我尝试这样做,这似乎不起作用。是否应该,或者一旦检索到网页,您可以不更改选项吗?

 // Somewhere after web page retrieved this gets called:

public void setIgnoreAlert() {
    ChromeDriver cd = (ChromeDriver) driver;
    ChromeOptions cap = new ChromeOptions();
    cap.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE);
    Capabilities other = cap;
    cd.getCapabilities().merge(other);
 }

我真的希望这能奏效,但没有。您是否必须在 Chrome 实例出现之前设置行为?也就是不能像我上面那样设置吗?关于 Chrome 实例启动后如何设置它的任何其他建议?

--- 稍后添加以回答问题

这是在带有 button.click() 的 try-catch 块之后立即完成的:

configPage.getAndHandleAlertPopUp() 方法执行以下操作:

public String getAndHandleAlertPopUp() {
    Alert alert = driver.switchTo().alert();
    String alertPopup = alert.getText();
    alert.accept();
    return alertPopup;
}

【问题讨论】:

  • 在初始化驱动之前在选项中设置。 options.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.IGNORE) 如果警报仍然存在,这将在执行某些后续操作时引发期望。如果你自己处理警报,你应该会很好。
  • 顺便说一句,默认似乎是 DISMISS_AND_NOTIFY 现在...关闭提示,但仍然抛出异常(我猜这是“通知”部分)。 ACCEPT 和 DISMISS 将关闭所有提示而不抛出异常。
  • 顺便说一句,如果您可以保留选项,但请注意,您必须在提示出现时立即处理。您用于检查文本的代码可能会抛出异常,具体取决于它的作用。这显示了新 Chrome 驱动程序遵循的 W3C 算法:w3.org/TR/webdriver1/#navigation 每当您看到“处理任何用户提示”......这就是意外警报行为发挥作用的地方。

标签: selenium google-chrome selenium-chromedriver alert webdriverwait


【解决方案1】:

你没看错。根据WebDriver - W3C Recommendation 中的User Prompts 部分:

用户提示的共同点是它们是模式窗口,需要用户在事件循环取消暂停并将控制返回到当前顶级浏览上下文之前与其交互。

除非已定义用户提示处理程序,否则默认情况下不会自动处理用户提示。当出现用户提示时,处理它是后续命令的任务。如果后续请求的命令不是本章列出的命令,则会返回意外的警报打开错误。

从 beforeunload 事件处理程序产生的用户提示,在导航或关闭窗口时被隐式关闭,无论定义的用户提示处理程序如何。

用户提示具有关联的用户提示消息,它是向用户显示的字符串消息,如果消息长度为 0,则为 null。


根据ChromeDriver should return user prompt (or alert) text in unhandled alert error response中的讨论:

当触发用户提示处理程序时,W3C 规范规定错误响应应返回“带注释的意外警报打开错误”,其中包括包含 user prompt 文本的可选字典。 ChromeDriver 应提供可选信息。


显然,ChromeDriver 不符合此标准,因为 @Test@NotYetImplemented 注释如下:

  @Test
  @NotYetImplemented(CHROME)
  @NotYetImplemented(CHROMIUMEDGE)
  @Ignore(value = HTMLUNIT, reason = "https://github.com/SeleniumHQ/htmlunit-driver/issues/57")
  @NotYetImplemented(value = MARIONETTE,
      reason = "https://bugzilla.mozilla.org/show_bug.cgi?id=1279211")
  @NotYetImplemented(EDGE)
  public void testIncludesAlertTextInUnhandledAlertException() {
    driver.get(alertPage("cheese"));

    driver.findElement(By.id("alert")).click();
    wait.until(alertIsPresent());

    assertThatExceptionOfType(UnhandledAlertException.class)
    .isThrownBy(driver::getTitle)
    .withMessageContaining("cheese")
    .satisfies(ex -> assertThat(ex.getAlertText()).isEqualTo("cheese"));
  }

现在这个功能已经用ChromeDriver v76.0实现了:

已解决问题 2869:ChromeDriver 应在未处理的警报错误响应 [Pri-2] 中返回用户提示(或警报)文本

因此,您必须将警报作为强制性措施来处理。


的更多代码块......然后这里是接受警报并获取文本的代码......会帮助我们以更好的方式调试问题。但是这里有一些选项:

注意:一旦 WebDriverWeb Browser 实例被初始化,您将无法在运行时更改配置。即使您能够从浏览会话中提取Session IDCookies 和其他功能和会话属性,您仍然无法更改WebDriver 的这些属性。

您可以在How can I reconnect to the browser opened by webdriver with selenium?找到详细讨论

【讨论】:

  • 是的,但我认为 setIgnoreAlert() 是无效的,因为驱动程序已经创建。我确实得到了我们的领导,给了我一个可以在我的@DataProvider 中设置的属性,以使驱动程序被忽略。我自己做不到。我必须设置属性。如果没有设置,那么它将保持默认值,我猜是接受和关闭(但抛出错误)
  • 我在问题中添加了几段内容,显示在新的 Chromedriver 版本之前如何处理警报。现在有了新的,它被解雇了,所以它不能被切换到。
  • @Tony 检查答案更新,如果有任何疑问,请告诉我。
  • 谢谢。我让他们为我添加了一种在创建驱动程序之前指定“忽略”的方法。这样可行。我还想,与其切换到警报并获取文本并接受,我可以捕获警报错误并从警报消息中获取文本,并模拟实际拦截错误。
  • @DebanjanB 我应该添加什么 Maven 依赖项以及要导入什么库才能使用 opt.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE) ?目前我的 IntelliJ 不知道什么是 CapabilityType 和什么是 UnexpectedAlertBehaviour?提前致谢!
猜你喜欢
  • 2023-01-02
  • 1970-01-01
  • 2021-11-15
  • 2022-09-23
  • 2017-06-29
  • 2021-09-23
  • 2011-10-07
  • 2018-12-21
  • 1970-01-01
相关资源
最近更新 更多