How to check a checkbox in capybara? - ruby-on-rails

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">

I found the following worked for me:
# Check
find(:css, "#cityID[value='62']").set(true)
# Uncheck
find(:css, "#cityID[value='62']").set(false)

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

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.

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.

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'

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.

An old topic but another solution is:
check('Option 3', allow_label_click: true)

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')

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.

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

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

I believe this looks more elegant:
find_by_id("cityID").set(true)
Tested on Rails 7. Works fine.

To select the checkbox
check 'name_of_checkbox'

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)...

Related

Rspec Selecting option from react drop down

I am new for rspec and ruby on rails. I would like to select one of the options shown in the attached image.
Can anyone suggest a simple way to click on the option?
This is what I have tried
el = find("#menu-campaign_type_id")
el2 =find("ul")
and I tried to find option inside el2 but I am not able to find it.
Thanking you in advance
Not sure it will work on an ul tag but you should try using capybara with rspec, then you could do things like this:
within :css, '#menu-campaign_type_id' do
select 'Awareness'
end
a simpler option would be
page.find('#menu-campaign_type_id > ul > option:first').select_option
I think you can do this with capybara test cases. In capybara with selenium web driver.
But before that, you need to correct your drop-down code, there is an option inside ul tag, but it should be a select tag.
drop-down example
<div class="test">
<select>
<option value="op1">option1</option>
<option value="op2">option2</option>
</select>
</div>
You can achieve this by executing the javascript
page.execute_script <<-JAVASCRIPT
$("div.test select").val("op2");
JAVASCRIPT
you can also try this
select 'option2', from: 'test', visible: false
hope it will help you to resolve.
Can you try this
find("ul.MuiList-root").find(:option, Awareness).select_option

Filling in a search box and then clicking on the autocomplete

I am having trouble filling in and clicking this search box
<input type="text" name="js-emu-operation-search" id="js-emu-operation-search" placeholder="Enter service name" autocomplete="off">
I have tried using
internet.fill_in('js-emu-operation-search', :with => "Alternator Replacement")
but it does not work. After that is filled in though I am also wondering how to click on the first autocomplete option.
Working with autocompletes can be pretty difficult, depending on how it's implemented. Some tricks I've used in the past:
Click the input before sending text to it
find('#js-emu-operation-search').click()
Try using the underlying element methods instead of the fill_in wrapper, e.g.
find('#js-emu-operation-search').set("Alternator Replacement")
Select from the dropdown options with find("#results-pane", text: "My Result").click, or if you get really desperate, make sure there's only a single result and select it with the down arrow, find('#js-emu-operation-search').native.send_keys(:arrow_down)
Disclaimer: My capybara is getting rusty, may have to tinker. If you're working on a team, I've also had good luck dragging another developer into it, preferably the guy who implemented the autocomplete.

Capybara (poltergeist) cannot find checkbox in form

I cannot get Capybara for find a checkbox element.
I've tried all the usual ways:
find_field
check
find
click_on
It's as if the element isn't there. If I select the parent element, and look at it's innerHTML the checkbox is included:
(byebug) all(:css, '.checkbox.form-group').last['innerHTML']
\n <input type=\"checkbox\" id=\"google_agreed_to_terms_at\" value=\"1\" required=\"true\" ng-model=\"agreed_to_terms\" required-notification=\"Please agree to the terms and conditions\" class=\"ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required\" bs-validation=\"\">\
but selecting the child elements it's not there:
(byebug) all(:css, '.checkbox.form-group').last.all :xpath, './*'
[#<Capybara::Node::Element tag="label"
path="//HTML[1]/BODY[1]/DIV[2]/DIV[1]/DIV[2]/FORM[1]/DIV[1]/LABEL[1]">]
I feel like I'm going mad.
Here's the relevant code (copied from save_and_open_page)
<div class="checkbox form-group">
<input type="checkbox" id="agreed_to_terms_at" value="1" required="true" ng-model="agreed_to_terms" required-notification="Please agree to the terms and conditions" class="ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required" bs-validation="">
<label class="label-light" for="agreed_to_terms_at">
I have read and agree to the terms</label>
</div>
I thought maybe rails was generating slightly non-compliant HTML, so I've gone to writing the checkbox by hand, but it didn't help.
What's going on here?
The checkbox is hidden to allow for uniform styling across all browsers. Since you have a label element correctly associated you can tell check to click the label instead of the actual checkbox
check('agreed_to_terms_at', allow_label_click: true)
which will click the checkbox if visible and if not it will click the label. If you want it to only click the label you can do
find(:label, 'I have read and agree').click
Or
find(:label, for:'agreed_to_terms_at').click
Due to CSS styling, the checkbox element was being hidden and the label used to present it. So the element was getting skipped over by capybara's default behaviour to ignore hidden elements.
I worked around it using
find('#agreed_to_terms_at', :visible => false).trigger('click')

