skip to Main Content

It appears that Capybara is unable to find the first form element on a page by the displayed text within that form-element’s label.

Capybara can however find that first form-element by that label’s for value, which seems odd. I’m thinking the DOM just hasn’t loaded yet, and Capybara can continuously search for for values but not the displayed text within labels?

Here is what my relevant form elements look like:

relevant form elements

so I should be able to grab each of these elements by the displayed Label text by saying:

fill_in "First Name", with: "foo"
fill_in "Last Name", with: "bar"
fill_in "Title", with: "some title"

Here is my spec:

scenario "with minimum fields while passing validations", js: true do
  visit "/"
  click_link "New Contact"
  fill_in "First Name", with: "foo"
  fill_in "Last Name", with: "bar"
  fill_in "Title", with: "some title"

  click_button "Create Contact"
  expect(page).to have_content "Success."
  expect(page).to have_content "foo bar"
end

It is not finding the First Name form element so it isn’t filling it in. It finds the Last Name element and the Title element just fine because I am assuming that the DOM has fully loaded by that time:

not filling in first name

This is the html:

the html

However, oddly enough: when I change filling in the First name from:

fill_in "First Name, with: "foo"

To:

fill_in "contact_first_name, with: "foo"

It works now, but I don’t want to use the for value of contact_first_name to grab that form element. I want to use the displayed label text as I am able to with The Title and Last Name.

enter image description here

What am I missing? Why can’t I use “First Name” to grab the First Name form element?

Update: It turns out that if I put sleep 1 right before `fill_in “First Name”, with: “foo” then it works! According to comments below from @TomWalpole, it seems like there is a javascript library that is getting in the way? Below are all the javascripts I include in:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require twitter/typeahead.min
//= require nested_form_fields

2

Answers


  1. If slow page loading is the case and especially if some Javascript and / or CSS animation is involved, then try raising the Capybara.default_max_wait_time to e.g. 30 seconds (the default is 2 seconds). And the fill_in should start working.

    The fill_in, as well as most other Capybara methods, is “synchronized”, i.e. it retries searching for the field up to the default max wait time and only if it is not found after this time, it fails.

    See the Capybara readme.

    Login or Signup to reply.
  2. Capybara is actually finding the input and filling it in, but then the value is being removed. This is because you have some JS library that is adding functionality/behavior to the input after the Capybara has filled in the element. Once the JS has augmented the input it is resetting its value to the inputs value property (as opposed to the value attribute which has been changed) which ends up setting it back to blank. Sleeping before the first fill_in is a workaround, other than that it would mean figuring out what JS is being run on the element and waiting for a detectable change (if there are any) before calling fill_in.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search