2

I need to authenticate my WebDriver Client for functional tests.

For example, In my integration tests, i'm doing something like that :

namespace Tests\Controller;

use App\Entity\Donor;
use App\Entity\User;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\SchemaTool;
use SebastianBergmann\Type\RuntimeException;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DonorTest extends WebTestCase
{
    private static $client;

    /**
     * @var EntityManager
     */
    private $entityManager;

    /**
     * @var SchemaTool
     */
    private $schemaTool;

    public function __construct(?string $name = null, array $data = [], string $dataName = '')
    {
        parent::__construct($name, $data, $dataName);

        static::ensureKernelShutdown();

        if (!self::$client) {
            self::$client = static::createClient([], [
                'PHP_AUTH_USER' => 'Same Old User',
                'PHP_AUTH_PW' => 'Same Old Password',
            ]);
        }

        $this->entityManager = self::bootKernel()
            ->getContainer()
            ->get('doctrine')
            ->getManager();

        $this->schemaTool = new SchemaTool($this->entityManager);

        /** Safeguard */
        $connection = $this->entityManager->getConnection()->getParams();
        if ($connection['driver'] != 'pdo_sqlite' || $connection['path'] != '/tmp/test_db.sqlite') {
            throw new RuntimeException('Wrong database, darling ! Please set-up your testing database correctly. See /config/packages/test/doctrine.yaml and /tests/README.md');
        }
    }

I'm just passing the credentials in paramaters, and it works.

But, in my functional tests, i'm using the WebDriver. It didn't accept credentials in arguments :

<?php

namespace App\Tests\Functional\Entities\Donor;

use App\Entity\Donor;
use App\Tests\Functional\Helpers\Carrier\CarrierHelper;
use App\Tests\Functional\Helpers\Donor\DonorHelper;
use Doctrine\ORM\EntityManager;
use Facebook\WebDriver\WebDriverBy;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Panther\PantherTestCase;
use Symfony\Component\Panther\Client;

class DonorTest extends PantherTestCase
{
    /**
     * @var EntityManager
     */
    private $entityManager;

    /**
     * @var CarrierHelper
     */
    private $helper;

    /**
     * @var Client
     */
    private $client;

    public function __construct(?string $name = null, array $data = [], string $dataName = '')
    {
        parent::__construct($name, $data, $dataName);

        $this->entityManager = self::bootKernel()
            ->getContainer()
            ->get('doctrine')
            ->getManager();

        $this->helper = new DonorHelper();
    }

    public static function setUpBeforeClass(): void
    {
        // Do something

    }

    public function setUp(): void
    {
        parent::setUp(); // TODO: Change the autogenerated stub
        $this->client = Client::createChromeClient();
        $this->client->manage()->window()->maximize();
    }

I can't pass any login arguments in createChromeClient() method. I think i have to play with cookies in cookieJar, or token, but i don't know how.

Feel free to ask me my ahtentication method, but i've followed the documentation : https://symfony.com/doc/current/security/form_login_setup.html

EDIT

I've just tried something else. Log in with my browser, for generate a cookie, and tried to handcraft an other with same PHPSESSID

    public function setUp(): void
    {
        parent::setUp(); // TODO: Change the autogenerated stub
        $this->client = Client::createChromeClient();
        $this->client->manage()->window()->maximize();

        $cookie = new Cookie('PHPSESSID', 'pafvg5nommcooa60q14nqhool0');
        $cookie->setDomain('127.0.0.1');
        $cookie->setHttpOnly(true);
        $cookie->setSecure(false);
        $cookie->setPath('/');

        $this->client->manage()->addCookie($cookie);

    }

But get this error :

Facebook\WebDriver\Exception\InvalidCookieDomainException: invalid cookie domain

Domain is good, same as my web browser. I will update as my investigations progressed.

EDIT 2

Ok... Got It.

According to this thread : Unable to set cookies in Selenium Webdriver

For setting-up cookie['domain'], you have to request firstly on the domain, THEN set-up the cookie...

SO, this is almost working :

    public function setUp(): void
    {
        parent::setUp(); // TODO: Change the autogenerated stub
        $this->client = Client::createChromeClient();
        $this->client->manage()->window()->maximize();

        $this->client->request('GET', 'http://127.0.0.1/randompage');

        $handcookie = Cookie::createFromArray([
            'name' => 'PHPSESSID',
            'value' => 'pcvbf3sjlla16rfb1b1274qk01',
            'domain' => '127.0.0.1',
            'path' => '/'
        ]);
        $this->client->manage()->addCookie($handcookie);
    }

Next step : Find a way to generate a permanent cookie, without lifetime. I think nobody will read this but i will update it in case someone else gets stuck.

shaax
  • 306
  • 3
  • 18
  • 1
    Since you allow for basic auth for your functional tests you should be able to reuse those credentials in your selenium driver by adding them to the url like this: `http://user:password@example.com` – dbrumann Feb 18 '20 at 16:01
  • Thanks mate, good idea ! But, basic auth works with cURL ( ~$ curl -L login:pass@localhost:8000) but not on my web browser. I investigate. – shaax Feb 19 '20 at 09:26
  • 1
    "I think nobody will read this but i will update it in case someone else gets stuck." => I'm reading it, thanks for the update :) – NicolasB Jun 11 '20 at 06:42

0 Answers0