Capybara/Poltergeist, clicking on Hidden Checkbox?

I have some HTML for a Checkbox im trying to click:
<td class="surface center">
<div class="checkbox-inline checkbox-inline--empty">
<input type="hidden" value="0" name="stuff_check">
<input id="stuff_1" class="boolean optional" type="checkbox" name="stuff_1_checked" value="1" data-item="5">
<label class="optional" for="stuff_1">Checked</label>
</div>
</td>
When running a page.find_by_id('id').trigger('click') it does indeed work, just using click however it complains about Poltergeist possibly clicking another elements:
Capybara::Poltergeist::MouseEventFailed:
Firing a click at co-ordinates [-9468.5, 6] failed. Poltergeist detected another element with CSS selector '' at this position. It may
be overlapping the element you are trying to interact with. If you
don't care about overlapping elements, try using
node.trigger('click').
However I felt maybe this is because of it being set as "hidden", so I tried doing page.find_by_id('ID', :visible => false).click however it gave the same issue.
Any suggestions? Since I know using trigger.('click') isn't advised.
There is no way to do a proper click on a hidden element because there would be no way for a user to click on an element that doesn't appear on the screen.
Your example is confusing because the hidden element doesn't have the same name attribute as the checkbox element which is what I would normally expect in this kind of setup. Assuming that what you're really trying to do is check the "stuff_1" checkbox (and that is hidden via CSS) then you should be doing what a user of your app would have to do - click on the label.
page.find('label[for="stuff1"]').click
Try
within('.checkbox-inline checkbox-inline--empty') do
check('#stuff_1')
end
I really recommend using Pry to do this though as you'll save yourself a ton of pain finding which elements are where.

How to test file attachment on hidden input using capybara?

I have hidden input inside of label:
<label for="upload">
<input class="hidden" type="file" name="file[picture]">
</label>
When I click on the label, I attach a file and then confirm.
After that modal window pops up and I need to find appropriate div class.
How can I test this with the help of capybara?
Update: Capybara 2.12 added a make_visible option to attach_file so if using 2.12+ you can first try
attach_file('file[picture]', 'path/to/file.png', make_visible: true)
before directly using execute_script yourself
File inputs are a special case since they are so often hidden for styling reasons and use a system modal for interaction. Capybara makes it hard to fill in hidden fields on a page because users generally can't interact with them, so for file inputs normal practice is to use execute_script to make them visible and then fill them in.
execute_script("$('input[name=\"file[picture]\"]').removeClass('hidden')") # assumes you have jQuery available - if not change to valid JS for your environment
attach_file('file[picture]', 'path/to/file.png') # takes id, name or label text of field not a random selector
Using Capybara '2.7.1':
attach_file('file[picture]', 'path/to/file.png', visible: false)
You can do something along the lines of:
find('label[for=upload]').click
attach_file('input[name="file[picture]"]'), 'path/to/file.png')
within '.modal-popup' do
expect(page).to have_content '.divclass'
end

Resources