3

Source snippet:

<div>
<div class="checkbox checkbox-primary margin-bottom-5 margin-top-5">
<input id="item" name="item" type="checkbox" value="true"/>
<label for="item">Item_Text</label>
<input name="item" type="hidden" value="false"/>
</div>

I'm trying to click on this checkbox using Splinter with the following code:

browser.find_by_id('item')click()

I've also tried find_by_name. Both produce the following exception:

(<class 'selenium.common.exceptions.ElementNotVisibleException'>, ElementNotVisibleException()

Attempting to debug:

print browser.is_element_present_by_id(item), browser.find_by_id(item).visible

returns True, False

It looks like Splinter's having trouble clicking the box because the second input block shows type='hidden'. However, adding .first.click() does not fix the problem and I'm out of ideas. I might be missing something really simple!

Mcdizzle
  • 81
  • 1
  • 9
  • probably the id is duplicate. Try using xpath or css which is unique. – Saifur May 21 '15 at 01:17
  • the id is used exactly four times on the page, all shown in that snippet. Twice in the first input tag (id/name), one in the label, and once in the second hidden input tag (name). I think this second input tag is causing it to be hidden, but I don't know how to only use the first tag, since .first isn't working. How would I use xpath or css in this case? – Mcdizzle May 21 '15 at 01:25
  • Is there any other div with `
    ` ?
    – Saifur May 21 '15 at 01:30
  • yes, that exists for every such checkbox I'd like to check on this page (there are 27 of them). The structure of each one is the same as the posted snippet. – Mcdizzle May 21 '15 at 01:34

3 Answers3

2

The following javascript execution fixed the problem: browser.execute_script('document.getElementsByName("%s")[0].checked=true' % item)

Mcdizzle
  • 81
  • 1
  • 9
0

I usually use xpath in such case since the label for the check boxes are unique and more secure to identify the element correctly. However, you need to make sure the ids are not duplicate. That's the main part of having ids for Selenium testing. try this:

//label[contains(text(),'Item_Text')]/../input[@type='checkbox']

Use

browser.find_by_xpath("//label[contains(text(),'Item_Text')]/../input[@type='checkbox']")

The above should find the element based on the label Item_Text

Edit

Try grabbing the list and then do a look up for the displayed one and click

elements = browser.find_by_xpath("//label[contains(text(),'Item_Text')]/../input[@type='checkbox']")
for element in elements:
    if element.is_displayed():
        element.click()
        break

Splinter syntax can be a little off. Please refer to the doc as needed.

Saifur
  • 16,081
  • 6
  • 49
  • 73
  • The xpath you are using is quite different than the one I gave. specially `\\\` (slashes). It is important to use the same slashes – Saifur May 21 '15 at 02:01
  • I am not familiar with splinter that much. But I am assuming you do not need `first` since the xpath should return only ONE element anyway – Saifur May 21 '15 at 02:25
  • Regarding your edit: I can create the list of elements using your code. The list looks something like this: [, , ...] However each item is still not visible, so I don't think this is solving the problem. Would executing some kind of javascript through splinter to check the boxes work instead? – Mcdizzle May 21 '15 at 08:10
0

This is a known issue when the web-code is "faked" by JavaScript. A variation of @Mcdizzle's solution in Selenium is to emit the click via JavaScript:

browser.execute_script('document.getElementById("%s").click()' % id_string)
James Hirschorn
  • 7,032
  • 5
  • 45
  • 53