如何在 Rails 中使用 Capybara 和 Minitest 测试 Cocoon gem 的嵌套形式

How to test Cocoon gem's nested forms with Capybara and Minitest in Rails

是否可以使用 Minitest 和 Capybara 来测试 Rails 中的多步表单?我在网上和 Whosebug 中阅读的所有示例都使用 Rspec。例如,.

看起来这应该是 Minitest 中可以做的事情。我正在尝试测试使用 Cocoon gem 的嵌套表单,如下所示:

点击"New Option"按钮前:

点击"New Option"按钮后:

但是,我的测试在这一步一直失败:

click_link 'New Option'

如果我在 click_link 'New Option' 之后添加 'save_and_open_page',浏览器会显示应该由 click_link 'New Option' 显示的字段。不过,当我在我的开发服务器上手动测试它时,它会起作用。这个 New Option 按钮是由 Cocoon 生成的:

<%= link_to_add_association 'New Option', f, :options %>

所以这让我相信它在下一步找不到该字段,因为 javacript 在 Capybara 和 Minitest 中不起作用。但我不确定。

我的 test_helper.rb 文件中有 Capybara.javascript_driver = :webkit,所以 javascript 驱动程序应该可以正常工作

这是 Minitest 的问题吗?或者我在测试中做错了什么?如果我在 save_and_open_page 生成的页面上查看源代码,我可以看到 New Option link 标记中的隐藏字段。这是它的样子:

基于this question,看来我需要做这样的事情:

click_link "New Option" 首先("input[name='product[options_attributes][new_options][name]']")。设置("New Option Name")

但这给了我错误:

Capybara::ExpectationNotMet: expected to find css "input[name='product[options_attributes][new_options][name]']" at least 1 time but there were no matches

Minitest 和 Capybara 测试 Javascript 似乎有问题,因为它似乎在 "New Option" link 时失败了,之后就没有了。我不知道这是与 Minitest 和 Capybara 相关的 Javascript 问题,还是我没有在 Minitest 中正确访问该字段。

感谢 Thomas Walpole for pointing out that capybara-webkit was the problem. Along with some help from this article,这是我需要更改测试通过的内容:

将这些添加到我的 Gemfile:

group :test do
  gem 'selenium-webdriver'
  gem 'webdrivers'
end

将此添加到我的 test_helper.rb:

class ActionDispatch::IntegrationTest
  Capybara.register_driver :selenium do |app|
    Capybara::Selenium::Driver.new(app, browser: :chrome)
  end

  Capybara.javascript_driver = :chrome

  Capybara.configure do |config|
    config.default_max_wait_time = 10 # seconds
    config.default_driver        = :selenium
  end
end

然后是我的测试:

test 'Account owners can add a new product as well as options and choices' do
  visit new_product_path(as: @account_owner)
  assert_title 'Add New Product'
  assert_selector 'h1', text: 'Add New Product'
  fill_in 'product_name', :with => @new_product.name
  # Users can add product options through the nested form
  click_link 'New Option'
  within('.product_options_name') do
    first('input.form-control').set("#{@t_shirt_colors.name}")
  end
  click_link 'Add Choice'
  within('.product-option-choice') do
    first('input.form-control').set("#{@red_color_choice.name}")
  end
  click_button 'Create Product'
  assert_selector '.alert', text: 'Product was successfully created.'
end