What can cause Capybara::Poltergeist::TimeoutError: in group testing that doesn't individually?

What can cause Capybara::Poltergeist::TimeoutError: in group testing that doesn't individually?

一个 Rails 应用程序,它使用远程测试在 Vag运行t Ubuntu VM 上测试 CakePHP 应用程序 运行ning。 我的 OS 是 macOS High Sierra。

'rspec/rails'
'capybara/rails'
'capybara/mechanize'
'capybara/poltergeist'
'phantomjs'

如果我运行rspec ./spec/features/my_tests_folder/, 文件夹中的前 2 个测试总是通过,其余总是以 Capybara::Poltergeist::TimeoutError:.

结尾

如果我单独 运行 那个文件夹中的任何测试,它们总是全部通过。

共有7个测试文件。他们每个人都有 1 个功能和 1 个场景。都是js: true.

我尝试在 Capybara.register_driver 中增加 :timeout 并在 Capybara.configure 中增加 default_max_wait_time。两者都没有改变结果。

我也在每次测试前后玩过 Capybara.reset!。好像也没关系。

当我用 config.order = :random 运行 时,有时 7 个中有 5 个有错误,有时 7 个中只有 2 个有错误。但是,总是有一些错误和一些通过。此外,每个测试至少在错误组中出现一次。

我运行没主意了。什么会导致这样的事情?

更新(包括 Capybara 和 Poltergeist 配置以及失败测试示例):

rails_helper.rb 中的配置:

Capybara.register_driver :poltergeist do |app|
  options = {
    :timeout => 90, # default is 30
    :js_errors => false,
    :phantomjs => Phantomjs.path,
    # :debug => true
  }
  Capybara::Poltergeist::Driver.new(app, options)
end

Capybara.register_driver :mechanize do |app|
  driver = Capybara::Mechanize::Driver.new(app)
  driver.configure do |agent|
    agent.user_agent_alias = 'Mac Safari'
  end

  driver
end

Capybara.configure do |config|
  config.run_server = false
  config.app_host = "http://my_vm_domain.com"
  config.javascript_driver = :poltergeist
  config.default_driver = :mechanize
  config.default_max_wait_time = 10 # default is 2
end

测试失败示例(不是失败,而是得到Capybara::Poltergeist::TimeoutError:):

require 'rails_helper'

feature 'agente visualiza estoques de um passeio', js: true do

  scenario 'com sucesso' do

    agente_log_in

    visit '/roteiro/show/723'

    find(:partial_href, 'new_passeio/723').click

    select 'Passeio Teste', from: 'passeio_produto'
    fill_in 'passeio_data', with: '11/11/2017'

    within('button#estoque_controls_0') do

      within('div#estoque_0_hora') do
        expect(page).to have_content('07:30')
      end

      within('span#estoque_0_vagas') do
        expect(page).to have_content('3')
      end

    end

    within('button#estoque_controls_1') do

      within('div#estoque_1_hora') do
        expect(page).to have_content('10:00')
      end

      within('span#estoque_1_vagas') do
        expect(page).to have_content('5')
      end

    end

  end

end

支持文件夹中 agente_log_in.rb 的代码:

def agente_log_in

  Capybara.app_host = "http://my_vm_domain.com"

  visit '/usuario/logout'
  visit '/'

  fill_in 'data[AdmUsuario][usuario]', with: 'agente'
  fill_in 'data[AdmUsuario][senha]', with: 'pa$$w0rd'

  click_on 'Entrar'

end

:partial_href 的代码找到:

module Selectors

  Capybara.add_selector(:partial_href) do
    xpath {|href| XPath.descendant[XPath.attr(:href).contains(href)] }
  end

end

应用程序其他文件夹中的其他测试一切正常。如果我单独 运行 此文件夹中的测试,它们也很好。这个问题似乎只发生在我 运行 这个特定文件夹作为一个整体时。

在包含 Thomas Walpole 要求的额外信息后,我继续搜索和研究各种可能性。

我终于遇到了 poltergeist's issue #781 on GitHub, which describes a situation very similar to mine, and eventually presents a wait_for_ajax solution

在我的项目中实施之前,我阅读了有关等待 Ajax 的更多信息,发现 this post 也很有帮助。

最后,我从GitHub中选择了jasonfb的代码,因为它看起来更全面,信息量更大。

效果非常好!我的测试现在一直通过。我什至能够删除 :timeoutdefault_max_wait_time.

的自定义

有问题的 CakePHP 应用程序非常依赖 js,并且此文件夹测试的特定部分特别充满 Ajax 请求。