131
votes

I'm using Rspec and Capybara.

How can I write a step to check a checkbox? I've tried check by value but it can't find my checkbox. I'm not sure what to do, as I have in fact same ID with different values

Here is the code:

 <input id="cityID" type="checkbox" style="text-align: center; opacity: 0;" value="61" name="cityID">
 <input id="cityID" type="checkbox" style="text-align: center; opacity: 0;" value="62" name="cityID">
 <input id="cityID" type="checkbox" style="text-align: center; opacity: 0;" value="63" name="cityID">
13
Your inputs shouldn't have the same IDs - they should have the same names, but different IDs.SamStephens

13 Answers

160
votes

I found the following worked for me:

# Check
find(:css, "#cityID[value='62']").set(true)

# Uncheck
find(:css, "#cityID[value='62']").set(false)
143
votes

It's better not to create multiple elements with the same id, so that (and not only for that) you can easily check/uncheck a checkbox with elegant

check 'cityID'
uncheck 'cityID'

If one can not avoid multiple elements with the same id and still needs to check a checkbox with certain value, he can do so with

find(:css, "#cityID[value='62']").set(true)
find(:css, "#cityID[value='62']").set(false)

More information on capybara input manipulations can be found here

59
votes

When running capybara test, you got the page object. This you can use to check/uncheck any checkboxes. As @buruzaemon already mentioned:

to find and check a checkbox by name, id, or label text.

So lets assume you got a checkbox in your html like:

<label>  
  <input type="checkbox" value="myvalue" name="myname" id="myid">
  MyLabel
</label>

You could check this with:

page.check('myid')
page.check('MyLabel')
page.check('myname')

Uncheck is the same just use page.uncheck method.

26
votes

I think you may have to give unique ids to your form elements, first of all.

But with regards to Capybara and checkboxes, the Capybara::Node::Actions#check instance method will allow you to find and check a checkbox by name, id, or label text.

11
votes

If the box is associated with text, e.g. 'Option 3', then as of capybara 3.0.3 you can just do

check 'Option 3'
7
votes

I know this is an older question, but I have been working through this myself, and having tried all of the above, this is what finally worked for me:

find("input[type='checkbox'][value='#{cityID.id}']").set(true)

Hope this is helpful to someone. I am using Capybara 2.4.4.

6
votes

An old topic but another solution is:

check('Option 3', allow_label_click: true)

5
votes

Had some issues with custom checkbox which is hidden behind label element. Needed a allow_label_click: true.

With reference to this blog post,

check 'checkbox[name]', allow_label_click: true

For cases where there is a link in your label like "I agree to terms and conditions", the above code will open the page, which is not what you want.

Do this instead.

find(:css, "#checkbox_id", visible: false).execute_script('this.checked = true')
1
votes

you can also use :xpath instead of :css if you have some problems finding it.

find(:xpath , '//*[@id="example"]').set(true)

on Chrome (and surely other browsers), you can "inspect element" and then by right clicking on the element you are interested in, there is 'copy xpath' if you don't know what xpath was, now you do.

1
votes

You can also check that all the checkboxes are not checked with this example.

all('input[type=checkbox]').each do |checkbox| checkbox.should_not be_checked end

1
votes

.set(true) didn't work for me so I had to call .click:

find(...).click

0
votes
check find(".whenever input")[:id]

I think this will make capybara wait for any event listener attached to that input, which sometimes is a pain-in-the-ass if it doesn't waits .... If that input doesn't have an ID, choose another property (there must be one)...

0
votes

to select the checkbox

  check 'name_of_checkbox'