ruby-on-railscapybararuby-on-rails-7

How to get the value of a form field in capybara?


Is there a way to get the value of a form field out of Capybara?

I know I can check that a form field is pre-filled correctly in Minitest by using:

assert page.has_field? "some_field", with: "some_value"

But is there a way to get the form field value, the way capybara reads it? The reason I ask is that I am trying to get capybara to test whether a datetime_field is prefilled correctly, and I'm having a heck of a time getting the strftime format correct. If I could get the value that capybara is checking against out even once using debugger or puts, then it would be trivial to design the with: "some_value" correctly.

--EDIT-- Ok, contrary to my comment, I am still struggling with this. I got it working on one part of a form by matching the format of the value="" attribute in the html tag.

But now I am dealing with another part of the form where a default value is filled in based on a turbo frame refresh using a value that's inputted earlier.

When I try save_page in Capybara, the html source contains this:

<input class="form-control" value="2024-02-07T00:17:00" type="datetime-local" name="record[actual_end_datetime]" id="record_actual_end_datetime">

But yet this Minitest assertion fails:

puts the_time = p_e_time.in_time_zone.strftime("%Y-%m-%dT%H:%M:00")
assert page.has_field? "record[actual_end_datetime]", with: the_time

Even though the puts output matches the exact string that is seen in the html: 2024-02-07T00:17:00. The test passes if I comment out the 'with:', so I'm really struggling to see how to get this match to work.

Any insight is appreciated!


Solution

  • Your answer about using find_field(...).value is correct, and returns the value property which is different from the value attribute in the HTML since the value property is updated with user edits. That being said you should NEVER be using Capybaras predicates with asset like

    assert page.has_field? ...
    

    By using that you are potentially removing Capybaras retrying behavior (important for async page updates) and losing the detailed error messages which would have likely given you what you wanted in the first place. Instead you should be using the assertions provided by Capybara and doing

    assert_field("record[actual_end_datetime]", with: the_time)