61
votes

I've already found that when I want to set value to text field, text area or password field, I can use id, name or label as something in fill_in something, :with => some_value. However such approach fails when I try to set value to <input type="hidden"> field (and I want to do it because those are normally filled client-side scripts which I test separately). How could I set such a hidden field with Capybara? Is it possible?

HTML:

<input id='offer_latitude' name='offer[latitude]' type='hidden'>
<input id='offer_longitude' name='offer[longitude]' type='hidden'>

spec:

describe "posting new offer" do
  it "should add new offer" do
    visit '/offer/new'
    fill_in 'offer[latitude]', :with => '11.11'
    fill_in 'offer[longitude]', :with => '12.12'
    click_on 'add'
  end
end

gives:

1) posting new offer should add new offer
   Failure/Error: fill_in 'offer[latitude]', :with => '11.11'
   Capybara::ElementNotFound:
     cannot fill in, no text field, text area or password field with id, name, or label 'offer[latitude]' found
4
normally a person can't fill in a hidden field, so therefor capybara doesn't fill them in. see groups.google.com/forum/?fromgroups#!topic/ruby-capybara/… for more discussion. But normally you either populate it on the server or use javascript..Doon
@Doon's comment is very true. If you want to inspect/alter hidden input, most probably you're using wrong tool. Capybara is designed to test whole application in various scenarios, not to test your JS components. Checkout Jasmine or Chai. However there are situations where it's sensible, for example filling HTML5 inputs which are polyfilled in incompatible browsers. Polyfills often hide proper input and insert additional markup.skalee

4 Answers

83
votes

You need to locate the hidden field and set its value. There are a couple ways, this is probably the simplest

find(:xpath, "//input[@id='my_hidden_field_id']").set "my value"

If you're executing a client_side script in production, you could just tell capybara to run it with a javascript-compliant driver

page.execute_script("$('hidden_field_id').my_function()")
57
votes

There are many ways to achieve the same result. The one I like the most is:

first('input#id.class', visible: false).set("your value")
4
votes

If you're using poltergeist/phantomjs as a driver and jquery isn't working for ya, there's always good old fashioned js:

page.execute_script("document.getElementById('#some-id').value = 'some-value'");
1
votes

This is what worked for me

find_field(id: 'your_hidden_field_id', type: :hidden).set('Field value here')