Reconstruct A Cookie Jar And Read Signed Cookie In Capybara

Prem Sichanugrist
Sikachu's Blog
Published in
2 min readNov 13, 2015

--

I recently had to read a unique token that was stored as a cookie in Capybara feature spec. Since Rails 3 started to signed all the data that got stored into the cookie jar by default, it was not a straightforward process to read the cookie.

Normally, if the cookie jar is not signed, I could access the cookie via a helper method in rack_mock_session:

# Navigate to a page that will set this cookie
visit root_path
# Accessing the cookie jar
cookies = page.driver.browser.rack_mock_session.cookie_jar
# Accessing the cookie
guest_token = cookies["guest_token"]
#=> "IlpmRjkyVExUc3VqMFdyVEF2V0NGbWci--6a4cf4c3e47c509e73803000..."

However, the value returned from the cookie jar above isn’t exactly the token I was looking for. So, I tried to use cookies.signed assessor:

guest_token = cookies.signed[“guest_token”]
NoMethodError: undefined method `signed’ for #<Rack::Test::CookieJar:0x007fe90965ccd8>

Uh oh. That doesn’t look right.

It turns out that the cookie jar in the feature spec is an instance of Rack::Test::CookieJar which has no support for signed cookie. I actually need an instance of ActionDispatch::Cookies::CookieJar instead.

The easiest (and safest) way to reconstruct the correct cookie jar is to reconstruct an ActionDispatch::Request object. I then can access the correct cookie jar using cookie_jar method on that request object.

In the end, I just added this helper method to my feature spec:

def cookies
ActionDispatch::Request.new(page.driver.request.env).cookie_jar
end

Now I can access the signed cookie by calling signed on that cookie jar:

$ cookies[“guest_token”]
#=> “IlpmRjkyVExUc3VqMFdyVEF2V0NGbWci--6a4cf4c3e47c509e73803000...”
$ cookies.signed[“guest_token”]
#=> “ZfF92TLTsuj0WrTAvWCFmg”

Alternatively, I could have added a test-specific controller action that returns the value of that cookie. However, I don’t think that code belongs in the app, and this approach gave me such a cleaner code in the spec in the end.

--

--

Senior Developer at Degica. I also contribute to open source projects, mostly in Ruby.