MinkZombieDriver icon indicating copy to clipboard operation
MinkZombieDriver copied to clipboard

Better way to set Cookie before visiting a page

Open eugef opened this issue 10 years ago • 12 comments

For now it is impossible to set cookie before visiting the page.

The reason is that ZombieDriver::setCookie() uses browser.window.location.hostname which is undefined before you actually visit the page.

My workaround was to use the code which allows to specify domain explicitly:

public function setBrowserCookie($domain, $name, $value)
    {
        if ($value === null) {
            $this->getSession()->evaluateScript(
                'browser.deleteCookie(' . json_encode($name). ')'
            );
        } else {
            $this->getSession()->evaluateScript(
                sprintf('browser.setCookie({name: %s, domain: %s}, %s)',
                    json_encode($name),
                    json_encode($domain),
                    json_encode($value)
                )
            );
        }
    }

So my questions are

  1. Is it possible to set browser.window.location.hostname before visiting the page?
  2. OR is it possible to refactor ZombieDriver::setCookie() so it accepts custom domain?

eugef avatar Jan 29 '15 14:01 eugef

In real browser you can't set cookie before visiting the page, because the cookie domain must match to page you set them on for page itself to recognize them.

Why you need to set cookie before visiting a page?

aik099 avatar Jan 29 '15 14:01 aik099

Also documentation http://mink.behat.org/en/latest/guides/session.html says that before you do anything you must visit a page first.

aik099 avatar Jan 29 '15 14:01 aik099

So my questions are

No matter which approach you decide to implement keep in mind, that new behavior must be implemented in all other Mink drivers as well.

aik099 avatar Jan 29 '15 14:01 aik099

Setting cookies on other domains will be impossible on Selenium or Sahi. This is why the Mink API does not allow it

stof avatar Jan 29 '15 15:01 stof

@aik099, I have different behavior on the page depending on cookie exists or not - that is why I need to set it. Also in a real browser you can send cookies in the request header. I tried to do this with ZombieJs but seems "Cookie" header is ignored.

@stof, Cookie will be set for the same domain.

eugef avatar Jan 29 '15 15:01 eugef

Maybe you can create wrapper page or pass some flag to a page, that when used will set cookie and redirect to correct page.

aik099 avatar Jan 29 '15 17:01 aik099

@aik099 , i don't think it is a good solution, this makes my tests/implementation depend on ZombieJs driver restrictions.

Possible solution would be allow to set domain without visiting a pageand then you can set cookie.

eugef avatar Jan 30 '15 09:01 eugef

@eugef it would make your test depend on the Mink API itself

stof avatar Jan 30 '15 09:01 stof

@eugef , aren't you trying to set session id in that cookie? I know there is an approach to create session and then inject it's ID in cookie so user would be logged-in on website. I recommend you performing login each time instead.

aik099 avatar Jan 30 '15 09:01 aik099

@aik099, no it is not a session cookie. Cookie is used by JS to hide/show some elements on the page.

eugef avatar Jan 30 '15 09:01 eugef

This worked for me:

use Symfony\Component\BrowserKit\Cookie;

$cookie = new Cookie($name, $value);
$this->getSession()->setRequestHeader('Cookie', (string)$cookie);

TerjeBr avatar Mar 14 '17 16:03 TerjeBr

@TerjeBr I'm getting this

 Request headers manipulation is not supported by Behat\Mink\Driver\Selenium2Driver (Behat\Mink\Exception\UnsupportedDriverActionException)

seyfer avatar Dec 26 '18 18:12 seyfer