如何从发起警报的页面恢复 "text",尤其是在**人类用户*点击* [关闭] 页面的**警报**之后?

How do I recover the "text" from the page originating the alert, esp **after** the human user has *clicked* [dismiss] on the page's **alert**?

基本上,当在 java 脚本中弹出警报时,我可以 dismiss() 从 python 调用 selenium.webdriver.common.alert.Alert(browser).dismiss().[=39= 完全没问题。 ]

但是,如果 "browser user" 通过用鼠标单击 [OK](在屏幕上)来解除警报,则浏览器警报会 "Lost in Space" body.text 无法不再可以从 python.

访问

那么...如何从发出警报的页面恢复 "text",尤其是在 人类用户 click [dismiss] 在页面的 alert?

这里是提示和演示问题的脚本...

仅供参考:原始代码的 objective 是否允许 浏览器用户 干预 在屏幕上 进行测试和手动对特定警报的响应。

#!/usr/bin/env python
import os,sys,time
import selenium.webdriver
import selenium.webdriver.support.expected_conditions

print dict(python=sys.version,selenium=selenium.__version__)

path=os.path.join(os.getcwd(),"hello_worlds.html")
url="file:///"+path

open(path,"w").write("""<HTML>
  <HEAD><TITLE>Head Title</TITLE></HEAD>
  <BODY><H1>Hello, worlds!</H1></BODY>
</HTML> """)

browser=selenium.webdriver.Firefox()
browser.get(url)

body=browser.find_element_by_tag_name("body")
print "BODY:",body.text

try:

  for enum,world in enumerate("Mercury Venus Earth Mars Asteroids Jupiter Saturn Uranus Neptune".split()):

    if "Earth" in world: world+=": So do MANUALLY dismiss! {Click [OK] now!!!}"
    else: world+=": AUTO PILOT... please DONT dismiss! {done via selenium.dismiss()!}"

    browser.execute_script('alert("Hello, %s!")'%world)
    if selenium.webdriver.support.expected_conditions.alert_is_present():
      print selenium.webdriver.common.alert.Alert(browser).text

    time.sleep(enum+5)
    if "Earth" not in world: selenium.webdriver.common.alert.Alert(browser).dismiss()

    print "BODY:",body.text

finally:
  browser.quit()

输出:(地球坠毁)

{'python': '2.6.6 (r266:84292, Aug 18 2016, 15:13:37) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]', 'selenium': '2.53.2'}
BODY: Hello, worlds!
Hello, Mercury: AUTO PILOT... please DONT dismiss! {done via selenium.dismiss()!}!
BODY: Hello, worlds!
Hello, Venus: AUTO PILOT... please DONT dismiss! {done via selenium.dismiss()!}!
BODY: Hello, worlds!
Hello, Earth: So do MANUALLY dismiss! {Click [OK] now!!!}!
BODY:
Traceback (most recent call last):
  File "./js_alert.py", line 37, in <module>
    print "BODY:",body.text
...
selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: Hello, Earth: So do MANUALLY dismiss! {Click [OK] now!!!}!
Message: Unexpected modal dialog (text: Hello, Earth: So do MANUALLY dismiss! {Click [OK] now!!!}!) The alert disappeared before it could be closed.

奇怪的是,如果 浏览器用户 触发了另一个警报(甚至在 另一个 页面上!),那么 selenium.dismiss()body.text 从 limbo 和 selenium 中拉回来 从那时起 将按照(我的)期望运行。

关于如何让浏览器返回 page.body 有什么建议吗? (并逃避警报)

附录:这里有类似的问题(通过大量搜索找到):

还没有解决方案...我怀疑这是文件 modals.js

中 Firefox 的 webdriver 中的错误

Firefox 的网络驱动程序捕获警报弹出窗口并将其替换为名为 'dialog' 的元素 { 例如getElementsByTagName('dialog')[0]}

问题是,如果测试者是人类并点击 "dismiss" 或 "accept",那么 'dialog' 的 "onclick" 不会调用 fxdriver.modals.clearFlag_ ...因此问题。

https://github.com/SeleniumHQ/selenium/blob/master/javascript/firefox-driver/js/modals.js#LC39

fxdriver.modals.isModalPresent = function(callback, timeout) {
    fxdriver.modaltimer = new fxdriver.Timer();
    fxdriver.modaltimer.runWhenTrue(
    function() {
      var modal = fxdriver.modals.find_();
      return modal && modal.document && modal.document.getElementsByTagName('dialog')[0];
    },
    function() { callback(true) },
    timeout,
    function() { callback(false) });
};


fxdriver.modals.acceptAlert = function(driver) {
  var modal = fxdriver.modals.find_();
  var button = fxdriver.modals.findButton_(modal, 'accept');
  button.click();
  fxdriver.modals.clearFlag_(driver);
};

https://github.com/SeleniumHQ/selenium/blob/master/javascript/firefox-driver/js/modals.js#LC127

fxdriver.modals.setFlag = function(driver, flagValue) {
  driver.modalOpen = flagValue;
};

fxdriver.modals.clearFlag_ = function(driver) {
  fxdriver.modals.setFlag(driver, false);
};

也许 file_detector 选择本地文件可以解决...

类似问题:

  • How to debug Firefox alert box closing automatically and being unable to detect the alert in Serenity BDD?

错误报告:

我断断续续为这个问题苦恼了很长时间;你对你问题的评论为我解决了问题:

UnexpectedAlertPresentExceptionNoAlertPresentException 都抛出后...

browser.execute_script('alert("Clearing out past dialogs.")')
browser.switch_to.alert.accept()

正如您在回答中所说,网络驱动程序会在出现警报时创建 'dialog'。手动关闭警报会导致其引用陷入困境,但它仍会阻止对 body.text 的访问。创建新警报似乎允许 webdriver 清除旧的 'dialog' 并(在接受后)再次授予对该页面的访问权限。