ActionCable、Capybara Webkit 和 Capybara Session 的计时问题#window

Timing issue with ActionCable, Capybara Webkit, and Capybara Session#window

我有一个 Rails 5 应用程序,它使用 ActionCable 来注册 'guest' 外观。当您访问该站点时,系统会提示您输入姓名。输入后,您的外观会广播给所有订阅者。当您退出 window 或 'disappear' 时,系统会显示您已离开。效果很好;我遇到的问题是测试失踪 - 它只通过了大约一半的时间。

相关测试如下:

RSpec.feature "Appearances", type: :feature, js: true do
  let(:picard) { 'Picard' }
  let(:riker) { 'Riker' }

scenario "A guest disappears" do
  create_guest picard
  new_window = within_new_incognito_window do
    visit '/'
    expect(page).to have_content picard
    create_guest riker
  end  
  new_window.close
  expect(page).to_not have_content riker
end

还有帮手:

module GuestHelpers
  def within_new_incognito_window
    new_window = open_new_window
    within_window new_window do
      Capybara.current_session.driver.clear_cookies
      yield
    end
    new_window
  end

  def create_guest(name)
    within('#new_guest') do
      fill_in('guest[name]', with: name)
    end
    click_on("Go")
    expect(page).to have_content name
  end
end

我试过将 default_max_wait_time 设置为 100,我试过在关闭 window 时插入 sleep(10),我试过放弃助手并按程序进行.我认为这是关闭 window 的时间问题 - 我是否遗漏了一些明显的东西?

我通过重构从 ActiveJob worker 中消失的广播并进入 AppearancesChannel,使测试始终如一地通过。我没有配置测试环境使用ActiveJob!

要使用 RSpec 测试需要 ActiveJobs 到 运行 的功能,我发现以下内容很有用 - 安装 rspec-activejob,在 test.rb 中设置 config.active_job.queue_adapter = :test,然后然后将以下文件放入您的 spec/support 目录

require 'rspec/active_job'

RSpec.configure do |config|
  config.include(RSpec::ActiveJob)

  # clean out the queue after each spec
  config.after(:each) do
    ActiveJob::Base.queue_adapter.enqueued_jobs = []
    ActiveJob::Base.queue_adapter.performed_jobs = []
  end

  config.around :each, perform_enqueued: true do |example|
    @old_perform_enqueued_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_jobs
    ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
    example.run
    ActiveJob::Base.queue_adapter.perform_enqueued_jobs = @old_perform_enqueued_jobs
  end

  config.around :each, peform_enququed_at: true do |example|
    @old_perform_enqueued_at_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs
    ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = true
    example.run
    ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = @old_perform_enqueued_at_jobs
  end
end

这将配置不同的元数据,您可以在每个测试中使用这些元数据来指定您是否希望创建的活动作业在测试期间执行。

scenario "does something that needs job to run", perform_enqueued: true do
   ...
end