水豚:在form.submit()上添加setTimeout时,会话丢失

时间:2019-07-18 17:22:50

标签: ruby-on-rails capybara rspec-rails

Rails v4.2.7

我有一个Rails表单(非远程),带有提交按钮,并附加了此事件,既可以防止重复提交,又可以向用户显示更好的反馈(基本上是data-disable-with将用于远程表单):

    $('#my-submit-button').on "click", ->
      this.disabled = "disabled"
      this.value = "Loading..."
      $(this).removeClass("button-active-class")
      $(this).addClass("button-busy-class")

      myForm = this.form
      setTimeout ->
        myForm.submit()
      , 500

使用setTimeout的原因是,如果我立即提交表单,由于某些原因在Safari中,样式更改将不会应用。

这很好用。

但是,我有一个像这样的Capybara测试(使用headless_chrome):

sign_in user

visit my_page_path

# fill in form

find("#my-submit-button").click

expect(page).to have_content "some content"

由于某种原因,我注意到在提交表单后current_user被设置为nil,所以我在ApplicationController中以before_filter的形式添加了cookie的日志:

def my_before_filter
  p cookies.first
end

并且输出有效地向我显示了两次访问以及表单提交触发的请求之间的两个cookie。 因此,我删除了setTimeout,以便立即提交表单:

    $('#my-submit-button').on "click", ->
      # [...]

      # myForm = this.form
      # setTimeout ->
        # myForm.submit()
      # , 500

      this.form.submit()

现在,即使在单击按钮后未正确应用样式,测试通过和cookie也相同。

有什么想法吗?如何解决?

1 个答案:

答案 0 :(得分:0)

注意:这是基于您的sign_in方法实际上访问页面,填写登录信息并提交表单的假设而做出的猜测。如果您的sign_in方法实际上是通过devise warden测试模式之类的快捷方式,那将是不正确的。

听起来您的$('#my-submit-button')也被应用于登录表单上的“提交”按钮。通过延迟半秒(似乎要延迟很长时间),驱动程序不再检测到sign_in中完成的动作正在触发页面转换,因此不再等待它。这意味着visit my_page_path将在登录完成并返回正确的cookie之前执行。您的sign_in方法的结尾应该有一个积极的期望,即页面上指示登录已按照

行完成的内容
expect(page).to have_text('You are logged in!')