Take the 2-minute tour ×
Software Quality Assurance & Testing Stack Exchange is a question and answer site for software quality control experts, automation engineers, and software testers. It's 100% free, no registration required.

See attached image. The element is visible to me as a user, but I keep getting the ElementNotVisibleException error. It seems to locate the element via multiple methods, but the .click() fails. Is it just something dumb like checkboxes use a different method?

elem = self.web.find_element_by_css_selector("input[name='tos_agree']")
elem.click()

can't click the checkbox

share|improve this question
    
Which version of Selenium are you using? –  user246 Nov 1 '11 at 1:46
    
I'm using 2.8.1 I believe. I easy-installed it for Python a couple weeks ago or so. –  Aaron Nov 1 '11 at 1:51
    
Does the page use any Javascript that controls whether the tos_agree element is visible? –  user246 Nov 1 '11 at 1:56
    
It does. Right now I'm trying to figure out how to use a CSS selector plus the WebDriver wait function to check if it's visible. –  Aaron Nov 1 '11 at 22:19
add comment

3 Answers

up vote 4 down vote accepted

We sometimes have problems like this. I have found the easiest way to solve this is to use a wait function. I imagine that when the page is loaded the button is hidden and there is javascript to make it visible. Often times the driver will run faster than the javascript.

EDIT:

elem = self.web.find_element_by_id('tos_agree')
driver = self.web 
elem_visible = WebDriverWait(self.web, 2).until(lambda driver : \ elem.is_displayed()) 
elem.click()

This seems to be the most clean solution using WebDrivers tools

share|improve this answer
    
I think you guys are spot on with the JavaScript wait idea. Indeed this page is hiding elements via a JavaScript trigger. Unfortunately, I tried the wait function this morning and it still gives the not visible error: driver = self.web elem = WebDriverWait(self.web, 2).until(lambda driver : \ driver.find_element_by_id('tos_agree')) elem.click() –  Aaron Nov 1 '11 at 18:29
    
I have never had much luck with the WebDriverWait. I suggest just making a simple timeout function that will loop a couple of times and sleep between each iteration, checking to see if the element is visible yet. –  Jason Ward Nov 1 '11 at 19:07
    
After more thought, I think it's not a timeout issue at all but a visibility issue. This might be the solution: stackoverflow.com/questions/6101461/… –  Aaron Nov 1 '11 at 20:09
    
I take it back. It is some kind of timeout issue. I did a quick and dirty sleep function in the Python, and now it's clickable. time.sleep(5) elem = self.web.find_element_by_id('tos_agree') elem.click() –  Aaron Nov 1 '11 at 20:15
1  
Finally got it using Jason's suggested method. Jason, can you please edit your answer to include this example code so it's not buried in comments? You'll need to format it too. elem = self.web.find_element_by_id('tos_agree') driver = self.web elem_visible = WebDriverWait(self.web, 2).until(lambda driver : \ elem.is_displayed()) elem.click() –  Aaron Nov 1 '11 at 23:01
show 3 more comments

It's a bit unorthodox, but you could inject javascript into the webdriver to make the element visible. Assuming there's some js function in the page called "makeItVisible", you could do this:

mydriver.ExecuteScript("makeItVisible();");

It's a bit hacky, and remarkably white-box-y, but it may solve your problem.

share|improve this answer
    
Cool idea, but I'm reluctant to do that, because I think one of the big benefits of WebDriver is that it drops the JS-injection that RC Server was doing. Seems like we get better cross-browser support that way. –  Aaron Nov 9 '11 at 20:00
    
Yeah, but the cool factor is high. Isn't that reason enough to do it? :) –  Stephen Gross Nov 9 '11 at 21:14
    
It definitely would be faster than doing a webdriver wait, and I think you could import less too. But adds potential breakage if the developer ever decides to rename the function/etc. –  Aaron Nov 10 '11 at 21:50
add comment

I'm having a similar problem, however with a button that starts off being hidden, then I use a piece of javascript to unhide it when one of the other buttons is clicked - it definitely has something to do with the javascript, is it possible that selenium builds a list of visible elements when the page loads and then doesn't refresh that list when changes are made on the page, only when it navigates to a new page?

share|improve this answer
    
Selenium calculates which elements are visible based on when they are used. If Selenium is telling you the element is not visible, but it looks like it is actually visible, it is almost certainly a timing issue and can be fixed by doing what is shown in my initial answer. –  Jason Ward Nov 9 '11 at 17:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.