mirror of
https://github.com/silverstripe/silverstripe-behat-extension
synced 2024-09-28 20:29:36 +02:00
6a7df2f702
Had some issues with multiple login forms on the same page, e.g. for social login, or with duplicated hidden login forms in the header.
201 lines
6.5 KiB
PHP
201 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace SilverStripe\BehatExtension\Context;
|
|
|
|
use Behat\Behat\Context\ClosuredContextInterface,
|
|
Behat\Behat\Context\TranslatedContextInterface,
|
|
Behat\Behat\Context\BehatContext,
|
|
Behat\Behat\Context\Step,
|
|
Behat\Behat\Exception\PendingException;
|
|
use Behat\Gherkin\Node\PyStringNode,
|
|
Behat\Gherkin\Node\TableNode;
|
|
|
|
// PHPUnit
|
|
require_once 'PHPUnit/Autoload.php';
|
|
require_once 'PHPUnit/Framework/Assert/Functions.php';
|
|
|
|
/**
|
|
* LoginContext
|
|
*
|
|
* Context used to define steps related to login and logout functionality
|
|
*/
|
|
class LoginContext extends BehatContext
|
|
{
|
|
protected $context;
|
|
|
|
/**
|
|
* Cache for logInWithPermission()
|
|
*/
|
|
protected $cache_generatedMembers = array();
|
|
|
|
/**
|
|
* Initializes context.
|
|
* Every scenario gets it's own context object.
|
|
*
|
|
* @param array $parameters context parameters (set them up through behat.yml)
|
|
*/
|
|
public function __construct(array $parameters)
|
|
{
|
|
// Initialize your context here
|
|
$this->context = $parameters;
|
|
}
|
|
|
|
/**
|
|
* Get Mink session from MinkContext
|
|
*/
|
|
public function getSession($name = null)
|
|
{
|
|
return $this->getMainContext()->getSession($name);
|
|
}
|
|
|
|
/**
|
|
* @Given /^I am logged in$/
|
|
*/
|
|
public function stepIAmLoggedIn()
|
|
{
|
|
$c = $this->getMainContext();
|
|
$adminUrl = $c->joinUrlParts($c->getBaseUrl(), $c->getAdminUrl());
|
|
$loginUrl = $c->joinUrlParts($c->getBaseUrl(), $c->getLoginUrl());
|
|
|
|
$this->getSession()->visit($adminUrl);
|
|
|
|
if (0 == strpos($this->getSession()->getCurrentUrl(), $loginUrl)) {
|
|
$this->stepILogInWith('admin', 'password');
|
|
assertStringStartsWith($adminUrl, $this->getSession()->getCurrentUrl());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a member in a group with the correct permissions.
|
|
* Example: Given I am logged in with "ADMIN" permissions
|
|
*
|
|
* @Given /^I am logged in with "([^"]*)" permissions$/
|
|
*/
|
|
function iAmLoggedInWithPermissions($permCode)
|
|
{
|
|
if (!isset($this->cache_generatedMembers[$permCode])) {
|
|
$group = \Group::get()->filter('Title', "$permCode group")->first();
|
|
if (!$group) {
|
|
$group = \Injector::inst()->create('Group');
|
|
}
|
|
|
|
$group->Title = "$permCode group";
|
|
$group->write();
|
|
|
|
$permission = \Injector::inst()->create('Permission');
|
|
$permission->Code = $permCode;
|
|
$permission->write();
|
|
$group->Permissions()->add($permission);
|
|
|
|
$member = \DataObject::get_one('Member', sprintf('"Email" = \'%s\'', "$permCode@example.org"));
|
|
if (!$member) {
|
|
$member = \Injector::inst()->create('Member');
|
|
}
|
|
|
|
// make sure any validation for password is skipped, since we're not testing complexity here
|
|
$validator = \Member::password_validator();
|
|
\Member::set_password_validator(null);
|
|
$member->FirstName = $permCode;
|
|
$member->Surname = "User";
|
|
$member->Email = "$permCode@example.org";
|
|
$member->changePassword('secret');
|
|
$member->write();
|
|
$group->Members()->add($member);
|
|
\Member::set_password_validator($validator);
|
|
|
|
$this->cache_generatedMembers[$permCode] = $member;
|
|
}
|
|
|
|
return new Step\Given(sprintf('I log in with "%s" and "%s"', "$permCode@example.org", 'secret'));
|
|
}
|
|
|
|
/**
|
|
* @Given /^I am not logged in$/
|
|
*/
|
|
public function stepIAmNotLoggedIn()
|
|
{
|
|
$c = $this->getMainContext();
|
|
$this->getSession()->visit($c->joinUrlParts($c->getBaseUrl(), 'Security/logout'));
|
|
}
|
|
|
|
/**
|
|
* @When /^I log in with "(?<username>[^"]*)" and "(?<password>[^"]*)"$/
|
|
*/
|
|
public function stepILogInWith($email, $password)
|
|
{
|
|
$page = $this->getSession()->getPage();
|
|
$forms = $page->findAll('css', 'form[action="Security/LoginForm"]');
|
|
assertNotNull($forms, 'Login form not found');
|
|
|
|
// Try to find visible forms on current page
|
|
// Allow multiple login forms (e.g. social login) by filering for "Email" field
|
|
$visibleForm = null;
|
|
foreach($forms as $form) {
|
|
if($form->isVisible() && $form->find('css', '[name=Email]')) {
|
|
$visibleForm = $form;
|
|
}
|
|
}
|
|
|
|
// If no login form, go to /security/login page
|
|
if(!$visibleForm) {
|
|
$c = $this->getMainContext();
|
|
$loginUrl = $c->joinUrlParts($c->getBaseUrl(), $c->getLoginUrl());
|
|
$this->getSession()->visit($loginUrl);
|
|
$page = $this->getSession()->getPage();
|
|
$forms = $page->findAll('css', 'form[action="Security/LoginForm"]');
|
|
}
|
|
|
|
// Try to find visible forms again on login page.
|
|
$visibleForm = null;
|
|
foreach($forms as $form) {
|
|
if($form->isVisible() && $form->find('css', '[name=Email]')) {
|
|
$visibleForm = $form;
|
|
}
|
|
}
|
|
|
|
assertNotNull($visibleForm, 'Could not find login form');
|
|
|
|
$emailField = $visibleForm->find('css', '[name=Email]');
|
|
$passwordField = $visibleForm->find('css', '[name=Password]');
|
|
$submitButton = $visibleForm->find('css', '[type=submit]');
|
|
|
|
assertNotNull($emailField, 'Email field on login form not found');
|
|
assertNotNull($passwordField, 'Password field on login form not found');
|
|
assertNotNull($submitButton, 'Submit button on login form not found');
|
|
|
|
$emailField->setValue($email);
|
|
$passwordField->setValue($password);
|
|
$submitButton->press();
|
|
}
|
|
|
|
/**
|
|
* @Given /^I should see a log-in form$/
|
|
*/
|
|
public function stepIShouldSeeALogInForm()
|
|
{
|
|
$page = $this->getSession()->getPage();
|
|
$loginForm = $page->find('css', '#MemberLoginForm_LoginForm');
|
|
assertNotNull($loginForm, 'I should see a log-in form');
|
|
}
|
|
|
|
/**
|
|
* @Then /^I will see a "([^"]*)" log-in message$/
|
|
*/
|
|
public function stepIWillSeeALogInMessage($type)
|
|
{
|
|
$page = $this->getSession()->getPage();
|
|
$message = $page->find('css', sprintf('.message.%s', $type));
|
|
assertNotNull($message, sprintf('%s message not found.', $type));
|
|
}
|
|
|
|
/**
|
|
* @Then /^the password for "([^"]*)" should be "([^"]*)"$/
|
|
*/
|
|
public function stepPasswordForEmailShouldBe($id, $password)
|
|
{
|
|
$member = \Member::get()->filter('Email', $id)->First();
|
|
assertNotNull($member);
|
|
assertTrue($member->checkPassword($password)->valid());
|
|
}
|
|
}
|