Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

API for cookie manipulation? #327

Closed
agibralter opened this Issue · 25 comments
@agibralter

Would it make sense/be possible to support an API for cookie manipulation?

get_cookie(name)
#=> return String with cookie that is set in user's browser session

set_cookie(name, value)
#=> set a cookie manually in the user's browser session

delete_cookie(name)

I don't know if it would work for all drivers... but it would certainly work for Rack, Selenium, and Webkit.

@dmarkow

I would like to see this too. I used to be able to use this to get the cookies:

Capybara.current_session.driver.current_session.instance_variable_get(:@rack_mock_session).cookie_jar

But that seems to be broken in 1.0.0.beta1?

Edit: Got it working by using Capybara.current_session.driver.browser.current_session instead of Capybara.current_session.driver.current_session. But it would still be nice to have an easier way to access these.

@agibralter

And one that is standard across drivers...

@nruth

https://github.com/nruth/show_me_the_cookies is an attempt at this, but driver support varies.

@nruth

dmarkow thanks for the pointer re: racktest cookie jar, saved me half an hour or so. I've updated the gem/project mentioned to work with edge capy but had some strange behaviour from selenium to investigate. Contributions welcome if anyone thinks a gem is a good fit for this.

I think it'd be better in core but on the mailing list there was little/no response to a post about it. Maybe a pull request would get more attention?

@joliss
Collaborator

I think both pull requests or list posts are good ways to Jonas's attention. Just don't be surprised if he takes a few days to get back -- he seems to work in spurts. ;-)

Pull requests are good for working code that's ready to be merged. (And, this being open source, a pull request is generally a lot more effective than writing a feature request and waiting for someone else to implement it.)

On the other hand, to start a discussion, the mailing list is the better place -- you can paste a diff (or link to GitHub) to discuss specific work-in-progress or proof-of-concept code.

@jnicklas
Owner

Really delayed comment on this: I don't think we'll do this for 1.0 but maybe for 1.1 it would be okay. I'm a bit worried though, because it goes a little bit against the user centric nature of Capybara. I guess it would be convenient for some use cases though, could someone write up an example where this feature would be useful?

@nruth

My use case was testing "Remember me" functionality provided by Devise.
I wanted a stepdef for the user quitting their browser (clearing the session cookie).
Other than that it's just debugging info really.
There's an example for rspec/cucumber in the linked repo's readme.

@agibralter
@mcrmfc

Have added a 'query only' possible api as a pull request, see pull #357. May be many good reasons why this is not a good approach so feel free to comment negatively...no hard feelings!

@mperham

This is hugely useful for testing affiliate cookie functionality:

  • User comes to site with a referral parameter
  • Server drops cookie into browser
  • User visits registration page and signs up.
  • Cookie is promoted into the database with the new user record.

This is an integration spec and right where Capybara is most useful.

@subelsky

+1 for this, I'm using it in a similar scenario to Mike and have to hack quite a bit to get it working

@jeshuaborges

+1 Ive been hacking around these issues as well.

@geoffroymontel

Thanks for the get_cookie gist, but did anyone manage to do the set_cookie ?

@nruth
@geoffroymontel

mmm, too bad.
The problem is that the login process takes something like 1 minute in my application, and it's so loooong to repeat it at each scenario... And I can't mock up this part on server side.
I will try to find the right api for the chromium driver!
best

@dobbs

I tried using this in a spec (the driver in this case is :rack_test):

it "renders the form when credentials are found" do
  page.driver.browser.set_cookie 'username=jhendrix'
  get new_service_request_path
  response.status.should == 200
end

But after much debugging discovered that the set_cookie call runs against a different Rack::MockSession and therefore in a different CookieJar than the call to get. What works right now is this:

it "renders the form when credentials are found" do
  get new_service_request_path, {}, 'HTTP_COOKIE' => 'username=jhendrix'
  response.status.should == 200
end

Although an API might be slightly more readable, I think it might be better to just widely document that this second form is the way to test cookies.

Details about my adventure debugging this one can be found here:
http://dobbse.net/thinair/2011/12/capybara-racktest-rspec-cookies-2of2.html

@blindninja

+1 I have several Rails apps that shares a single sign on solution using cookies. Since the authentication function is tested elsewhere, I don't need to test it again in my app. I just need to set the cookie with the token that I need to log in and and go right into my app. Right now I have to write a little fake login screen just so I can get RSpec/Capabara requests tests to work.

I tried:

get new_service_request_path, {}, 'HTTP_COOKIE' => 'username=jhendrix'

But it's using get instead of visit so I can't do things like:

page.should have_content "My stuff"

Having the ability to view and setting the cookies would be a great option. I checked out show_me_the_cookies gem but it doesn't have a way to set it.

@betelgeuse

@lsj256go You should be able to adapt this piece of code I use to make login faster in tests to your problem:

class ApplicationController
  prepend_before_filter :quick_login_in_tests

private
  def quick_login_in_tests
    if user_id = params[:login_user_in_tests]
      sign_in User.find(user_id)
    end
  end
end

I have this in features/support/quick_login.rb here I sign the user in to an app using Devise but you should be able to set a cookie just as well.

@cayblood

Here's another use case. We're writing cucumber integration tests for a PHP-based web app. We want to get code coverage reports for our cucumber/capybara tests. To do this, our code coverage tool needs us to set a header or cookie with a session ID that will stay the same over multiple requests. If we put this in a header, we might miss coverage for some ajax calls, but if we put it in a cookie it will work even for ajax calls.

@blindninja

@betelgeuse Thanks for the tip. I actually did something similar, except that I set up a specific session controller and enabled only for test. That way no one can just put in a parameter and get access to your system in production.

For example, if I visit http://myapp.com/login/username, the system will login as that user. But it only works when RAILS_ENV=test.

@ahawkins

+1 We need a standard cookie api.

@dentarg

+1

@jnicklas
Owner

Let's see some pull requests if people want this ;) Though I suspect that changes need to happen in RackTest if Capybara wants to implement this in a non-silly way.

@jnicklas
Owner

No pull requests yet. I'm closing this issue. I don't need it. I'm not going to fix it. Though if someone can provide a decent pull request I'd be happy to merge it.

@jnicklas jnicklas closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.