Capybara: Unable to find css
Asked Answered
S

6

38

I am using capybara to click a checkbox, however it can't seem to find it no matter what I do. I am able to correctly find both the span and the label inside the span, but not the input I actually need.

Here is the checkbox

<span class="checkbox tos">
  <input id="agreement" name="agreement" onclick="agreeValidate();" type="checkbox" value="false">
  <label for="agreement">I accept the <a href="http://www.dev.com:3000/terms" target="_blank">Terms of Use</a>, <a href="http://www.dev.com:3000/privacy" target="_blank">Privacy Policy</a>, and am at least 13 years old</label>
</span>

And here are some of the things I have tried

page.check('agreement')
find(:css, '#agreement').set(true)
find('#agreement').set(true)
find('#agreement').click

However, they all give me the same error

Unable to find css "#agreement" (Capybara::ElementNotFound)

I am also wondering will any of these methods fire off the onclick method, when the checkbox is clicked? I feel like find(:css, '#agreement').set(true) will not trigger the onclick event. However, I am not sure about the rest.

Update

I have also tried selecting the element through xpath. Here are the various things I have found out

find(:xpath, '//*[@id="registration"]/span[2]')

This is able to find the span element no problem

find(:xpath, '//*[@id="registration"]/span[2]/input')

This can't find the element I need, but this xpath correctly selects the element in chrome's console

find(:xpath, '//*[@id="agreement"]')

This can't find the element I need, but the xpath selects the element in chrome's console

find(:xpath, '//*[@id="registration"]/span[2]/label')

This is able to find the label element in the span with no problem.

Saddlebacked answered 9/1, 2014 at 23:43 Comment(2)
Please post more of your code. In isolation, it looks like find('#agreement') should work to find that checkbox, so if that's not working, there might be something wrong with the surrounding code (maybe it isn't loading the page correctly at all, or maybe there is invalid markup in the page).Dehypnotize
What is the value of Capybara.default_wait_time?Brackish
L
41

I had the exact issue yesterday. Capybara was automatically ignoring the input due to it being invisible. I solved it with the following:

find('#agreement', :visible => false).click

You can also add the following to env.rb to enable Capybara to interact with all hidden elements:

Capybara.ignore_hidden_elements = false
Lozada answered 5/2, 2014 at 11:53 Comment(1)
I tried check('#id', :visible => false) and Capybara raised 'Selenium::WebDriver::Error::ElementNotVisibleError: Element is not currently visible and so may not be interacted with' So the solution I came up with involved clicking the actual parent element that the user does see. Ideally Capybara does what your user does, so clicking on a non-visible element should be avoided.Seyler
B
10

Try to add :visible option set to false.

find('#agreement', visible: false).click

By default Capybara finds only visible elements. It seems that underlying driver identified this input as invisible so it hasn't been found by Capybara.

:visible option is also supported by most of other Capybara methods (like check, has_css?, have_selector, etc.)

Brackish answered 19/1, 2014 at 8:33 Comment(0)
C
3

Try this page.execute_script("$('#agreement').attr('checked', true)"). To make this work you should tag your examples with js: true

Cormack answered 19/1, 2014 at 13:11 Comment(0)
B
1

I have the same problem ... I tried the following it works fine ...

find('#tos', visible: false).set(true)
Benita answered 23/1, 2014 at 17:22 Comment(0)
R
0

The problem is that the page is not being rendered because you're taken to some other page. To solve this, you don't need to change you're Capybara code. You will likely have to make some changes in your controller code.

I got this idea since you brought up in one of the comments that you are taken to your domain's internal server when doing save_and_open_page instead. Please provide me with the details of what you see in the internal server. Are there any error messages you see there? Also, please provide me with your code for the controller action of that view you want to check a checkbox on and any other code you defined that's called in that controller action.

Repair answered 19/1, 2014 at 13:24 Comment(0)
U
-1

Hard to tell without seeing the whole HTML page. Here are some possible problems:

  1. You may be looking for the checkbox before the page is fully loaded? Make sure you have enough wait time before calling find(#agreement)
  2. You may have multiple tags with the same id="agreement". Make sure you only have one.
  3. Make sure the page is valid HTML.
  4. Make sure the checkbox is visible, and enabled, and agreeValidate() is working properly.
Ungotten answered 22/1, 2014 at 18:21 Comment(2)
2 point is invalid. Capybara won't raise such error if there were multiple elements with such locator.Brackish
AFAIK it also shouldn't matter if input is enabled when find is invoked. It would matter if click is invoked but OP's code stops execution on find.Brackish

© 2022 - 2024 — McMap. All rights reserved.