【问题标题】:Capybara Webkit doesn't seem to submit the form quickly enoughCapybara Webkit 提交表单的速度似乎不够快
【发布时间】:2017-12-29 04:57:27
【问题描述】:

我正在使用 Capybara 测试一个基本表单 - 当用户填写并提交时,它应该创建一个新的 User 记录

it "creates a new user" do
  visit some_random_path

  # Fill In Form
  fill_in("name", with: "foo bar")
  fill_in("email", with: "foo.bar@example.com")

  expect do
    click_button("Submit")
  end.to change { User.count }.by(1)
end

expect 块会引发错误,因为它没有看到 User.count 增加 1。但是我注意到,如果我执行类似的操作

click_button("Submit") && sleep(0.1)

效果很好!

所以看起来 RSpec 正在尝试快速检查 - 即在 Capybara 运行的浏览器有机会实际提交表单并将结果提交到数据库之前。

我没有使用任何 JavaScript,只是一个普通的旧 :webkit 规范。

对为什么会发生这种情况有什么想法吗?

下面是我的 Capybara 配置。我有一个多租户应用程序(我使用apartment gem 来处理重要的事情)所以我使用localhostlvh.me 作为应用程序主机,如下所述,但我无法想象这会干扰以上。

Capybara.configure do |config|
  config.ignore_hidden_elements = true
  Capybara.default_driver = :webkit
  config.javascript_driver = :webkit
end

Capybara::Webkit.configure do |config|
  config.block_unknown_urls
  config.allow_url("lvh.me")
end

RSpec.configure do |config|
  config.before(:suite) do
    Capybara.always_include_port = true
    # The default is to treat each spec as single tennat, in which case
    # we want to hit localhost. Hitting the Capbyara default of www.example.com
    # causes the apartment setup to try and parse the `www` as a subdomain
    Capybara.app_host = "http://localhost"
  end

  config.before(:each, multi_tenant: true) do
    # For multi-tenant specs, use "lvh.me"
    Capybara.app_host = "http://lvh.me"
  end
end

谢谢!

【问题讨论】:

    标签: rspec capybara capybara-webkit


    【解决方案1】:

    当使用带有 Capybara 的“真正的浏览器”驱动程序之一(除了 rack_test 之外的几乎所有驱动程序)时,单击按钮触发的任何操作都不能保证在单击方法返回时完成。这意味着您需要在继续之前检查页面上表明操作已完成的可见更改。在你的情况下,这意味着像

    expect do
      click_button("Submit")
      expect(page).to have_text("New User Created") # whatever appears on screen to indicate successful creation of the user
    end.to change { User.count }.by(1)
    

    请注意,在编写功能测试时,对事物进行直接数据库检查通常被认为是不良代码气味,您真的应该只检查用户索引页面上显示的新用户,确认出现成功消息或类似的东西而不是检查User.count

    【讨论】:

    • 修复效果很好!我最终使用expect(current_path).to eq(current_path) 作为一种技巧,让它等到current_path 可用。另外,在个人笔记中,感谢您对 Capybara 的持续支持 - 这是一个非常有用的工具,我知道维护它需要时间/精力,因此非常感谢。
    • @user2490003 嗯——我不确定expect(current_path).to eq(current_path) 实际上会做什么——这种行为可能与驱动程序高度相关。如果你知道你期望的路径expect(page).to have_current_path(expected_path) 会更好(使用eq 匹配器和current_path/current_url 绝不是一个好主意)
    猜你喜欢
    • 2014-02-03
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2012-10-17
    • 1970-01-01
    相关资源
    最近更新 更多