使用Behat + Symfony时模拟身份验证或登录

时间:2016-09-24 11:46:38

标签: bdd symfony behat mink

我的应用程序的大部分内容都要求User已登录,而某些部分要求User具有特定角色。

我有这个功能文件。

  Background:
        Given I am logged in as "saif"
        And I am making transaction for "Jaime Sangcap"


    @critical @javascript
    Scenario: Transaction having a sales person for commission
        Given there is "General English Level 1" which costs "499" on the product list
        When I add the "General English Level 1"
        And I assign "Emy Ventura" as the sales person
        Then I should see "Emy Ventura" as the sales person

这是我的上传文件。

<?php


namespace Akademia\Institution\Behat\Sales\Context;


use Akademia\Institution\Behat\Common\Context\CanAuthenticateWithKernel;
use Akademia\Institution\Sales\Domain\Model\Client;
use Akademia\Institution\Sales\Domain\Model\ClientRepository;
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Mink\Driver\BrowserKitDriver;
use Behat\Mink\Exception\UnsupportedDriverActionException;
use Behat\MinkExtension\Context\MinkContext;
use Behat\Symfony2Extension\Context\KernelAwareContext;
use Behat\Symfony2Extension\Context\KernelDictionary;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

class SalesUiContext extends MinkContext implements SnippetAcceptingContext, KernelAwareContext
{
    use KernelDictionary;

    /** @var ClientRepository */
    private $clientRepository;
    private $clientName;

    /**
     * @BeforeScenario
     */
    public function clearData()
    {
        $em = $this->getContainer()->get('doctrine.orm.sales_entity_manager');
        $em->getConnection()->executeQuery('SET foreign_key_checks = 0;');
        $purger = new ORMPurger($em);
        $purger->purge();
    }

    /**
     * @BeforeScenario
     */
    public function loadFixtures()
    {
        shell_exec('bin/console hautelook_alice:doctrine:fixtures:load -n --env=test');
    }

    /**
     * @Given I am making transaction for :name
     */
    public function iAmMakingTransactionFor($name)
    {
        $this->clientName = $name;
        $this->clientRepository = $this->getContainer()->get('akademia_institution.sales.client_repository');
        $this->clientRepository->add(Client::withMinimumDetails($name, '056xxxxxxx', 'irrelevant source'));
        $this->visit(sprintf('clients/?keyword=%s', $name));
        $this->clickLink('register');
    }

    /**
     * @Given there is :arg1 which costs :arg2 on the product list
     */
    public function thereIsWhichCostsOnTheProductList($arg1, $arg2)
    {
        throw new PendingException();
    }

    /**
     * @When I add the :arg1
     */
    public function iAddThe($arg1)
    {
        throw new PendingException();
    }

    /**
     * @When I assign :arg1 as the sales person
     */
    public function iAssignAsTheSalesPerson($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then I should see :arg1 as the sales person
     */
    public function iShouldSeeAsTheSalesPerson($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Given I am logged in as :username
     * @Given I am logged in
     */
    public function iAmLoggedInAs($username = null)
    {
        $driver = $this->getSession('symfony_session')->getDriver();
        if (! ($driver instanceof BrowserKitDriver)) {
            throw new UnsupportedDriverActionException('This step is only supported by the BrowserKitDriver', $driver);
        }

        $client = $driver->getClient();
        $client->getCookieJar()->set(new Cookie(session_name(), true));

        $session = $client->getContainer()->get('session');

        $firewall = $this->getContainer()->getParameter('fos_user.firewall_name');
        $user = $this->getContainer()->get('elite.user_repository')->findByUser($username);
        $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
        $session->set('_security_'.$firewall, serialize($token));
        $session->save();

        $cookie = new Cookie($session->getName(), $session->getId());
        $client->getCookieJar()->set($cookie);
    }
}

behat.yml文件

default:
    gherkin:
        filters:
            tags: "~@wip&&~@disabled"

    extensions:
            Behat\Symfony2Extension:
                kernel:
                    env: test
            Behat\MinkExtension:
                base_url: http://elitesolutions.app
                javascript_session: selenium2_session
                default_session: goutte_session
                sessions:
                    goutte_session:
                        goutte: ~
                    symfony_session:
                        symfony2: ~
                    selenium2_session:
                        selenium2:
                            wd_host: http://192.168.100.0/wd/hub
                            capabilities:
                                browser: firefox
                                version: ANY
    suites:


        sales:
            paths: [ "%paths.base%/features/Sales" ]
            contexts: [ Akademia\Institution\Behat\Sales\Context\SalesDomainContext ]

        sales_ui:
            paths: ["%paths.base%/features/Sales"]
            contexts: [ Akademia\Institution\Behat\Sales\Context\SalesUiContext ]
            filters:
                tags: "@critical"

Given I am logged in as "saif"正在过去 但我在下一步有错误 And I am making transaction for "Jaime Sangcap"说:

Link with id|title|alt|text "register" not found. (Behat\Mink\Exception\ElementNotFoundException)

我认为这是因为在尝试访问网址时,会将其重定向到登录页面,而不是重定向到目标网址(页面)。

因为我的大多数情况都要求您登录我不喜欢在每个方案的真实登录表单上对它们进行身份验证。

有没有办法做到这一点,比如手动设置令牌?

我已尝试按照此post但无法使其正常工作

修改

我认为问题是我正在使用两个数据库,symfony2会话正在使用指向test的{​​{1}}环境,而selenium2正在使用指向{{1}的elite_solutions_test环境}}

这是我的behat.yml

dev

parameters.yml

elite_solutions_dev

config_test.yml

extensions:
        Behat\Symfony2Extension:
            kernel:
                env: test
        Behat\MinkExtension:
            base_url: http://elitesolutions.app
            default_session: symfony
            javascript_session: javascript
            browser_name: phantomjs
            sessions:
                goutte:
                    goutte: ~
                symfony:
                    symfony2: ~
                javascript:
                    selenium2:
                        wd_host: http://10.0.2.2:4444/wd/hub

我应该如何告诉selenium2使用测试环境?或者我应该添加app_test.php?

0 个答案:

没有答案