How can I check that a form field is prefilled correctly using capybara?

82,816

Solution 1

You can use an xpath query to check if there's an input element with a particular value (e.g. 'John'):

expect(page).to have_xpath("//input[@value='John']")

See http://www.w3schools.com/xpath/xpath_syntax.asp for more info.

For perhaps a prettier way:

expect(find_field('Your name').value).to eq 'John'

EDIT: Nowadays I'd probably use have_selector

expect(page).to have_selector("input[value='John']")

If you are using the page object pattern(you should be!)

class MyPage < SitePrism::Page
  element :my_field, "input#my_id"

  def has_secret_value?(value)
    my_field.value == value
  end
end

my_page = MyPage.new

expect(my_page).to have_secret_value "foo"

Solution 2

Another pretty solution would be:

page.should have_field('Your name', with: 'John')

or

expect(page).to have_field('Your name', with: 'John')

respectively.

Also see the reference.

Note: for disabled inputs, you'll need to add the option disabled: true.

Solution 3

If you specifically want to test for a placeholder, use:

page.should have_field("some_field_name", placeholder: "Some Placeholder")

or:

expect(page).to have_field("some_field_name", placeholder: "Some Placeholder")

If you want to test the user-entered value:

page.should have_field("some_field_name", with: "Some Entered Value")
Share:
82,816

Related videos on Youtube

Marc-André Lafortune
Author by

Marc-André Lafortune

♥ Ruby ♥ Javascript ♥ I'm a committer on: Ruby RuboCop DeepCover Parsley.js Featherlight.js Don't be surprised if I refer to my extensive list of polyfills that makes it easier to write Ruby code for different versions of Ruby. My blog: # Hash

Updated on July 08, 2022

Comments

  • Marc-André Lafortune
    Marc-André Lafortune almost 2 years

    I have a field with a proper label that I can fill in with capybara without a problem:

    fill_in 'Your name', with: 'John'
    

    I'd like to check the value it has before filling it in and can't figure it out.

    If I add after the fill_in the following line:

    find_field('Your name').should have_content('John')
    

    That test fails, although the filling just before worked as I've verified by saving the page.

    What am I missing?

  • Marc-André Lafortune
    Marc-André Lafortune almost 12 years
    Ah, I was missing the .value bit. Thanks!
  • John Y
    John Y over 11 years
    I was having the same problem, but with a div rather than a form field. For anybody else having the same problem, use find_by_id().text rather than find_field().value. It took me ages to spot that value only worked on form fields…
  • fqxp
    fqxp almost 11 years
    The problem with the latter way is that it does not use Capybara's polling cycle and therefore will fail instantly if the field is set by longer-running JS code. The first way is to be preferred unless you are trying this on a statically generated form.
  • Agent47DarkSoul
    Agent47DarkSoul over 10 years
    I think @fqxp has a better answer which uses RSpec Matchers and the new expectation syntax. From what I see in the documentation, find_field and other Node::Finders are used to find nodes and perform actions on them rather than expectation. Of course this is not a rule, but for something simple as this going with the inbuilt solution is a better idea. Just saying!
  • Agent47DarkSoul
    Agent47DarkSoul over 10 years
    Much better than the selected answer!
  • DVG
    DVG over 10 years
    True, expect would be the preferred way now, however that syntax was released about a month after this question.
  • mraaroncruz
    mraaroncruz over 10 years
    I would still prefer the selected answer because the error message shows you the expected and actual strings. This gives the unhelpful "expected field "my field" to return something" error. But this one does definitely read better and follows the page matcher API better. Upvotes all around!!!
  • PriyankaK
    PriyankaK about 10 years
    You are a saviour!Thanks for the perfect answer.
  • Avi Tevet
    Avi Tevet about 10 years
    This worked for me when using typeahead.js to verify the contents of the field, while the xpath matcher did not.
  • roman-roman
    roman-roman about 10 years
    I think that happens because with that have_field capybara is waiting some time for that field before reporting failure.
  • user664833
    user664833 almost 10 years
    With Minitest the lines look like this: assert has_xpath?("//input[@value='John']") and assert_equal 'John', find_field('Your name').value
  • Nick
    Nick almost 10 years
    As far as I can tell, this doesn't actually confirm the value of the field, just the presence of the field regardless of value. I'm guessing it's a bug since the docs say it should filter based on value.
  • Ben Saufley
    Ben Saufley almost 10 years
    Passing in with definitely only returned true if the value matches, for me, which is the expected result.
  • Patru
    Patru over 9 years
    Maybe the error message has been improved since the answer was first written, but I now get expected […] but there were no matches. Also found "", which matched the selector but not all filters.. on an empty field which comes very close to a very nice error message.
  • siannopollo
    siannopollo almost 9 years
    You could also use the form find_field('field-name').value.should have_content('John') if you don't want to match on the entire field value.
  • pduey
    pduey almost 8 years
    If you're using poltergeist, this answer is best because it will keep checking until the configured timeout, so you don't need a bunch of lame sleeps in your specs.
  • mahi-man
    mahi-man almost 8 years
    One more thing to look out for - if you field is disabled, you must do expect(page).to have_field('Your name', with: 'John', disabled: true) for this to work.
  • David Cook
    David Cook about 3 years
    This has the advantage of being DOM-agnostic. It works for other form fields like textarea.