Reputation: 268
I have been trying to set up Capybara to test a form but I keep getting the error
cannot fill in, no text field, text area or password field with id, name, or label 'Name' found
Here is what I have in my view:
<%= form_for(@user) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
...
<%= f.submit "Create Account", class: "btn btn-large btn-primary" %>
<% end %>
which renders the following html:
<label for="user_name">Name</label>
<input id="user_name" name="user[name]" size="30" type="text" />
So it seems like it should be finding the field based on the label.
Here is what my user_pages_test.rb file has (I am using Test::Unit and shoulda-context):
context "sign up page" do
should "add user to database when fields are filled in" do
fill_in "Name", with: "Bubbles"
...
click_button "Create Account"
end
end
Here is what I've tried so far:
1) changing the call to fill_in
to match the id with fill_in "user_name", with: "Bubbles"
2) changing the call to fill_in
to page.fill_in "Name", with: "Bubbles"
to match the example in the documentation
3) changing the view to manually add the id "Name"
with <%= f.text_field :name, id: "Name" %>
(this answer)
4) changing the call to get sign_up_path
to get "/sign_up"
(in case it was an issue with the routing)
All these still give me the same error, which makes me think that the page isn't being loaded correctly for some reason. However, I have a different (passing) test in the same context that asserts the page has the correct title, so I know the page does get loaded correctly (in the setup
).
Based on this (and according to this answer), it seems like the problem might just be that the fill_in
method isn't waiting for the page to load before trying to access the fields. According to this suggestion, I added the line puts page.body
in my test to see that the HTML was being loaded completely before it was trying to fill in the fields, and got the following output:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
So, I was pretty sure that fill_in
just wasn't waiting for the page to load. I then tried
5) changing the Capybara.default_wait_time
according to this answer, but this had no effect. I tried setting it in the ActionDispatch::IntegrationTest
class in the test_helper file (where Capybara is included), and also in the test itself.
Then I tried adding puts page.body
in the passing test (both before and after it asserts the correct title), and I got the same output. THEN, I found this answer, and finally got the console to print out the page's HTML. I tried one more thing to get Capybara to fill in the fields:
6) changed the call to fill_in
to say @response.fill_in
, since @response
seems to do what I thought the page
variable was supposed to do.
So, I have two questions about this:
1) What does the page
variable actually refer to? The doctype declaration for my app is just <!DOCTYPE html>
, so I have no idea where it gets the old one from.
2) Why isn't Capybara able to find/fill_in these fields?
Upvotes: 3
Views: 2072
Reputation: 4808
You need to use the visit
method to get the page object setup properly. The capybara documentation indicates that '/' is visited by default and if you want to visit some other page you need to do an explicit call. It may also be helpful to read a bit about the difference between visit
and get
.
Upvotes: 1