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

时间:2012-03-09 07:01:24

标签: selenium capybara rspec2

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

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

当我将其设置为before :each时,它可以正常工作,但页面会加载两次。这是Capybara的限制吗?

1 个答案:

答案 0 :(得分:3)

问题原因

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

config.after do
  if self.class.include?(Capybara::DSL)
    Capybara.reset_sessions!
    Capybara.use_default_driver
  end
end

我用Google搜索了几个小时,发现其他几个人正在努力解决这个问题,但确实无济于事。

我还发现patch允许Capybara配置而不是以在每个示例提出后重置会话...但是Capybara创建者 jnicklas declined the pull request

解决方案

我发现(迄今为止)最快的 - 虽然可能不是最好的 - 可行的解决方案是monkey-patch Capybara:

module Capybara                                                                                                                                                                                  
  class << self                                                                                                                                                                                  
    alias_method :old_reset_sessions!, :reset_sessions!                                                                                                                                          
    def reset_sessions!; end                                                                                                                                                                     
  end                                                                                                                                                                                            
end

这只会让reset_sessions!在调用时不执行任何操作。注意:注意意外的副作用! (如果您需要再次发生默认重置行为,您可以随后在代码中恢复alias_method。)