3

I wuold like to handle alerts with Python. What I wuold like to do is:

  • Open a url
  • Submit a form or click some links
  • Check if an alert occurs in the new page

I made this with Javascript using PhantomJS, but I would made even with Python.

Here is the javascript code:

file test.js:

var webPage = require('webpage');
var page = webPage.create();

var url = 'http://localhost:8001/index.html'

page.onConsoleMessage = function (msg) {
    console.log(msg);
}    
page.open(url, function (status) {                
    page.evaluate(function () {
        document.getElementById('myButton').click()       
    });        
    page.onConsoleMessage = function (msg) {
        console.log(msg);
    }    
    page.onAlert = function (msg) {
        console.log('ALERT: ' + msg);
    };    
    setTimeout(function () {
        page.evaluate(function () {
            console.log(document.documentElement.innerHTML)
        });
        phantom.exit();
    }, 1000);
});

file index.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <meta charset="utf-8" />
</head>
<body>
    <form>
        <input id="username" name="username" />
        <button id="myButton" type="button" value="Page2">Go to Page2</button>
    </form>
</body>
</html>

<script>
    document.getElementById("myButton").onclick = function () {
        location.href = "page2.html";
    };
</script>

file page2.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <meta charset="utf-8" />
</head>
<body onload="alert('hello')">
</body>
</html>

This works; it detects the alert on page2.html. Now I made this python script:

test.py

import requests
from test import BasicTest
from selenium import webdriver
from bs4 import BeautifulSoup   

url = 'http://localhost:8001/index.html'    

def main():
    #browser = webdriver.Firefox()
    browser = webdriver.PhantomJS()
    browser.get(url)
    html_source = browser.page_source
    #browser.quit()    
    soup = BeautifulSoup(html_source, "html.parser")
    soup.prettify()    
    request = requests.get('http://localhost:8001/page2.html')
    print request.text    
    #Handle Alert    
if __name__ == "__main__":
    main();

Now, how can I check if an alert occur on page2.html with Python? First I open the page index.html, then page2.html. I'm at the beginning, so any suggestions will be appreciate.

p.s. I also tested webdriver.Firefox() but it is extremely slow. Also i read this question : Check if any alert exists using selenium with python

but it doesn't work (below is the same previous script plus the solution suggested in the answer).

.....    
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

....

def main():
    .....
    #Handle Alert
    try:
        WebDriverWait(browser, 3).until(EC.alert_is_present(),
                                        'Timed out waiting for PA creation ' +
                                        'confirmation popup to appear.')

        alert = browser.switch_to.alert()
        alert.accept()
        print "alert accepted"
    except TimeoutException:
        print "no alert"

if __name__ == "__main__":
    main();

I get the error :

"selenium.common.exceptions.WebDriverException: Message: Invalid Command Method.."

iamsankalp89
  • 4,607
  • 2
  • 15
  • 36
d3llafr33
  • 347
  • 4
  • 15

1 Answers1

1

PhantomJS uses GhostDriver to implement the WebDriver Wire Protocol, which is how it works as a headless browser within Selenium.

Unfortunately, GhostDriver does not currently support Alerts. Although it looks like they would like help to implement the features:

https://github.com/detro/ghostdriver/issues/20

You could possibly switch to the javascript version of PhantomJS or use the Firefox driver within Selenium.

from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException

if __name__ == '__main__':
    # Switch to this driver and switch_to_alert will fail.
    # driver = webdriver.PhantomJS('<Path to Phantom>')
    driver = webdriver.Firefox()
    driver.set_window_size(1400, 1000)
    driver.get('http://localhost:8001/page2.html')

    try:
        driver.switch_to.alert.accept()
        print('Alarm! ALARM!')
    except NoAlertPresentException:
        print('*crickets*')
  • Hi! thanks for the answer. I tried to run your solution, but it doesn't work. It opens a blank page and nothing happens. Am I missing something? – d3llafr33 Sep 30 '16 at 12:38
  • The script runs using the Python 3.5 interpreter, is that what you're using? I would suggest copying and pasting the code under '__main__': and the import statements into your own script. If running correctly it should open a firefox window to your URL and print one of the two messages to the console. –  Sep 30 '16 at 12:47
  • I was using python 2.7. I switched to python 3.5 but the result is the same. I also followed your suggestions. I'm using selenium v.2.53.6 – d3llafr33 Sep 30 '16 at 13:02
  • When all else fails, debug :) Open your python console and go line by line. (Skip the if __name__ == '__main__': line). I expect its an issue with Python not seeing the webdriver or the webdriver failing to connect to the URL. All the script is really doing is opening the URL, trying to switch to the alert, and printing to the console . –  Sep 30 '16 at 13:14
  • I think that is is related to this issue : http://stackoverflow.com/questions/37693106/selenium-2-53-not-working-on-firefox-47 or this https://github.com/seleniumhq/selenium/issues/1431 – d3llafr33 Sep 30 '16 at 22:38