Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error trying to login to webpage using selenium with python

I get an element isn't visible error:

ElementNotVisibleException: Message: u'Element is not currently visible and so may 
not be interacted with' 

For every find element line when I run this code:

from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://www.example.com')
browser.find_element_by_name('username').send_keys('myusername')
browser.find_element_by_name('password').send_keys('mypassword')
browser.find_element_by_class_name('welcomeLoginButton').click()

The HTML for the login section of the page looks like this:

<div class='welcomeLoginUsername'>
<div class='welcomeLoginUsernameLabel'><b>Username:</b></div>
<div class='welcomeLoginUsernameInput'><input type='text' name='username' tabindex='1'>
<br><a class='sf' href='javascript: void(0);' onclick='showUsernamePopup();'>
<b>Forgot Username?</b></a>
</div>
</div>
<div class='welcomeLoginPassword'>
<div class='welcomeLoginPasswordLabel'>
<b>Password:</b>
<br><span class='sf'>(It's cAsE sEnSitIvE!)</span>
</div>
<div class='welcomeLoginPasswordInput'>
<input type='password' name='password' tabindex='2'>
<br><a class='sf' href="javascript: void(0);" onclick="showPasswordPopup();">
<b>Forgot Password?</b></a>
</div>
</div>
</div>
<input type="submit" value="" class='welcomeLoginButton' style='border: 0px; 
padding: 0px; margin: 0px;) no-repeat;' onclick='document.forms["login"].submit()'>
like image 864
Frozsht Avatar asked Aug 12 '12 00:08

Frozsht


1 Answers

Selenium interacts with the web browser in a similar way that the user would. So if there is an html element you're trying to interact with that is not visible then the simplest explanation is that when youre writing your selenium code you're not interacting with the web page like a normal user would.

In the end this isn't about the html of your web page its about the DOM and an element's hidden attribute. I suggest you download firebug or some other html viewer program, and then highlight the button you want to press. Use the DOM lookup for the html viewer and go through the sign in process manually. Notice what you have to do to make the element visible in order to interact with it then mimic the same steps in your selenium code.

If it is a matter of the fact that you did everything you needed to do, but selenium is interacting with the web page faster than the javascript will make the element visible then there is a wait that you have to programmed in.

Naive way:

import time
time.sleep(1) # this is done in seconds

More scalable manner:

import time

welcome_button = browser.find_element_by_class_name('welcomeLoginButton')

wait_for_element_visibility(welcome_button).click()

def wait_for_element_visibility(element):
   if element.is_visible():
      return element
   else:
      for i in range(10):
         if not element.is_visible():
            time.sleep(.5)
         else:
            return element
like image 51
Greg Avatar answered Oct 27 '22 07:10

Greg