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**?
Asked Answered
M

2

1

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):

Millett answered 15/6, 2017 at 13:8 Comment(3)
whats wrong with calling dismiss() rather than clicking?Chita
Basically I have a prompt... "Do you want to continue testing?" No point getting the script to call accept()/dismiss() when a human is required.Millett
Ironically, even if I catch the exception in python, AFTER the alert has been manually dismissed or accepted I find the browser is still pointing to the "alert" and another exception is triggered is I try to run browser.execute_script('alert("Hello, %s!")'%world) or selenium.webdriver.common.alert.Alert(browser).dismiss(). My conclusion... the alert never disappears and remains in limbo after calls to either accept() or dismiss()Millett
B
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.

Bes answered 13/12, 2017 at 16:7 Comment(0)
M
0

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...

Similar problem:

Bug report:

Millett answered 16/6, 2017 at 15:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.