Alessandro De Simone
Alessandro De Simone

Reputation: 4215

Capybara - Submit a form without button

I am trying to submit a form without button using just Capybara and Rspec (no Cucumber or Selenium, I know there is already a question about that).

I've seen there is a gist to add a method to submit a form without button:

module SubmitRackTestFormWithoutButton
  def submit_form!
    Capybara::RackTest::Form.new(driver, form).submit({})
  end
end
Capybara::RackTest::Node.send :include, SubmitRackTestFormWithoutButton

https://gist.github.com/989533, but I've not gotten it to work and I left a comment on it:

I get undefined method `submit_form!' for #Capybara::Node::Element:... actually by "Capybara::RackTest::Node.send :include, SubmitRackTestFormWithoutButton" the method submit_form! is added to the Node (not to the Element), but find return an Element

Do you have some idea to work out that gist, or some other solution to submit a form without button ?

Thanks

Upvotes: 29

Views: 22005

Answers (9)

felixbuenemann
felixbuenemann

Reputation: 639

None of the above solutions work with the current capybara 3.40.0 when using the :rack_test driver.

After reading the source I came up with this one-liner to submit a form:

Capybara::RackTest::Form.new(page.driver.browser, page.find("form").native).submit(nil)

Upvotes: 0

Adrien Rey-Jarthon
Adrien Rey-Jarthon

Reputation: 1154

As I was looking for the same thing and @Motine mentionned in some comments this issue, I just discovered here this very nice and concise way (IMO) to submit single input forms (like a search field) when using the RackTest driver (no selenium, cuprite, javascript, etc.):

fill_in 'q', with: "search\n"

The trick is simply to add the "\n" at the end of the string and if there's only one input in the form, the RackTest driver will strip the newline and submit the form (as if you hit enter).

Upvotes: 0

equivalent8
equivalent8

Reputation: 14227

best solution is by using JS driver test (as mentioned comment above):

page.execute_script(%q{document.querySelector("form[action='/admin/opt_outs']").submit()})

if no JS driver:

Fact is every form should have a button, if the button should not appear in UI just hide it with display: none and then instead click_button do:

find('form input[type=submit]', visible: false)

Upvotes: 0

Cruz Nunez
Cruz Nunez

Reputation: 3139

Here's a simple solution that doesn't require capybary-webkit, qt, lmnop or whatever.

Does not require a submit button. People say you need it but whatever.

Just monkeypatch a class or two

# /spec/support/capybara.rb
  class Capybara::Session
    def submit(element)
      Capybara::RackTest::Form.new(driver, element.native).submit({})
    end
  end

Then you can do something like

require 'support/capybara'

before do
  create :lead
  create :user, :different_email
end

it 'Searchable' do
  visit users_path
  page.should have_content 'Slicer'
  page.should have_content 'Dicer'

  fill_in 'Search', with: 'dice'

  form = find '#search-form' # find the form
  page.submit form           # use the new .submit method, pass form as the argument

  page.should have_content 'Dicer'
  page.should_not have_content 'Slicer'
end

It's kinda like jacob's answer on here but for his you have to define that in the middle of the test.

For this solution, you can define this in some file in the /support directory or at the beginning of that one spec, etc. It reduces the clutter in the test.

Upvotes: 10

Now You should use click_on

click_on 'Sign up'

Upvotes: 0

Rob Fox
Rob Fox

Reputation: 5581

You can do this by pressing enter within the input

find('form input').native.send_keys :enter

Upvotes: 10

jacob
jacob

Reputation: 365

I got this to work in capybara 1.1.2 with:

  form = page.find("form")
  class << form
    def submit!
      Capybara::RackTest::Form.new(driver, native).submit({})
    end
  end
  form.submit!

and it looks like a similar solution is described here: http://minimul.com/submitting-a-form-without-a-button-using-capybara.html

Upvotes: 4

Marcelo Eden
Marcelo Eden

Reputation: 351

All your production code should be testable, so if you add a code that is only used by the test than the test will make no sense...

Try to do this instead:

page.execute_script("$('form#your-form').submit()")

Upvotes: 31

Mario Visic
Mario Visic

Reputation: 2663

Although it's possible to achieve what you want using capybara, the easier and more practical solution is to put a submit button on the form.

There is no reason to not have a button on the form, it's bad accessibility to not have a form and users that do not have a GUI or are using screen readers will have trouble submitting the form otherwise.

If you don't want the form button to be visible, can I suggest using some CSS to make it hidden:

<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;">

Upvotes: 0

Related Questions