Litvin Litvin - 1 month ago 18
Python Question

Selenium Webdriver: window determined as alert (HTTP Basic Access Authentication), how to login (Python)

Sript click a link like

<a href="/loginform.do">

and it's open a new pop up window with login/password fields (OK/Cancel buttons).
And webdriver for some reason determine this pop up as alert not window...

if try

for handle in browser.window_handles:
print(handle)


it's return exception: UnexpectedAlertPresentException: Alert Text: Message: Modal dialog present

if try

alert=browser.switch_to_alert()
alert.send_keys('userlogin')


it's working (userlogin inserted into first field).
And then if trying to move cursor to next field (password) by TAB key

alert.send_keys(Keys.TAB)


it's replace text at the first field to bullet symbol instead of tabbing to next field...

Not only TAB, even ENTER working in the same way

alert.send_keys(Keys.ENTER)


it's paste the same bullet symbol instead of sending request to a server

And

alert.accept()


doing nothing (no sending request to a server)

What can be done here?


  • It's an alert, so find_element_by_... methods are not applicable.

  • TAB by send_keys is not working (no tabbing).

  • Is the only solution to click by coordinates (using pyautogui module as an option)?

  • Or is it possible to do more with webdriver?



BTW using IE (IEDriverServer)

And some searching for close questions



So an example with login form of .htaccess password protection (advancedhtml.co.uk/password.html)

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

browser=webdriver.Ie('c:\\...\\IEDriverServer.exe')

page='http://www.advancedhtml.co.uk/password/'
browser.get(page)
alert=browser.switch_to_alert()
#alert=browser.switch_to.alert() # this should work, but it doesn't: TypeError: 'Alert' object is not callable
alert.send_keys('user')
alert.send_keys(Keys.TAB) # no tabbing, bullet symbol instead...
#alert.send_keys('password')

Answer

So this kind of login page is HTTP Basic Access Authentication. And looks the best way to handle such authentication is to sent post request (Requests package)

Need to pass browser session from Selenium to Requests (29563335)

The code may look like this:

from selenium import webdriver
import requests

startURL='http://some_url'
browser=webdriver.Ie('c:\\path\\IEDriverServer.exe')
browser.get(startURL)

# an example of finding login link and get the url
loginLink=browser.find_element_by_xpath("//*[contains(text(), 'Log In')]")
loginURL=loginLink.get_attribute('href')

# load cookies from Selenium to Requests (so we could authenticate in current session)
cookies=browser.get_cookies()
s=requests.Session()
for cookie in cookies:
 s.cookies.set(cookie['name'], cookie['value'])

# and send the post request
auth=('login', 'password')
r=s.post(url=loginURL, auth=auth)
browser.refresh() # refresh page to see the result