1

Some time ago I edited version 2.5.3 of java selenium standalone to remove the error message "unable to set cookie" that occurs when trying to set a cookie prior to loading a page from the domain that the cookie pertains to. That modification involved editing some javascript to remove the error checking.

Is it possible to do a similar modification in selenium 3.7.1 for the java build towards altering the java chrome?

Currently I'm using the following maven dependencies. I haven't modified the open source yet.

<dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-chrome-driver</artifactId>
            <version>3.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-remote-driver</artifactId>
            <version>3.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.7.1</version>
        </dependency>

I would be interested to know why selenium handles cookies differently than the browser. When you load a page on a browser, the cookies are already available on the first load of the page. With selenium the cookies are only available after loading the given domain page a first time and then a second load of the given domain page is required to have the cookies recognized.

I'm assuming there must be some logical reason why things must be implemented this way. Does anyone know why?

My continuing research into modifying selenium 3.7.1:

I've found the error message l[25] = "unable to set cookie"; in the following java and javascript files in the selenium github code

grep -rnw './' -e "unable to set cookie"

./javascript/atoms/error.js:142:  UNABLE_TO_SET_COOKIE: 'unable to set cookie',
./javascript/node/selenium-webdriver/test/lib/error_test.js:61:    test('unable to set cookie', error.UnableToSetCookieError);
./javascript/node/selenium-webdriver/test/lib/error_test.js:115:    test(error.UnableToSetCookieError, 'unable to set cookie');
./javascript/node/selenium-webdriver/test/lib/error_test.js:189:    test('unable to set cookie', error.UnableToSetCookieError);
./javascript/node/selenium-webdriver/lib/error.js:474:    ['unable to set cookie', UnableToSetCookieError],
./java/client/src/org/openqa/selenium/remote/ErrorCodes.java:245:    .add(new KnownError(UNABLE_TO_SET_COOKIE, "unable to set cookie", 500, UnableToSetCookieException.class, true, true))

./javascript/node/selenium-webdriver/lib/error.js:474 has the following code

/**
 * A request to set a cookie’s value could not be satisfied.
 */
class UnableToSetCookieError extends WebDriverError {
  /** @param {string=} opt_error the error message, if any. */
  constructor(opt_error) {
    super(opt_error);
  }
} has the 

./java/client/src/org/openqa/selenium/remote/ErrorCodes.java:245 has the following code

 public static final int UNABLE_TO_SET_COOKIE = 25;

 .add(new KnownError(UNABLE_TO_SET_COOKIE, "unable to set cookie", 500, UnableToSetCookieException.class, true, true))

Cleary UnableToSetCookieException may be of importance. So I've greped the following

 grep -rnw './' -e "UnableToSetCookieException"

./java/client/src/org/openqa/selenium/remote/ErrorCodes.java:45:import org.openqa.selenium.UnableToSetCookieException;
./java/client/src/org/openqa/selenium/remote/ErrorCodes.java:245:    .add(new KnownError(UNABLE_TO_SET_COOKIE, "unable to set cookie", 500, UnableToSetCookieException.class, true, true))
./java/client/src/org/openqa/selenium/BUCK:128:    'UnableToSetCookieException.java',
./java/client/src/org/openqa/selenium/UnableToSetCookieException.java:25:public class UnableToSetCookieException extends WebDriverException {
./java/client/src/org/openqa/selenium/UnableToSetCookieException.java:26:  public UnableToSetCookieException() {
./java/client/src/org/openqa/selenium/UnableToSetCookieException.java:29:  public UnableToSetCookieException(String message) {
./java/client/src/org/openqa/selenium/UnableToSetCookieException.java:33:  public UnableToSetCookieException(Throwable cause) {
./java/client/src/org/openqa/selenium/UnableToSetCookieException.java:37:  public UnableToSetCookieException(String message, Throwable cause) {
./java/client/test/org/openqa/selenium/remote/ErrorHandlerTest.java:54:import org.openqa.selenium.UnableToSetCookieException;
./java/client/test/org/openqa/selenium/remote/ErrorHandlerTest.java:460:    exceptions.put(ErrorCodes.UNABLE_TO_SET_COOKIE, UnableToSetCookieException.class);

Clearly the following class throws the cookie exception

/**
 * Thrown when a driver fails to set a cookie.
 *
 * @see org.openqa.selenium.WebDriver.Options#addCookie(Cookie)
 */
public class UnableToSetCookieException extends WebDriverException {
  public UnableToSetCookieException() {
  }

  public UnableToSetCookieException(String message) {
    super(message);
  }

However I'm not yet understanding how or if this relates to the addCookie method which generates the error.

driver.manage().addCookie(aCookie);

I'll continue to update my research here as I learn more...

conteh
  • 1,544
  • 1
  • 17
  • 39
  • The method `addCookie` handles cookies just like the browser and needs a domain which is missing if you don't call `get` first. A web page cannot set a cookie on a different domain. If it was the case, any page would be able to rewrite the cookies from your Google or Facebook session. It's possible to set the cookies at a browser level with Selenium alone, but it requires a specific implementation which depends on the driver/browser. – Florent B. Nov 21 '17 at 15:53
  • 1
    @FlorentB. I understand your comments. It would seem though that using the browser as a human the cookies are available to the site being opened fairly early on in the loading process. If I load a shopping website with a cart, the items in the cart are present before the page is loaded. If I do that same interaction with selenium it's not possible without loading the page a second time. This is very clear difference. I would like selenium to work the same way as the browser loading the cookies on first load or the page. Is that possible with the selenium java chrome driver? – conteh Nov 21 '17 at 18:12
  • 1
    If your goal is to reuse a session then use a static profile with the argument `--user-data-dir="path to Default directory"`. Otherwise either set the domain with a cheap resource like `https://www.google.com/favicon.ico` or call the devtool API to set the cookie at a browser level: https://stackoverflow.com/questions/47020772/selenium-and-google-how-do-you-use-cookies/47022711#47022711 – Florent B. Nov 21 '17 at 18:30
  • add products to your cart and save the browser profile and use that profile every time you open the browser. Should work. – Arno Nov 22 '17 at 02:20
  • @FlorentB. I tested the --user-data-dir method with firefox and an earlier version of selenium, perhaps 3.5.1, I'm not sure, however I didn't find that it handled the cookies effectively. That's good advice to call the favicon.ico as a cheap resource. Hopefully if it's possible Selenium can create some logic to set a domain and then load the domain with cookies similar to how the browser is already working. Perhaps it's not feasible? – conteh Nov 22 '17 at 09:56
  • @FlorentB. I earlier created a webextension in chrome that saves cookies as they are modified in chrome into an xml file and loads cookies at browser startup towards sharing cookies with selenium. It works in chrome with human interaction however with selenium it loads the cookies, i.e. cart item is present on first load of the page, however selenium does not have access to list these cookies and the webextension saves an empty XML file. Do you have insight as to why the webextension behaves differently between the two use cases and why selenium does not have access to the cookies? – conteh Nov 22 '17 at 10:04
  • The switch `--user-data-dir` is specific to Chrome. For Firefox, use `-profile "path to static profile"`. Don't know about the web extension. – Florent B. Nov 22 '17 at 10:08
  • @FlorentB. I had been using FirefoxProfileEx profile = new FirefoxProfileEx(new File("/home/username/profile")); – conteh Nov 22 '17 at 10:17
  • FirefoxProfile is a legacy class from the previous driver, use FirefoxOptions instead. – Florent B. Nov 22 '17 at 10:23

0 Answers0