Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reliably set cookies on localhost using webdriver and Chrome?

In my experience, this works fine when using webdriver (via Protractor) to inject a cookie into a browser session on Firefox:

browser.manager().addCookie(...)

Where the "..." is an "httpOnly" localhost session cookie used to indicate that a user is logged in.

The same code when run against a Chrome browser (using the direct ChromeDriver) does not work. First, there are the localhost cookie exceptions:

Message:
     InvalidCookieDomainError: invalid cookie domain: invalid domain:"localhost"
  (Session info: chrome=41.0.2272.89)
  (Driver info: chromedriver=2.14.313457 (3d645c400edf2e2c500566c9aa096063e707c9cf),platform=Linux 3.13.0-45-generic x86_64)
   Stacktrace:
     InvalidCookieDomainError: invalid cookie domain: invalid domain:"localhost"
  (Session info: chrome=41.0.2272.89)
  (Driver info: chromedriver=2.14.313457 (3d645c400edf2e2c500566c9aa096063e707c9cf),platform=Linux 3.13.0-45-generic x86_64)

Even if I can work-around the localhost problem (E.g., by setting fully qualified domain), Chrome will just ignore my changes to the cookie.

I'm running on Linux, with Protractor 2.0.0, and google-chrome 41.0.xxx and chromedriver 2.14.

like image 202
P.T. Avatar asked Mar 28 '15 00:03

P.T.


People also ask

Can we set cookie in localhost?

Secure cookies are set only on HTTPS, but not on http://localhost for all browsers.

Does selenium Webdriver store cookies?

When the code is executed, webdriver will store the cookie information using FileWriter Class to write streams of characters and BufferedWriter to write the text into a file named “Cookiefile. data“. The file stores cookie information – “Name, Value, Domain, Path”.


1 Answers

There are two workarounds that will work with Chrome and will not break Firefox.

First, use null instead of localhost as the cookie domain. Chrome will treat this as meaning "the same page as the current page's domain". Which is fine, since you need to make the browser visit a page before you're allowed to set the cookies anyway.

Second, clear the existing cookie before setting the new cookie (browser.manager().deleteCookie()). Chrome disallows (silently) changes to some cookies via the webdriver API. By deleting the cookie, you're then allowed to set it.

// cookieObj is a "tough.Cookie" instance in my case
function setCookie(cookieObj) {
   var domain = cookieObj.domain;
   if (domain === 'localhost') {
      domain = null;
   }

   var mgr = browser.manage();
   var cName = cookieObj.key;

   var cookieProm = mgr.deleteCookie(cName).then(function() {
      return mgr.addCookie(
         cName,
         cookieObj.value,
         cookieObj.path,
         domain,
         cookieObj.secure,
         cookieObj.expiryTime());
   });

   cookieProm.then(function() {
      mgr.getCookie(cName).then(function(cookie) {
         console.log("Actual cookie", cName, "::", cookie);
         expect(cookie.value).toBe(cookieObj.value);
      });
   });

   return cookieProm;
}
like image 99
P.T. Avatar answered Nov 15 '22 03:11

P.T.