capimbara/selenium与rspec之前:所有钩子

bre*_*ter 13 selenium capybara rspec2

为了减少使用selenium的页面访问次数,我想从一个before :all钩子调用visit方法,并在单个页面加载时运行我的所有示例.但是,当我指定before :allvs时before :each,浏览器会打开,但永远不会访问该URL.以下是一个简化的人为例子......

describe 'foobar', :js => true do
  before :all do
    Capybara.default_wait_time = 10
    obj = Factory(:obj)
    visit obj_path(obj)
  end

  it 'should have foo' do
    page.should have_content('foo')
  end

  it 'should have bar' do
    page.should have_content('bar')
  end
end
Run Code Online (Sandbox Code Playgroud)

当我设置它时before :each,它可以工作,但页面加载两次.这是Capybara的限制吗?

Gla*_*eep 3

问题原因

第二个示例不起作用,因为 Capybara 在每个 RSpec 示例之后都会重置会话;visit您在块中编辑的页面before :all此时不再打开。这是水豚的明显行为。它位于capybaragem 中,位于/lib/capybara/rspec.rb

config.after do
  if self.class.include?(Capybara::DSL)
    Capybara.reset_sessions!
    Capybara.use_default_driver
  end
end
Run Code Online (Sandbox Code Playgroud)

我在谷歌上搜索了几个小时,发现其他几个人也在努力解决这个问题,但实际上毫无效果。

我还发现了一个补丁,允许将 Capybara 配置为在提出每个示例后不重置会话......但 Capybara 创建者jnicklas 拒绝了 Pull 请求

解决方案

我发现(到目前为止)最快的(尽管可能不是最好的)可行的解决方案是对Capybara 进行猴子补丁

module Capybara                                                                                                                                                                                  
  class << self                                                                                                                                                                                  
    alias_method :old_reset_sessions!, :reset_sessions!                                                                                                                                          
    def reset_sessions!; end                                                                                                                                                                     
  end                                                                                                                                                                                            
end
Run Code Online (Sandbox Code Playgroud)

这只会使得当reset_sessions!它被调用时什么都不做。注意:谨防意外的副作用!(alias_method如果您需要再次发生默认重置行为,您可以随时在代码中恢复稍后的内容。)