Problem: The GhostDriver API does not yet support alert handling. There is an acceptable workaround for the time being, which is to inject your own javascript into the page that will handle the alert and store it's text for you.
I'm having trouble using this workaround via the python webdriver bindings. It might be related to my novice level understanding of javascript.
Here is an example of the workaround I am trying to utilize: https://github.com/detro/ghostdriver/issues/20#issuecomment-15641983
I'm using a public site that demonstrates an alert to make this more straightforward: http://www.tizag.com/javascriptT/javascriptalert.php
Here is my code:
from selenium import webdriver
button_xpath = "/html/body/table[3]/tbody/tr/td[2]/table/tbody/tr/td/div[4]/form/input"
js = """
(function () {
var lastAlert = undefined;
window.alert = function (message) {
lastAlert = message;
};
window.getLastAlert = function () {
var result = lastAlert;
lastAlert = undefined;
return result;
};
}());
"""
driver = webdriver.PhantomJS()
driver.get('http://www.tizag.com/javascriptT/javascriptalert.php')
driver.execute_script("window.alert = %s" % js)
driver.find_element_by_xpath(button_xpath).click()
#exception just occured
driver.execute_script("return window.getLastAlert && window.getLastAlert();")
The exception is:
WebDriverException: Message: u'Error Message => \'Click failed: TypeError: \'undefined\' is not a function (evaluating \'alert(\'Are you sure you want to give us the deed to your house?\')\')\'\n caused by Request => {"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"81","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:41752","User-Agent":"Python-urllib/2.7"},"httpVersion":"1.1","method":"POST","post":"{\\"sessionId\\": \\"0eaf7680-9897-11e2-b375-55b9cb6ceb0f\\", \\"id\\": \\":wdc:1364578560610\\"}","url":"/click","urlParsed":{"anchor":"","query":"","file":"click","directory":"/","path":"/click","relative":"/click","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/click","queryKey":{},"chunks":["click"]},"urlOriginal":"/session/0eaf7680-9897-11e2-b375-55b9cb6ceb0f/element/%3Awdc%3A1364578560610/click"}' ; Screenshot: available via screen
I'm a JS noob. I'm hoping somebody can point me in the right direction.
A simple solution is to rewrite the window.alert method to output the argument to a global variable.
Define the js injection variable with your override function:
js = """
window.alert = function(message) {
lastAlert = message;
}
"""
And then just pass the js variable through the execute_script call in python like this:
driver.execute_script("%s" % js)
Then when it's all been run you can execute a return on the global lastAlert:
driver.execute_script("return lastAlert")
This is some workaround.
Use this for every reloaded page that would have an alert later.
driver.execute_script("window.confirm = function(){return true;}");
This works for PhantomJS within Selenium/Splinter.
See more reference here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With