18

我想继续使用同一个会话,我指的是 Rails 在Test::Unit使用 Capybara 的各种集成测试之间的会话。该Capybara::Session对象在所有测试中都是相同的,因为它被重复使用,但是当我在另一个测试中访问另一个页面时,我会立即注销。

深入研究我发现capybara_session.driver.browser.manage.all_cookies在一个测试和下一个测试之间清除了。

有什么想法吗?或者为什么?或如何避免?

为了解决这个问题,我将 cookie 保存在一个类变量中,稍后通过运行重新添加:

capybara_session.driver.browser.manage.add_cookie(@@cookie)

它似乎工作,cookie在那里,但是当有一个请求时,cookie被另一个替换,所以它没有效果。

有没有其他方法可以实现这一目标?

4

4 回答 4

18

在与页面交互的水豚代码之后添加以下内容:

Capybara.current_session.instance_variable_set(:@touched, false)

or

page.instance_variable_set(:@touched, false)

如果这不起作用,这些可能会有所帮助:

https://github.com/railsware/rack_session_access

http://collectiveidea.com/blog/archives/2012/01/05/capybara-cucumber-and-how-the-cookie-crumbles/

于 2012-09-30T05:29:45.347 回答
5

如果您正在尝试将单个示例串联成一个故事(黄瓜风格,但没有黄瓜),您可以使用名为 rspec-steps 的 gem 来完成此操作。例如,通常这不起作用:

describe "logging in" do
  it "when I visit the sign-in page" do 
    visit "/login"
  end
  it "and I fill in my registration info and click submit" do
    fill_in :username, :with => 'Foo'
    fill_in :password, :with => 'foobar'
    click_on "Submit"
  end
  it "should show a successful login" do
    page.should have_content("Successfully logged in")
  end
end

因为 rspec 回滚了它的所有实例变量、会话、cookie 等。

如果您安装 rspec-steps(注意:当前与 2.9 之后的 rspec 不兼容),您可以将 'describe' 替换为 'steps' 并且 Rspec 和 capybara 将保留示例之间的状态,允许您构建更长的故事,例如:

steps "logging in" do
  it "when I visit the sign-in page" #... etc.
  it "and I fill in" # ... etc.
  it "should show a successful" # ... etc.
end
于 2013-01-17T20:47:17.330 回答
3

@browser.manage.delete_all_cookies您可以通过猴子修补方法来防止在测试之间发生调用Capybara::Selenium::Driver#reset!。这不是一种干净的方式,但它应该可以工作......

将以下代码添加到您的项目中,以便在您之后require 'capybara'执行它:

class Capybara::Selenium::Driver < Capybara::Driver::Base
  def reset!
    # Use instance variable directly so we avoid starting the browser just to reset the session
    if @browser
      begin
        #@browser.manage.delete_all_cookies <= cookie deletion is commented out!
      rescue Selenium::WebDriver::Error::UnhandledError => e
        # delete_all_cookies fails when we've previously gone
        # to about:blank, so we rescue this error and do nothing
        # instead.
      end
      @browser.navigate.to('about:blank')
    end
  end
end

出于兴趣,可以在 Capybara 的代码库中看到违规行:https ://github.com/jnicklas/capybara/blob/master/lib/capybara/selenium/driver.rb#L71

于 2012-10-02T17:35:53.377 回答
0

It may be worth posting the reason why you need this kind of behaviour. Usually, having the need to monkey patch Capybara, is an indication that you are attempting to use it for something it was not intended for. It is often possible to restructure the tests, so that you don't need the cookies persisted across integration tests.

于 2012-12-15T11:20:05.710 回答