我的规格问题没有超时。我的一些规格已达到某一点,只是悬挂。我确定其中一个规格导致它被破坏有问题,我无法弄清楚为什么当我定义超时时它们只是无限期地挂起......
# frozen-string-literal: true
require 'rspec'
require 'capybara/rspec'
require 'capybara/dsl'
require 'selenium-webdriver'
require 'site_prism'
Dir[File.dirname(__FILE__) + '/page_objects/*/*.rb'].each do |page_object|
require page_object
end
def wait_for_ajax
Timeout.timeout(Capybara.default_max_wait_time) do
loop until page.evaluate_script('jQuery.active').zero? && page.has_no_css?(".k-loading-color")
end
end
def whole_page
Capybara.current_session
end
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.default_driver = :selenium
Capybara.app_host = #REDACTED
Capybara.default_max_wait_time = 20
RSpec.configure do |config|
config.before(:each) do
config.include Capybara::DSL
end
config.after(:each) do
Capybara.reset_sessions!
end
end
答案 0 :(得分:2)
你没有提到它挂在哪个命令上,但我会猜测它在你的wait_for_ajax
方法中。如果是这样的话,那是因为你使用的是Timeout.timeout
,这是Ruby提供的最危险的方法。它的工作方式是启动第二个线程,然后在发生超时时在原始线程中引发异常。问题是原始线程中的任何地方都可能发生异常,这意味着如果timeout
调用中的块正在做任何非常重要的事情,它可能最终处于完全不可恢复的状态(网络通信等)。基本上Timeout.timeout
只能安全地使用,并且非常详细地了解它所发生的每一件小事,这意味着它永远不会被用于对第三方库的任何调用。相反,如果您需要超时,您应该只使用计时器并休眠。像
def wait_for_ajax
start = Time.now
until page.evaluate_script('jQuery.active').zero? && page.has_no_css?(".k-loading-color", wait: false) do
sleep 0.1
raise <Some Error> if (Time.now - start) > Capybara.default_max_wait_time
end
end
据说你真的不应该wait_for_ajax
使用可用的UI和正确编写的测试。
此外,通过加入capybara/rspec
,您已经为reset_sessions
设置了在每次测试后调用,并且Capybara::DSL
要包含在测试类型中,它应该被包含在 - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/rspec.rb#L9 - 所以通过添加自己的after
块,您只需在每次测试后调用reset_sessions
两次,这只是浪费时间。