我有一个包含一些AJAX代码的页面,我正在尝试构建使用Capybara的规范。此测试有效:
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
单击链接'run_now'后,将启动一个作业,并将用户重定向到launched_jobs_path
,其中有一个Datatable,它使用一些AJAX来提取当前正在运行的作业。这个测试通过。但是,我想添加测试以检查以确保在单击“run_now”按钮之前作业尚未运行(这会给我一个误报)。我开始玩它,但后来我注意到,即使只是在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"
我很确定这是Javascript没有在正确的时间运行的问题,但我不太清楚如何解决它。有任何想法吗?这是带有Capybara 2.4和Capybara-webkit 1.3的Rails 4.1。
谢谢!
更新
在规范的父上下文中,我确实有: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
答案 0 :(得分:0)
我认为它可能像添加一样简单:js =>对于您的方案标题是true,以便它知道启动webkit / selenium来测试js / ajax。
scenario 'clicks the Run now link', :js => true do
希望有所帮助!
<强>更新强>
这是另一个想法。您可以尝试将其添加到'rails_helper'或'spec_helper'文件中以设置:js驱动程序。
Capybara.javascript_driver = :webkit
你有其他:js测试正常使用:webkit?您是否尝试过使用save_and_open_page来查看您要查找的元素是否实际位于页面上而Capybara是否找不到它?
答案 1 :(得分:0)
好的,我很确定我现在有一些至少可以工作的东西。如果有人有更优雅的解决方案,我很乐意听到它们。
我认为问题在于&#39; run_now&#39;控制器。它为Rufus调度程序进程添加了一个作业,然后必须启动该作业(应该立即启动)。只有在通过Rufus运行启动的作业后,才会创建launch_jobs表中的条目。
在开发过程中,我会在点击“立即运行”后立即启动该作业。但是,我猜测WebKit是如此之快,以至于当它到达launch_jobs #index页面时,该作业还没有被启动。额外的visit current_path
一开始似乎有帮助,因为它会刷新页面,但它只是偶尔起作用。在同步块中包含最后两个步骤似乎可靠地工作(我现在已经运行了大约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