65

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
skalee
  • 12,331
  • 6
  • 55
  • 57
  • 3
    normally a person can't fill in a hidden field, so therefor capybara doesn't fill them in. see https://groups.google.com/forum/?fromgroups#!topic/ruby-capybara/EstLVItkyrA for more discussion. But normally you either populate it on the server or use javascript.. – Doon May 29 '12 at 18:58
  • @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](http://pivotal.github.com/jasmine/) or [Chai](http://chaijs.com/). 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 Jan 24 '13 at 15:37

4 Answers4

85

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()")
Chris Peters
  • 17,918
  • 6
  • 49
  • 65
DVG
  • 17,392
  • 7
  • 61
  • 88
  • Yes, XPath did the job. You have a typo near @, it should rather be `find(:xpath, "//input[@id='my_hidden_field_id']").set "my value"` – skalee May 29 '12 at 19:55
  • 18
    CSS matchers worked fine for me as well `find("#my_hidden_field").set("my value")` – bonyiii Mar 24 '13 at 20:11
  • 16
    FWIW, this no longer works for me as of Capybara 2.7.1. Fixed by passing `visible: false` to the `#find` method. – Ryan Dlugosz Jun 13 '16 at 17:58
  • @RyanDlugosz - `page.execute_script` definitely still works, even with Capybara's new constraints on clicking hidden/invisible DOM elements. – danielricecodes Apr 04 '19 at 15:39
  • Works Perfect with skalee and ryan-dlugosz comments combined: `find("#my_hidden_field", visible: false).set("my value")` – Markus Andreas May 14 '21 at 11:29
60

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")
Luis D Urraca
  • 2,024
  • 4
  • 24
  • 46
7

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'");
penner
  • 2,707
  • 1
  • 37
  • 48
4

This is what worked for me

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