Rails、Cucumber、Capybara:会话不持久

Posted

技术标签:

【中文标题】Rails、Cucumber、Capybara:会话不持久【英文标题】:Rails, Cucumber, Capybara: session is not persisted 【发布时间】:2011-07-05 21:48:20 【问题描述】:

我正在尝试为依赖于某些会话存储数据的功能编写测试,我的场景如下所示:

Scenario: Create offer
  Given I am on the start offer page
  When I select "Foo" from "bar"
  And I press "Go on"
  Then I should see "You are going to offer foo"

通过使用调试器,我发现信息正确地存储在会话中,但在每个新请求上我都会获得一个新会话。

至少每个场景都应该有一个工作会议吗?任何想法为什么不是这种情况?

提前致谢, 乔

版本:在 rails 2.3.10、cucumber 0.10.0、cucumber-rails 0.3.2、capybara 0.4.1.2 上运行

【问题讨论】:

你用的是什么驱动,有没有修改过Capybara的设置? 你能发布这个场景的相关步骤实现吗? 回答您的第一个问题:是的,场景中应该有持久的会话状态。 (它应该与默认的 Rack::Test 驱动程序和 Selenium 一起使用。)为什么它可能不适合你,我不知道。 @Joe 你有没有想过,乔?谢谢。 @webren 我为我的测试做了一些解决方法,但 nickgrim 指向的东西看起来非常相似:blog.ardes.com/2010/4/28/… 【参考方案1】:

由于水豚在测试中期切换主机名,我们遇到了丢失会话的问题。场景类似于以下内容:

# Good
When I visit some page
# will call 'http://capybarawhatever/some_page
And I click the the button
# will call 'http://capybarawhatever/some_new_page'
Then I still have the session

# Failing
When I visit some page
# will call 'http://capybarawhatever/some_page'
And I do something that redirects me to "http://newhost.org/new_page"
And I visit some page
# No this may go to 'http://newhost.org/some_page
Then I have lost my session

这可能值得研究。您可以在会话中获取current_url,并且可以使用host! 'newhost.org' 为水豚设置新主机

【讨论】:

我会朝这个方向进行调查。该步骤中涉及到上下文的切换,虽然会话信息只是在上下文切换后存储和使用。 我看来水豚会话也可能是sensitive to relative URLS。【参考方案2】:

某些驱动程序没有明确的设置 cookie 的方法。在整理它们之前,这是一个 hacky 解决方法:

  def set_cookie(name, value, domain)
    driver = Capybara.current_session.driver rescue nil

    return unless driver

    case driver
    when Capybara::Driver::RackTest
      driver.set_cookie "#name=#value"
    when Capybara::Driver::Selenium
      visit '/' # must visit the domain before we can set the cookie

      br = driver.browser.send(:bridge)

      br.addCookie(
        'name'    => name,
        'domain'  => domain,
        'value'   => value,
        'path'    => '/',
        'expires' => (Time.now + 100.years).to_i
      )
    else
      raise "Unsupported driver #driver"
    end
  end

【讨论】:

所以没有人会感到困惑:驱动程序确实会处理来自应用程序的 cookie —— 在我看来,您的回答是关于手动设置 cookie。 (虽然我不确定这是否解决了 OP 的问题。) 你是对的,是的,如果你想强制登录,这很有用,例如,如果正常登录过程将由可能需要时间/需要互联网的 openid/oauth 方法驱动连接。 只是想补充一点,你的案例陈述应该是case driver.class,否则你会看到一个巨大的散列 这适用于旧版本的 Cucumber/Capybara,我必须使用 page.driver.set_cookie() 才能工作。谢谢!【参考方案3】:

可能是this bug?

【讨论】:

@Ankur 博客文章中的要点感觉像是对 OP 的“任何想法为什么不是这种情况?”的合理回答,所以我不确定你为什么认为这不是一个答案(尽管仅链接点是有效的;在我的辩护中,我在 2.5 年前写了这个)。 这对我很有用,因为我的问题是 Capybara 在更改域时清除会话,即使我从 /some/url 导航到 localhost:8080/some/other

以上是关于Rails、Cucumber、Capybara:会话不持久的主要内容,如果未能解决你的问题,请参考以下文章

Rails + Cucumber/Capybara:如何在测试中设置/检索 cookie?

Rails 3.0.9 + Devise + Cucumber + Capybara 臭名昭著的“没有路线匹配 /users/sign_out”

Rails Cucumber使用Capybara测试AJAX

使用 Cucumber 和 Capybara-Webkit 在 Rails 4 上进行 typeahead.js 测试失败

如何使用rails cucumber,rspec,capybara在视图(dhtml)中测试动态部分?

Rails:Capybara执行js以节省浏览器本地存储的价值