| #Symfony2, #Codeception, #testing

Logging in programmatically with Codeception and Symfony2

This article describes how to acceptance test pages that require a logged in user.

This article is not about testing the login functionality, which includes filling in a form and being redirected. It is about logging in without filling forms and being redirected, to rapidly test pages behind a firewall.

This article presumes, that you have Codeception up and running.

First the Symfony2 Module and the WebDriver Module have to be downloaded and enabled in the acceptance.suite.yml file. Since the login functionality should be accessible from all acceptance tests, it is placed in a helper class in the /_support directory. The helper class also has to be enabled in the acceptance.suite.yml file.

The code

The WebHelper.php looks like this:

<?php
namespace Codeception\Module;


use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;


class WebHelper extends \Codeception\Module
{
    public function amLoggedInAs($username)
    {

        $container = $this->getModule('Symfony2')->container;

        $doctrine = $container->get('doctrine');
        $user = $doctrine
            ->getRepository('UserBundle:User')
            ->findOneBy(['name' => $username]);

        $firewall = 'main';
        $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());


        $session = $container->get('session');
        $session->set('_security_' . $firewall, serialize($token));
        $session->save();


        $webDriver = $this->getModule('WebDriver');
        $webDriver->setCookie($session->getName(), $session->getId());
        $webDriver->reloadPage();
    }

}

This function works as follows. The function accepts an username as parameter. The Symfony2 service container is retrieved from the Codeception Symfony2 module. The user repository may have to be changed based on your Symfony 2 application. A security Token for the given user and firewall is created. The token is saved to the Symfony2 session, to keep the user logged in after following links. Finally the Webdriver Module is used to add a session cookie to the response and it reloads the page.

The acceptance.suite.yml may look similar to:

class_name: AcceptanceTester
modules:
    enabled:
        - WebHelper
        - Symfony2
        - WebDriver
    config:
        WebDriver:
             url: 'http://127.0.0.1:8888/app.php'
             browser: chrome
             window_size: 1024x768
             wait: 0

borwser: chrome is optional. It also works using other browsers.

Usage

In any test file, the login functionality can be used as
$I->amLoggedInAs('Username');, where username obviously has to be a valid username in the database.

Example:

public function SecurePageTest(AcceptanceTester $I)
{
    $I->amOnPage('/');
    $I->amLoggedInAs('adminUser');
    $I->amOnPage('/admin');
    $I->see('edit settings');
}

← How to call jQuery plugins using the apply() or call() functions
→ dice 8