首页 > 解决方案 > 什么会导致 Capybara::Poltergeist::TimeoutError: 在不单独进行的组测试中?

问题描述

一个 Rails 应用程序,它使用远程测试来测试在 Vagrant Ubuntu VM 上运行的 CakePHP 应用程序。我的操作系统是 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

我试过:timeout增加Capybara.register_driverdefault_max_wait_time增加Capybara.configure。两者都没有改变结果。

我也在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

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

标签: ruby-on-railsphantomjscapybaramechanizepoltergeist

解决方案


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

我最终在 GitHub 上遇到了poltergeist 的 issue #781 ,它描述了一个与我非常相似的情况,并最终提出了一个wait_for_ajax解决方案

在我的项目中实现它之前,我阅读了更多关于等待 Ajax 的内容,发现这篇文章也很有帮助。

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

它就像一个魅力!我的测试现在一直通过。我什至能够删除:timeout和的自定义default_max_wait_time

有问题的 CakePHP 应用程序的 js 非常重,而且这个文件夹测试的特定部分特别充满了 Ajax 请求。


推荐阅读