How can I check that a form field is prefilled correctly using capybara?
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")
Related videos on Youtube
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, 2022Comments
-
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 almost 12 yearsAh, I was missing the
.value
bit. Thanks! -
John Y over 11 yearsI 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 almost 11 yearsThe 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 over 10 yearsI 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 otherNode::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 over 10 yearsMuch better than the selected answer!
-
DVG over 10 yearsTrue, expect would be the preferred way now, however that syntax was released about a month after this question.
-
mraaroncruz over 10 yearsI 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 about 10 yearsYou are a saviour!Thanks for the perfect answer.
-
Avi Tevet about 10 yearsThis worked for me when using typeahead.js to verify the contents of the field, while the xpath matcher did not.
-
roman-roman about 10 yearsI think that happens because with that have_field capybara is waiting some time for that field before reporting failure.
-
user664833 almost 10 yearsWith Minitest the lines look like this:
assert has_xpath?("//input[@value='John']")
andassert_equal 'John', find_field('Your name').value
-
Nick almost 10 yearsAs 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 almost 10 yearsPassing in
with
definitely only returned true if the value matches, for me, which is the expected result. -
Patru over 9 yearsMaybe 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 almost 9 yearsYou 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 almost 8 yearsIf 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 almost 8 yearsOne 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 about 3 yearsThis has the advantage of being DOM-agnostic. It works for other form fields like
textarea
.