Cucumber, capybara and selenium - 无需按钮即可提交表单

Posted

技术标签:

【中文标题】Cucumber, capybara and selenium - 无需按钮即可提交表单【英文标题】:Cucumber, capybara and selenium - Submitting a form without a button 【发布时间】:2011-02-17 08:55:43 【问题描述】:

我有一个使用 Cucumber、capybara 和 selenium 驱动程序的测试。这个测试应该去一个表格并提交它。正常的文本是

  Scenario: Fill form
    Given I am on the Form page
    When I fill in "field1" with "value1"
    And I fill in "field2" with "value2"
    And I press "OK"
    Then I should see "Form submited"

问题是表单中没有确定按钮 我需要一种方法来执行“form.submit”,而无需单击任何按钮或链接 - 与使用浏览器在表单字段中按 ENTER 时发生的情况相同。

我不知道如何告诉 capybara 提交表单。我该怎么做?

【问题讨论】:

【参考方案1】:

您可以访问 selenium send_keys 方法来调用返回事件,例如

 find_field('field2').native.send_key(:enter)

【讨论】:

请注意,至少对于使用 poltergeist 作为驱动程序的我来说,您必须使用 :Enter【参考方案2】:

一个简单的解决方案:

When /^I submit the form$/ do
  page.evaluate_script("document.forms[0].submit()")
end

使用 capybara-envjs 为我工作。也应该与硒一起使用。

【讨论】:

还有另一个类似的解决方案:page.execute_script("$('form#your-form').submit()") -- 另外,请查看有关 Capybara::Session#execute_script 的注释(它说 execute_script 应尽可能使用而不是 evaluate_script) -- 这只是一个需要考虑的信息。【参考方案3】:

我只需要自己解决这个问题。在 webrat 我有这样的事情:

Then /^I submit the "([^\"]*)" form$/ do |form_id|
  submit_form form_id
end

我能够在 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

【讨论】:

这太棒了,因为它甚至不需要javascript!所以它不应该依赖于驱动程序的实现(就像世界上其他所有东西一样......)特别是它根本不需要 js。【参考方案4】:

使用 capybara Selenium 驱动程序,您可以执行以下操作:

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

【讨论】:

【参考方案5】:

简单地说:你不能。

某些浏览器根本不允许您在没有提交按钮的情况下提交表单(尤其是 Internet Explorer

【讨论】:

问题是我无法添加按钮,因为我正在测试一个网站我无法更改源代码。【参考方案6】:

您可能会推出自己的步骤(例如,我提交带有“Ok”链接的表单),并自己模拟提交功能。

这是在 Rails 3 中删除的 javascript 模拟,以支持“不显眼”(强调引号)Javascript。线

Capybara::Driver::RackTest::Form.new(driver, js_form(self[:href], emulated_method)).submit(self)

可能是回答您问题的线索。完整代码是here

【讨论】:

我认为确实如此。我现在在应用程序中使用带有确认对话框的表单提交没有问题,并且它们工作正常。【参考方案7】:

我建议您添加一个提交按钮,然后使用 CSS 将其隐藏。然后你可以测试表单提交,但仍然得到你想要的用户行为。

【讨论】:

【参考方案8】:

使用 Webrat,您可以:

When /^I submit the form$/ do
  submit_form "form_id"
end

p。 307,RSpec 书

【讨论】:

【参考方案9】:

display:none 解决方案不适用于使用 selenium 驱动程序的 capybara,因为 selenium 抱怨与不可见元素交互。 如果您尝试上述解决方案,您最终可能会看到以下错误消息:

Element is not currently visible and so may not be interacted with (Selenium::WebDriver::Error::ElementNotVisibleError)

【讨论】:

【参考方案10】:

您可以尝试发送换行符:

find_field('field2').native.send_key("\n")

【讨论】:

【参考方案11】:

这有点骇人听闻,但它满足了需求。我对 Capybara 进行了猴子补丁以支持元素上的 #submit 方法。

它并不健壮,因为它天真地从每个输入元素的 namevalue 属性创建 POST 参数。 (在我的例子中,我所有的 <input> 元素都是 hidden 类型的,所以它工作正常。

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

【讨论】:

【参考方案12】:

试试这个..

find(:css, "input[name$='login']").native.send_keys :enter

【讨论】:

以上是关于Cucumber, capybara and selenium - 无需按钮即可提交表单的主要内容,如果未能解决你的问题,请参考以下文章

Rails、Cucumber、Capybara:会话不持久

Cucumber 和 Capybara,单击非链接或按钮元素

Rails + Cucumber/Capybara:如何在测试中设置/检索 cookie?

Cucumber / Capybara 错误:参数 [0] 未定义(Selenium::WebDriver::Error::JavascriptError)

Rails Cucumber使用Capybara测试AJAX

在 Cucumber + Capybara + PhantomJS 在 Rails 中调试 jQuery Ajax