0

在我的 Rails 应用程序中,我使用以下 jQuery 来禁用通过在输入字段中按“输入”来提交表单的功能:

$('input').on('keydown', function(e) {
  if(e.which == '13') {
    return false;
  }
})

我想用 Capybara 测试这个,但不知道怎么做。例如:

# the form being tested creates a new Shift object: 
test "enter does not submit form" do
  shift_count = Shift.count
  # fill in form, etc...
  page.driver.browser.execute_script "var e = jQuery.Event('keydown'); e.which = 13; $('#shift_employee').trigger( e );"
  assert Shift.count == shift_count
end

即使 jQuery 函数被注释掉,这个测试也通过了,大概是因为它Shift.count在 ActiveRecord 有时间将新记录保存到数据库之前计算。

我还尝试让 jQuery 函数执行自定义$.get()请求,控制器以简单的文本对其进行响应,认为这将建立足够的时间来完成所有服务器端工作。但这仍然不起作用,我认为这是因为,无论我如何设置 jQuery 函数,提交表单和保存新记录总是会发生在我构建的任何 AJAX 内容之后。

关于如何可靠地测试表单未提交的任何想法?

4

2 回答 2

0

我让 Capybara 重新访问页面,然后检查Shift.count. 现在,当 jQuery 函数被注释掉时测试会失败,而当函数被取消注释时测试会通过。不过,我仍然想知道是否有更好的方法。

于 2013-09-05T19:33:36.080 回答
0

那么表单提交是通过AJAX完成的吗?这是测试人员在使用 Capybara 时遇到的常见问题。您需要做的是等待 AJAX 完成。

有两种方法可以做到这一点。一个非常具体,是首选方法,另一个是通用的,只有在第一种方法无法完成时才应使用。

第一种方法是等待 DOM 上的内容发生变化。在您的情况下,什么都不会改变,但是,例如,如果出现警告说“您不能按 Enter,您必须单击保存按钮!” 那么您可以通过执行以下操作来等待它出现:

page.driver.browser ... # your code
page.should have_css(".info", :text => "You cannot ...etc...")

当然,您不必使用该:text选项。

另一种方法是创建一个辅助方法,例如wait_for_ajax,它会进行通用等待,直到 AJAX 完成。

def wait_for_ajax
  start = Time.now
  while true
    break if (page.evaluate_script('$.active') == 0)
    if Time.now > start + Capybara.default_wait_time.seconds
      fail "AJAX did not register as complete after #{Capybara.default_wait_time} seconds!"
    end
    sleep 0.1
  end
end

这是基于人们过去检查 AJAX 的旧方法,但这种新脚本更适合 Capybara 2.0。

然后你的步骤会做:

page.driver.etc
wait_for_ajax

wait_for_ajax方法可以进入 Cucumber 将加载的任何文件。

于 2013-09-04T19:58:21.407 回答