Field should be filled.
Raises Capybara::ElementNotFound Exception: Unable to find visible field nil that is not disabled
When(/\AI populate "([^"]*)" with "([^"]*)"\z/) do |field_locator, value|
field = find_field(field_locator)
if field.matches_selector?(:fillable_field)
field.fill_in(:with => value)
elsif field.matches_selector?(:checkbox)
if [ '0', '', 'nil', 'false', 'unchecked', 'no' ].include?(value.to_s.downcase)
field.uncheck
else
field.check
end
elsif field.matches_selector?(:radio_button)
field.choose(value)
elsif field.matches_selector?(:select)
field.select(value)
elsif field.matches_selector?(:file_field)
field.attach_file(File.expand_path(value))
else
warn "Unknown field type for #{field.inspect}."
field.set(value)
end
end
When(/\AI populate "([^"]*)" with the following:\z/) do |form, fields|
within(form) do
fields.rows_hash.each do |name, value|
step %{I populate "#{name}" with "#{value}"}
end
end
end
Given I populate "#new_user_session" with the following:
| user_session_email | [email protected] |
| user_session_password | password |
This error occurs to be occurring because the #fill_in method runs find(:fillable_field, locator, options) in the context of the element and find appears to only look at descendants of the current element (of which there are obviously none). Intuitively, however, #fill_in should performed on the current object given the way I invoke it.
NB: I imagine similar issues also exist in the other form fill methods invoked in my (not yet fully tested) step definition.
Looking into this more, one could argue I should be using the #set method for everything, but this is rather unintuitive considering I can't use it for <select>s, and #check, #uncheck and #choose have added functionality with regard to the :allow_label_click option that I would have to duplicate, should I need it.
@mvastola This isn't an issue in Capybara, you're just using it wrong. As you stated, if you have already located the element you want to interact with , you call set on it (which you can call on checkboxes, etc with true or false). fill_in as documented - http://www.rubydoc.info/gems/capybara/Capybara/Node/Actions#fill_in-instance_method - finds a field a fills it in, it doesn't act on the current scope element
Why you would ever write a cucumber step as
Given I populate "some_check_box_id" with "unchecked"
is beyond me though.
If you really want the step you've defined you could just change it to call the methods with the field_locator - e.g. instead of field.fill_in(with: value) do fill_in(field_locator, with: value) although you're going a long way to generalize cucumber steps that really shouldn't be.
Haha. I wouldn't write
Given I populate "some_check_box_id" with "unchecked"
in long form, but I wrote the step to work with checkboxes too so I could fill in a whole web form (checkboxes included) if I supply the inputs in the tabular format.
Anywho, I can accept I'm not using it as it was intended. It just seemed a bit unintuitive because you'd think calling #fill_in on an object of a class literally named Element would let you fill in said element. Not a huge deal though.
@mvastola This isn't an issue in Capybara, you're just using it wrong. As you stated, if you have already located the element you want to interact with , you call
seton it (which you can call on checkboxes, etc with true or false).fill_inas documented - http://www.rubydoc.info/gems/capybara/Capybara/Node/Actions#fill_in-instance_method - finds a field a fills it in, it doesn't act on the current scope element
The documentation must've been updated since this was written, because now it shows two examples:
# will fill in a descendant fillable field with name, id, or label text matching 'Name'
page.fill_in 'Name', with: 'Bob'
# will fill in `el` if it's a fillable field
el.fill_in with: 'Tom'
So el.fill_in with: 'Tom' should work but it doesn't, at least for me (using Capybara 2.18.0)
Looks like 3.7.0 introduced support for calling fill_in on the current element.
@dpashkevich You're using 2.18 and looking at the docs for 3.13.x, there are big differences between those two versions. The ability to call fill_in on the element you want filled in was added in 3.7
Nevermind - you apparently figured that out --- 2.18 was released a year ago -- it's pretty obsolete at this point