【问题标题】:Why is Capybara discarding my session after one event?为什么 Capybara 在一个事件后放弃我的会话?
【发布时间】:2013-09-08 12:57:59
【问题描述】:

为大多数控制器测试具有before_filter :authenticate_user! 的 Rails 应用程序,我无法让 Capybara 保留会话。

我使用 PhantomJS 和 poltergeist 配置了 Capybara。

我使用以下助手:

require 'spec_helper'
include Warden::Test::Helpers

module FeatureHelpers
  def login(user = FactoryGirl.create(:default_user))
    login_as user, scope: :user
    user
  end
end

我有以下规格文件:

require 'spec_helper'
include Warden::Test::Helpers

feature 'Leads Data Tasks View' do
  before(:each) do
    @user = login
  end

  after{ Warden.test_reset! }

  context "clicking a task button" do
    scenario "login persists across multuple actions", js: true do
      visit '/tasks'

      page.should have_selector('#parse', count: 1)
    end
  end
end

当我运行这里显示的测试时,它会通过。但是,如果我在执行 AJAX 操作的东西上调用 click_link,或者如果我只是尝试执行 visit '/tasks' 两次,should 断言将失败,因为我将被重定向到应用程序的登录页面。

我尝试了几种不同的方法,包括设置Capybara::Session,但我仍然在 AJAX 请求中收到 401 代码,并且每个规范只能成功访问一次。

我做错了什么?

【问题讨论】:

  • 根据您使用的语法,我猜这是设计。您是否触发了许多 ajax 调用?在处理 ajax 调用时,Devise 有一些奇怪的行为。请参阅stackoverflow.com/questions/11845500/… 了解更多信息
  • 感谢您向我指出这个问题。为了回答您的问题,我经常触发许多 AJAX 调用,但是即使我不触发任何调用,这个问题似乎也正在发生。如果我复制 visit 调用,以便它只加载页面两次,则不会在两者之间发生 AJAX。
  • 此外,为了测试,我决定尝试从您的链接问题中接受的答案中选择 2,并在我的应用程序控制器中暂时注释掉 protect_from_forgery。这些都没有改变结果。除了第一个请求,我仍然得到 401。
  • 如果正常运行,是否有效。即使用它的用户?
  • 不确定这是否会有所帮助,但请尝试强制 phantom js 使用相同的数据库连接。看看这个 railscasts:railscasts.com/episodes/391-testing-javascript-with-phantomjs 并尝试spec/support/shared_db_connection.rb中的代码

标签: ruby-on-rails rspec capybara phantomjs poltergeist


【解决方案1】:

所以问题在于 phantomjs 驱动程序 (poltergeist) 正在使用单独的数据库连接。我之前遇到过完全相同的问题,我从railscast episode 391 得到了解决方案,代码在spec/support/shared_db_connection.rb

由于我找不到他的代码的许可证,所以我将链接到code here

【讨论】:

  • 我怀疑你使用 DatabaseCleaner gem,你应该告诉它使用 :truncation 策略明确地进行水豚测试。还有self.use_transactional_fixtures = false。这样你就不需要共享连接了。
  • @Fedcomp 请记住 :truncation 很可能会非常慢,因为实际的数据库写入和随后的删除将会发生。共享连接允许在事务中运行规范,这要快得多。尝试使共享连接工作,这绝对值得。另请参阅 EvilMartian 的 TestProf gem,它提供了共享连接反向端口。
  • 这不是随机的答案,而是我的经验。 Capybara 运行额外的线程,这就是为什么你不能让它共享连接,这就是为什么你使用截断来共享与事务不同的所有内容。如果您知道如何通过启动另一个线程并共享连接来击败水豚 - 请告诉我。在那之前,这可能是唯一的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
  • 2012-02-12
  • 2018-01-06
  • 2017-01-22
  • 1970-01-01
相关资源
最近更新 更多