I am following Michael Hartl's Ruby on Rails Tutorial. When I use rspec/capybara, the fill_in method makes me confused. I have the following view code:
<%= f.label :name %>
<%= f.text_field :name %>
This is my testing code:
fill_in "Name", with: "Example User"
It seems that label and text_field are both required for fill_in to locate the input field. If I either take off f.label
or change <%= f.text_field :name %>
to be <%= f.text_field :another_name %>
, the test will give me ElementNotFound
error. Can anyone explain how the fill_in works here? Are input field and label both required for fill_in
method?
It is stated that fill_in
looks for field name
, id
or label text. According to ActionView::Helpers::FormHelper section of rails guides, the view code which you ask about should be translated to the following html code:
# I assume that you made a form for a @user object
<label for="user_name">
Name
</label>
<input id="user_name" name="user[name]" type="text" />
As you see, label
produced the "Name" text, which you ask for inside of your fill_in
expression. But id
and name
properties of input
field are slightly different, so you should have been using id
based selector to achieve the same result:
fill_in "user_name", with: 'Example User'
So, to sum up, label
field is not required, but you should watch for your html code carefully and select the appropriate parameters for fill_in
expression.
Just to add to what twonegatives posted. Here's what the capybara docs say for the fill_in() method:
The field can be found via its name [attribute], id [attribute,] or label text
http://rubydoc.info/github/jnicklas/capybara/Capybara/Node/Actions:fill_in
When I delete the 'Name' label, I can use any of the following and the tests still pass:
fill_in 'user_name', with: "Example User" #locate text field by id attribute
fill_in :user_name, with: "Example User" #locate text field by id attribute
fill_in 'user[name]', with: "Example User" #locate text field by name attribute
fill_in :'user[name]' with: "Example User" #locate text field by name attribute
In ruby, some characters cannot be used in a symbol name unless the whole symbol is quoted.
Capybara must be retrieving all the text fields (or text areas) from the page, then getting the values of the id and name attributes(easily done with something like Nokogiri) then checking if either value is equal to the first argument to fill_in() (after converting the first argument to a String via to_s()).
I provided my 2 cents here: Capybara not finding form elements.
If you call the Rails text_field helper with underscore (:first_name), the DOM gets rendered as "First name" and its what Capybara will need. No need for an id attribute.
View:
<%= form.text_field :first_name %>
Test:
fill_in "First name", with: 'Elaine'