minkphp / MinkZombieDriver

Zombie.js driver for Mink framework
41 stars 49 forks source link

Better way to set Cookie before visiting a page #122

Open eugef opened 9 years ago

eugef commented 9 years ago

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?
aik099 commented 9 years ago

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 commented 9 years ago

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

aik099 commented 9 years ago

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.

stof commented 9 years ago

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

eugef commented 9 years ago

@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.

aik099 commented 9 years ago

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

eugef commented 9 years ago

@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.

stof commented 9 years ago

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

aik099 commented 9 years ago

@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.

eugef commented 9 years ago

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

TerjeBr commented 7 years ago

This worked for me:

use Symfony\Component\BrowserKit\Cookie;

$cookie = new Cookie($name, $value);
$this->getSession()->setRequestHeader('Cookie', (string)$cookie);
seyfer commented 5 years ago

@TerjeBr I'm getting this

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