问题
Basically, when an alert is popped up in javascript, I can dismiss()
it from python perfectly OK, by calling selenium.webdriver.common.alert.Alert(browser).dismiss()
.
However, if the "browser user" dismisses the alert by clicking [OK]
(on screen) with their mouse, then the browser alert gets "Lost in Space" the body.text
can no longer be accessed from python.
So... 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?
Here are the hints and a script to demonstrate the problem...
FYI: The objective of the originating code is it allow the browser user intervene on screen in testing and manually response to specific alerts.
#!/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()
Output: (Crash at Earth)
{'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.
The strange thing is that if the browser user triggers another alert (on another page even!), then a selenium.dismiss()
will pull body.text
back from limbo and selenium with from then will operate as per (my) expectations.
Any suggestions on how to get the browser back to the page.body
? (And escape the alert)
Addendum: Here are similar questions (found with intense searching):
- downloading - Issues downloading file using Selenium + Firefox
- java alert - Selenium WebDriver - Unexpected modal dialog Alert
- UnexpectedAlertPresentException - Webdriver error: "No alert is present" after UnexpectedAlertPresentException is thrown
- DesiredCapabilities - How to handle an Alert with "UnexpectedAlertBehaviour" capability in Selenium?
- java&javascript - org.openqa.selenium.UnhandledAlertException: unexpected alert open
- disables exception or DesiredCapabilities - org.openqa.selenium.UnhandledAlertException: unexpected alert open
- non-click suggestion - When I show a dialog, an exception "UnhandledAlertException: Modal dialog present" is thrown
- IE and in the wild - https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/4839
- java bug report? https://groups.google.com/forum/#!topic/webdriver/aNyOfEjMENg
- "still doesn't work." catching exception does not reset the problem - (However almost exactly the same problem) - how to handle javascript alerts in selenium using python
- suggested doing a
driver.findElement(By.id("myAlert"));
but that throws same exception - https://sqa.stackexchange.com/questions/22482/why-my-alert-is-not-popping-up browser.refresh();
givesUnexpectedAlertPresentException
so doesn't work. https://github.com/angular/protractor/issues/1486browser.switch_to.window(browser.window_handles[0])
thenbody.text
gives:UnexpectedAlertPresentException
- Similar - Python webdriver to handle pop up browser windows which is not an alert
回答1:
I have been struggling with this issue off and on for a long time; your comment on your question solved the problem for me:
After both UnexpectedAlertPresentException
and NoAlertPresentException
are thrown...
browser.execute_script('alert("Clearing out past dialogs.")')
browser.switch_to.alert.accept()
As you said in your answer, webdriver is creating a 'dialog' when the alert is present. Closing the alert by hand causes its reference to get lost in limbo, but it's still blocking access to body.text
. Creating a new alert seems to allow webdriver to clear out that old 'dialog' and (after accepting) grants access to the page again.
回答2:
No solution yet... I suspect it is a bug in Firefox's webdriver in file modals.js
Firefox's web driver captures the alert popup and replaces it with an element named 'dialog' { e.g. getElementsByTagName('dialog')[0]
}
The problem is that if the tester is human and clicks on either "dismiss" or "accept", then the "onclick" for 'dialog' does not call fxdriver.modals.clearFlag_
... hence the problem.
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);
};
Maybe the file_detector selecting local files has a work around...
- http://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.file_detector_context
Similar problem:
- How to debug Firefox alert box closing automatically and being unable to detect the alert in Serenity BDD?
Bug report:
- https://github.com/SeleniumHQ/selenium/issues/4190
来源:https://stackoverflow.com/questions/44568402/how-do-i-recover-the-text-from-the-page-originating-the-alert-esp-after-t