简体   繁体   English

Rails水豚访问不相关的页面导致测试失败

[英]Rails capybara visiting unrelated page causes test to fail

I've got got a page with some AJAX code that I'm trying to build a spec for using Capybara. 我有一个页面,其中包含一些AJAX代码,我正在尝试为使用Capybara建立规范。 This test works: 此测试有效:

context 'from the JobSpec#index page' do
  scenario 'clicks the Run now link' do
    visit job_specs_path
    within( find('tr', text: @job_spec.name) ) { click_link 'run_now' }
    visit current_path
    expect(find('tr', text: @job_spec.name)).to have_content(/(running|success)/)
  end
end

After clicking the link 'run_now', a job is launched and the user is redirected to the launched_jobs_path , which has a Datatable that uses some AJAX to pull currently running jobs. 点击链接“run_now”后,作业启动,用户被重定向到launched_jobs_path ,它具有使用一些AJAX来拉动当前运行的作业的DataTable。 This test passes. 该测试通过。 However, I wanted to add to the test to check to make sure that the job wasn't already running before clicking the 'run_now' button (which would give me a false positive). 但是,我想添加到测试中以确保在单击“ run_now”按钮之前该作业尚未运行(这将给我带来误报)。 I started playing around with it, but then I noticed that even simply putting visit launched_jobs_path before visit job_specs_path would cause the test to fail with the error 我开始玩弄它,但后来我发现,即使简单地将visit launched_jobs_path之前visit job_specs_path会导致测试失败与错误

Failure/Error: expect(find('tr', text: @job_spec.name)).to have_content(/(running|success)/)
 Capybara::ElementNotFound:
   Unable to find css "tr" with text "job_spec_collection-1"

I'm fairly certain that this is an issue with the Javascript not running at the right time, but I don't quite know how to resolve it. 我相当确定这是Javascript无法在正确的时间运行的问题,但是我不太了解如何解决它。 Any ideas? 有任何想法吗? This is Rails 4.1 with Capybara 2.4, and Capybara-webkit 1.3. 这是带有Capybara 2.4和Capybara-webkit 1.3的Rails 4.1。

Thanks! 谢谢!

Update 更新资料

In the parent context of the spec, I do have :js => true 在规范的父上下文中,我确实有:js => true

feature 'User runs a JobSpec now', :js => true do
  before do
    Capybara.current_driver = :webkit
    @job_spec = FactoryGirl.create(:job_spec, :with_client_spaces)
  end

  after { Capybara.use_default_driver }

  context 'from the JobSpec#index page' do
    ...
  end
end

I think it might be as simple as adding :js => true to your scenario header so that it knows to launch webkit / selenium to test the js / ajax. 我认为这可能与在场景标题中添加:js => true一样简单,以便它知道启动webkit / selenium以测试js / ajax。

scenario 'clicks the Run now link', :js => true do

Hope that helps! 希望有帮助!

UPDATE 更新

Well here's one more idea. 好吧,这里还有一个主意。 You could try adding this to your 'rails_helper' or 'spec_helper' file to set the :js driver. 您可以尝试将其添加到“ rails_helper”或“ spec_helper”文件中以设置:js驱动程序。

Capybara.javascript_driver = :webkit

Do you have other :js tests that are working properly with :webkit? 您是否有其他:js测试可以与:webkit一起正常使用? Have you tried using save_and_open_page to see if the element you are looking for is actually on the page and Capybara just isn't finding it? 您是否尝试过使用save_and_open_page来查看要查找的元素是否确实在页面上,而Capybara却找不到它?

Ok, pretty sure I've got something that will at least work for now. 好的,可以肯定的是,我现在至少可以使用某些功能。 If anyone has more elegant solutions I'd love to hear them. 如果有人有更优雅的解决方案,我很想听听他们。

I think the issue is in the complexity of what happens in the 'run_now' controller. 我认为问题在于'run_now'控制器中发生的事情的复杂性。 It adds a job to a Rufus scheduler process, which then has to start the job (supposed to start immediately). 它将作业添加到Rufus调度程序进程中,然后必须启动该作业(假定立即启动)。 Only after the launched job is running via Rufus does an entry in the launched_jobs table get created. 只有通过Rufus运行启动的作业后,才会在launch_jobs表中创建一个条目。

While developing, I would see the job just launched as soon as I clicked 'Run now'. 在开发过程中,只要单击“立即运行”,我就会看到工作刚刚启动。 However, I'm guessing that WebKit is so fast that the job hasn't been launched by the time it gets to the launched_jobs#index page. 但是,我猜想WebKit是如此之快,以至于该作业在进入launchd_jobs#index页面时尚未启动。 The extra visit current_path there seem to help at first because it would refresh the page, but it only worked occasionally. 最初,那里的额外visit current_path似乎会有所帮助,因为它将刷新页面,但仅偶尔起作用。 Wrapping these last two steps in a synchronize block seems to work reliably (I've run it about 20 times now without any failures): 在同步块中包装这最后两个步骤似乎可以可靠地工作(我已经运行了大约20次,没有任何失败):

context 'from the JobSpec#index page' do
  scenario 'clicks the Run now link' do

    # First make sure that the job isn't already running
    visit launched_jobs_path
    expect(page).to have_no_selector('tr', text: @job_spec.name)

    # Now launch the job
    visit job_specs_path
    within( find('tr', text: @job_spec.name) ) { click_link 'run_now' }
    page.document.synchronize do
      visit current_path
      expect(find('tr', text: @job_spec.name)).to have_content(/(running|success)/)
    end

  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM