如何使用 webdriver 和 Chrome 在本地主机上可靠地设置 cookie?

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

根据我的经验,在 Firefox 上使用 webdriver(通过 Protractor)将 cookie 注入浏览器会话时效果很好:

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

其中“...”是一个 "httpOnly" 本地主机会话 cookie,用于指示用户已登录。

当 运行 针对 Chrome 浏览器(使用直接 Chrome 驱动程序)时,相同的代码不起作用。首先,有 localhost cookie 异常:

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)

即使我可以解决本地主机问题(例如,通过设置完全限定的域),Chrome 也只会忽略我对 cookie 的更改。

我 运行正在 Linux 上使用 Protractor 2.0.0,并且 google-chrome 41.0.xxx 和 chrome驱动程序 2.14.

有两种解决方法适用于 Chrome,并且不会破坏 Firefox。

首先,使用 null 而不是 localhost 作为 cookie 域。 Chrome 会将此视为 "the same page as the current page's domain" 的意思。这很好,因为您需要先让浏览器访问一个页面,然后您才能设置 cookie。

其次,在设置新 cookie 之前清除现有 cookie (browser.manager().deleteCookie())。 Chrome 不允许(静默地)通过网络驱动程序更改某些 cookie API。通过删除 cookie,您可以设置它。

// 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;
}