Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authentification with HTTP cookie in Selenium using Behat

I would like to create a behat definition to authenticate a user using a cookie.

It works with the Behat BrowserKitDriver, when there is no @javascript tag on the behat scenario. But it did not work with the Behat Selenium2Driver, when there is the @javascript tag like here.

I used the symfony-demo application for demonstrate my tests.

What's wrong in my definition ?

/**
 * @Given I am logged in as :username
 */
public function iAmLoggedInAs($username)
{
    $driver = $this->getSession()->getDriver();
    $session = $this->kernel->getContainer()->get('session');
    $user = $this->kernel->getContainer()->get('security.user.provider.concrete.database_users')->loadUserByUsername($username);
    $providerKey = 'secured_area';

    $token = new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());
    $session->set('_security_'.$providerKey, serialize($token));
    $session->save();

    if ($driver instanceof BrowserKitDriver) {
        $client = $driver->getClient();
        $cookie = new Cookie($session->getName(), $session->getId());
        $client->getCookieJar()->set($cookie);
    } else if ($driver instanceof Selenium2Driver) {
        $this->visitPath('/');
    } else {
        throw new \Exception('Unsupported Driver');
    }

    $this->getSession()->setCookie($session->getName(), $session->getId());
}

I just want that my last behat test works.
I don't know if I'm clear... ask if not.

If you can do a Pull Request with a fix it will be perfect.

like image 788
mykiwi Avatar asked Jun 09 '16 21:06

mykiwi


1 Answers

You have a few ways

Option 1. Just Use Mink

  • If you use Mink, your Context will extend RawWebContext or WebContext so you can access to the Mink Session with getSession().

  • Then, use setCookie.

As you can see, luckily for us, and this is the point with working with Mink, Cookie Manipulation is supported by many drivers

// ...
$this->visitPath('/');
$this->getSession()->setCookie(
    $session->getName(),
    $session->getId()
);

Note 1: Mind you, the following are not the same thing:

  • $session (ref. your question) is an instance of Symfony\Component\HttpFoundation\Session\Session

  • $this->getSession() returns an instance of Behat\Mink\Session

Note 2: Want to see your cookies?

var_dump($driver->getClient()->getCookieJar());

Option 2. Access Selenium2 Session

Don't hesitate to dive in the code to see how Selenium2 WebDriver Session works.

You will surely find absolute joy and peace of mind.

else if ($driver instanceof Selenium2Driver) {
      $this->visitPath('/');
      $cookie =  array(
           "domain" => "", <----- You can even add your domain here 
           "name" => $session->getName(), 
           "value" => $session->getId(),
           "path" => "/",
           "secure" => False
      );
      $driver->getWebDriverSession()->setCookie($cookie);
} 

Note 3: Want to see your cookies?

var_dump($driver->getWebDriverSession()->getAllCookies());
like image 88
Mick Avatar answered Sep 28 '22 06:09

Mick