Migrating to form_with
Whilst upgrading a Rails application from 4.1 to 5.2, my feature specs started throwing a strange error:
Unable to find field "X" that is disabled (Capybara::ElementNotFound)
I reverted my changes... the tests passed. Step 1 in debugging: read the error message. Capybara is saying the element I'm trying to find is disabled. If I inspect the html generated by form_for
:
= form_for book do |f|
= f.label :title, 'Title'
= f.text_field :title
= f.button 'Save Changes', type: :submit
<form action="/books/14" accept-charset="UTF-8" method="post">
<label for="book_title">Title</label>
<input type="text" name="book[title]" id="book_title">
<button name="button" type="submit">Save Changes</button>
</form>
and compare it to the html generated by form_with
:
= form_with model: book, local: true do |f|
= f.label :title, 'Title'
= f.text_field :title
= f.button 'Save Changes', type: :submit
<form action="/books/14" accept-charset="UTF-8" method="post">
<label for="book_title">Title</label>
<input type="text" name="book[title]">
<button name="button" type="submit">Save Changes</button>
</form>
Notice what's missing. form_with
does not automatically generates ids for form elements, and the id is necessary to link the label's for
with the input's id
, otherwise fill_in('Title', with: "Pride and Prejudice")
doesn't work in Capybara. Either add the ids manually, or in Rails 5.2 use this setting:
Rails.application.config.action_view.form_with_generates_ids = true
Tweet