watir-webdriver cookie jar saving and loading
Asked Answered
E

2

6

I'm surprised there didn't seem to be much discussion on this.

in Mechanize I can easily read an entire cookie jar from the browser, store it to a file, and load it in to a later session/run before loading that website's pages again.

How can one do the same with watir-webdriver?

UPDATE

Now with 0.5.2 I do see new methods browser.cookies.to_hash which would turn this question into "How to implement .from_hash or similar loader using eg. .clear and .add?"

However I'd be especially keen on loading and saving all cookies using previous versions (0.4.1) which my servers are likely to be stuck with for a while. Via the Selenium driver maybe?

Eyepiece answered 11/2, 2012 at 10:19 Comment(0)
R
8
browser = Watir::Browser.new :firefox
browser.goto 'http://google.com'
# save cookies
saved_cookies = browser.cookies.to_a
# clear and get new cookies
browser.cookies.clear
browser.goto 'http://google.com'
# set new cookies
browser.cookies.clear
saved_cookies.each do |saved_cookie|
  browser.cookies.add(saved_cookie[:name], saved_cookie[:value])
end
Rocca answered 11/2, 2012 at 11:34 Comment(1)
Almost. Thanks! Saving & reloading array from plaintext file become somewhat problematic, so I used YAML. Posting full solution belowEyepiece
E
4

Applying pOdeje's loop to repopulate the cookie jar, here's a solution that includes storing the cookies into a file, readable in a later Ruby run. A straight File.open write and read of the array had some issues I didn't wish to work around (parsing?), but YAML object serialization already bundled in Ruby was well suited to the task.

require 'yaml'

# Save/serialize cookies 
# File.open("ST.cookies.txt", 'w').write $browser.cookies.to_a.to_s 
File.open("ST.cookies.yaml", 'w').write YAML::dump($browser.cookies.to_a)


# Load/deserialize cookies
# $cookies = File.open("ST.cookies.txt", 'r').to_a # returns 1-elem array of single long line, not indiv elements
$cookies = YAML::load(File.open("ST.cookies.yaml", 'r'))
$browser.cookies.clear
$cookies.each do |saved_cookie|
  $browser.cookies.add saved_cookie[:name], 
      saved_cookie[:value],
      :domain => saved_cookie[:domain], 
      :expires => saved_cookie[:expires], 
      :path => saved_cookie[:path], 
      :secure => saved_cookie[:secure]
    end

Still on the lookout for a pre watir-webdriver 0.5.x method, though.

CAVEAT

Not thoroughly tested yet but it seems I have to first load the URL to which the cookies apply, then load in my cookie jar using the above method, and finally load that URL into $browser object a second time. This is only a minor inconvenience and time cost for my case in which I'm staying within the same domain throughout my web session, but I can see this turning into a real thorn for cookie jars affecting several unrelated sites (as had indeed been an expectation for my old programs using other languages & libraries like Mechanize). Curl and Wget and generally other tools I've used for SOAP interfacing always let me control my POST/session/cookie environments prior to site loading. Just a thought.

Eyepiece answered 13/2, 2012 at 0:10 Comment(4)
Amended to include cookie's :domain :expires :path and :secure as well...possibly the reason my jar seemed ignored and I still had to create a whole new session every time!Eyepiece
good stuff. does make me wonder how many folks would need or make use of methods such as .save_cookies and .load_cookies if they were to be addedNicety
I've been using those two cookie jar functions in other web-driving libraries for years--usually to extend session lifetime or manipulate data offsite--and would positively love to see them in the Watir specs too. But I just ran into another problem I feel I need to warn about; commenting above.Eyepiece
FYI watir-webdriver now implements Cookie#save and Cookie#load which saves/loads cookies to/form YAML fileRocca

© 2022 - 2024 — McMap. All rights reserved.