I have a test using Cucumber, capybara and selenium driver. This test should go to a form and submit it. The normal text would be
Scenario: Fill form
Give
This is a bit hackish, but it filled a need. I monkey-patched Capybara to support a #submit
method on elements.
It is not robust because it naively creates the POST parameters from every input elements's name
and value
attributes. (In my case, all my <input>
elements were of type hidden
, so it works fine).
class Capybara::Node::Element
# If self is a form element, submit the form by building a
# parameters from all 'input' tags within this form.
def submit
raise "Can only submit form, not #{tag_name}" unless tag_name =~ /form/i
method = self['method'].to_sym
url = self['action']
params = all(:css, 'input').reduce({}) do |acc, input|
acc.store(input['name'], input['value'])
acc
end
session.driver.submit(method, url, params)
end
end
...
form = find('#my_form_with_no_submit_button')
form.submit
With the capybara Selenium driver you can do something like this:
within(:xpath, "//form[@id='the_form']") do
locate(:xpath, "//input[@name='the_input']").set(value)
locate(:xpath, "//input[@name='the_input']").node.send_keys(:return)
end
With Webrat you can just:
When /^I submit the form$/ do
submit_form "form_id"
end
p. 307, The RSpec Book
I just had to solve this problem myself. In webrat I had something like this:
Then /^I submit the "([^\"]*)" form$/ do |form_id|
submit_form form_id
end
I was able to achieve the same thing with this in Capybara:
Then /^I submit the "([^\"]*)" form$/ do |form_id|
element = find_by_id(form_id)
Capybara::RackTest::Form.new(page.driver, element.native).submit :name => nil
end
Simply put: you can't.
Some browsers will not allow you to submit a form without a submit button at all (most notably Internet Explorer <= 6). So this kind of form is a bad idea to begin with. Add a submit button and position it off the screen with CSS.
Try this..
find(:css, "input[name$='login']").native.send_keys :enter