mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge remote-tracking branch 'origin/3.0' into 3.1
Conflicts: tests/behat/features/bootstrap/SilverStripe/Framework/Test/Behaviour/CmsUiContext.php
This commit is contained in:
commit
7791f20f49
23
dev/BehatFixtureFactory.php
Normal file
23
dev/BehatFixtureFactory.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @package framework
|
||||
* @subpackage testing
|
||||
*/
|
||||
class BehatFixtureFactory extends \FixtureFactory {
|
||||
public function createObject($name, $identifier, $data = null) {
|
||||
if(!$data) $data = array();
|
||||
|
||||
// Copy identifier to some visible property unless its already defined.
|
||||
// Exclude files, since they generate their own named based on the file path.
|
||||
if(!is_a($name, 'File', true)) {
|
||||
foreach(array('Name', 'Title') as $fieldName) {
|
||||
if(singleton($name)->hasField($fieldName) && !isset($data[$fieldName])) {
|
||||
$data[$fieldName] = $identifier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::createObject($name, $identifier, $data);
|
||||
}
|
||||
}
|
@ -116,6 +116,7 @@ class FixtureBlueprint {
|
||||
|
||||
$this->setValue($obj, $fieldName, $fieldVal, $fixtures);
|
||||
}
|
||||
|
||||
$obj->write();
|
||||
|
||||
// Save to fixture before relationship processing in case of reflexive relationships
|
||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\Framework\Test\Behaviour;
|
||||
use SilverStripe\BehatExtension\Context\SilverStripeContext,
|
||||
SilverStripe\BehatExtension\Context\BasicContext,
|
||||
SilverStripe\BehatExtension\Context\LoginContext,
|
||||
SilverStripe\BehatExtension\Context\FixtureContext,
|
||||
SilverStripe\Framework\Test\Behaviour\CmsFormsContext,
|
||||
SilverStripe\Framework\Test\Behaviour\CmsUiContext;
|
||||
|
||||
@ -20,6 +21,12 @@ require_once 'PHPUnit/Framework/Assert/Functions.php';
|
||||
*/
|
||||
class FeatureContext extends SilverStripeContext
|
||||
{
|
||||
|
||||
/**
|
||||
* @var FixtureFactory
|
||||
*/
|
||||
protected $fixtureFactory;
|
||||
|
||||
/**
|
||||
* Initializes context.
|
||||
* Every scenario gets it's own context object.
|
||||
@ -28,11 +35,46 @@ class FeatureContext extends SilverStripeContext
|
||||
*/
|
||||
public function __construct(array $parameters)
|
||||
{
|
||||
parent::__construct($parameters);
|
||||
|
||||
$this->useContext('BasicContext', new BasicContext($parameters));
|
||||
$this->useContext('LoginContext', new LoginContext($parameters));
|
||||
$this->useContext('CmsFormsContext', new CmsFormsContext($parameters));
|
||||
$this->useContext('CmsUiContext', new CmsUiContext($parameters));
|
||||
|
||||
parent::__construct($parameters);
|
||||
$fixtureContext = new FixtureContext($parameters);
|
||||
$fixtureContext->setFixtureFactory($this->getFixtureFactory());
|
||||
$this->useContext('FixtureContext', $fixtureContext);
|
||||
|
||||
// Use blueprints to set user name from identifier
|
||||
$factory = $fixtureContext->getFixtureFactory();
|
||||
$blueprint = \Injector::inst()->create('FixtureBlueprint', 'Member');
|
||||
$blueprint->addCallback('beforeCreate', function($identifier, &$data, &$fixtures) {
|
||||
if(!isset($data['FirstName'])) $data['FirstName'] = $identifier;
|
||||
});
|
||||
$factory->define('Member', $blueprint);
|
||||
}
|
||||
|
||||
public function setMinkParameters(array $parameters)
|
||||
{
|
||||
parent::setMinkParameters($parameters);
|
||||
|
||||
if(isset($parameters['files_path'])) {
|
||||
$this->getSubcontext('FixtureContext')->setFilesPath($parameters['files_path']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FixtureFactory
|
||||
*/
|
||||
public function getFixtureFactory() {
|
||||
if(!$this->fixtureFactory) {
|
||||
$this->fixtureFactory = \Injector::inst()->create('BehatFixtureFactory');
|
||||
}
|
||||
return $this->fixtureFactory;
|
||||
}
|
||||
|
||||
public function setFixtureFactory(FixtureFactory $factory) {
|
||||
$this->fixtureFactory = $factory;
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ use Behat\Behat\Context\ClosuredContextInterface,
|
||||
Behat\Behat\Context\BehatContext,
|
||||
Behat\Behat\Context\Step,
|
||||
Behat\Behat\Exception\PendingException,
|
||||
Behat\Mink\Exception\ElementNotFoundException;
|
||||
use Behat\Gherkin\Node\PyStringNode,
|
||||
Behat\Mink\Exception\ElementNotFoundException,
|
||||
Behat\Gherkin\Node\PyStringNode,
|
||||
Behat\Gherkin\Node\TableNode;
|
||||
|
||||
|
||||
@ -310,7 +310,7 @@ class CmsUiContext extends BehatContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround for chosen.js dropdowns which hide the original dropdown field.
|
||||
* Workaround for chosen.js dropdowns or tree dropdowns which hide the original dropdown field.
|
||||
*
|
||||
* @When /^(?:|I )fill in the "(?P<field>(?:[^"]|\\")*)" dropdown with "(?P<value>(?:[^"]|\\")*)"$/
|
||||
* @When /^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for the "(?P<field>(?:[^"]|\\")*)" dropdown$/
|
||||
@ -320,6 +320,12 @@ class CmsUiContext extends BehatContext
|
||||
$field = $this->fixStepArgument($field);
|
||||
$value = $this->fixStepArgument($value);
|
||||
|
||||
$nativeField = $this->getSession()->getPage()->findField($field);
|
||||
if($nativeField) {
|
||||
$nativeField->selectOption($value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Given the fuzzy matching, we might get more than one matching field.
|
||||
$formFields = array();
|
||||
|
||||
@ -338,26 +344,28 @@ class CmsUiContext extends BehatContext
|
||||
);
|
||||
}
|
||||
|
||||
// Find by name (incl. hidden fields)
|
||||
if(!$formFields) {
|
||||
$formFields = $this->getSession()->getPage()->findAll('xpath', "//*[@name='$field']");
|
||||
}
|
||||
|
||||
assertGreaterThan(0, count($formFields), sprintf(
|
||||
'Chosen.js dropdown named "%s" not found',
|
||||
$field
|
||||
));
|
||||
|
||||
// Traverse up to field holder
|
||||
$containers = array();
|
||||
foreach($formFields as $formField) {
|
||||
// Traverse up to field holder
|
||||
$containerCandidate = $formField;
|
||||
do {
|
||||
$containerCandidate = $containerCandidate->getParent();
|
||||
} while($containerCandidate && !preg_match('/field/', $containerCandidate->getAttribute('class')));
|
||||
|
||||
if(
|
||||
$containerCandidate
|
||||
&& $containerCandidate->isVisible()
|
||||
&& preg_match('/field/', $containerCandidate->getAttribute('class'))
|
||||
) {
|
||||
$containers[] = $containerCandidate;
|
||||
}
|
||||
$container = $formField->getParent();
|
||||
$containerClasses = explode(' ', $container->getAttribute('class'));
|
||||
$containers[] = $container;
|
||||
} while(
|
||||
$container
|
||||
&& in_array('field', $containerClasses)
|
||||
&& $container->getTagName() != 'form'
|
||||
);
|
||||
}
|
||||
|
||||
assertGreaterThan(0, count($containers), 'Chosen.js field container not found');
|
||||
@ -371,17 +379,27 @@ class CmsUiContext extends BehatContext
|
||||
$this->getSession()->wait(100); // wait for dropdown overlay to appear
|
||||
$linkEl->click();
|
||||
|
||||
if(in_array('treedropdown', $containerClasses)) {
|
||||
// wait for ajax dropdown to load
|
||||
$this->getSession()->wait(
|
||||
5000,
|
||||
"jQuery('#" . $container->getAttribute('id') . " .treedropdownfield-panel li').length > 0"
|
||||
);
|
||||
} else {
|
||||
// wait for dropdown overlay to appear (might be animated)
|
||||
$this->getSession()->wait(300);
|
||||
}
|
||||
|
||||
|
||||
$listEl = $container->find('xpath', sprintf('.//li[contains(normalize-space(string(.)), \'%s\')]', $value));
|
||||
assertNotNull($listEl, sprintf(
|
||||
if(null === $listEl) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Chosen.js list element with title "%s" not found',
|
||||
$value
|
||||
));
|
||||
}
|
||||
|
||||
// Dropdown flyout might be animated
|
||||
// $this->getSession()->wait(1000, 'jQuery(":animated").length == 0');
|
||||
$this->getSession()->wait(300);
|
||||
|
||||
$listEl->click();
|
||||
$listEl->find('xpath', './/a')->click();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,37 +5,10 @@ Feature: Manage files
|
||||
So that I can insert them into my content efficiently
|
||||
|
||||
Background:
|
||||
# Idea: We could weave the database reset into this through
|
||||
# saying 'Given there are ONLY the following...'.
|
||||
Given there are the following Folder records
|
||||
"""
|
||||
folder1:
|
||||
Filename: assets/folder1
|
||||
folder1.1:
|
||||
Filename: assets/folder1/folder1.1
|
||||
Parent: =>Folder.folder1
|
||||
folder2:
|
||||
Filename: assets/folder2
|
||||
Name: folder2
|
||||
"""
|
||||
And there are the following File records
|
||||
"""
|
||||
file1:
|
||||
Filename: assets/folder1/file1.jpg
|
||||
Name: file1.jpg
|
||||
Parent: =>Folder.folder1
|
||||
file2:
|
||||
Filename: assets/folder1/folder1.1/file2.jpg
|
||||
Name: file2.jpg
|
||||
Parent: =>Folder.folder1.1
|
||||
"""
|
||||
Given a "file" "assets/folder1/file1.jpg"
|
||||
And a "file" "assets/folder1/folder1.1/file2.jpg"
|
||||
And a "folder" "assets/folder2"
|
||||
And I am logged in with "ADMIN" permissions
|
||||
# Alternative fixture shortcuts, with their titles
|
||||
# as shown in admin/security rather than technical permission codes.
|
||||
# Just an idea for now, could be handled by YAML fixtures as well
|
||||
# And I am logged in with the following permissions
|
||||
# - Access to 'Pages' section
|
||||
# - Access to 'Files' section
|
||||
And I go to "/admin/assets"
|
||||
|
||||
@modal
|
||||
@ -76,7 +49,7 @@ Feature: Manage files
|
||||
Scenario: I can change the folder of a file
|
||||
Given I click on "folder1" in the "Files" table
|
||||
And I click on "file1" in the "folder1" table
|
||||
And I fill in =>Folder.folder2 for "ParentID"
|
||||
And I fill in "folder2" for "ParentID" dropdown
|
||||
And I press the "Save" button
|
||||
# /show/0 is to ensure that we are on top level folder
|
||||
And I go to "/admin/assets/show/0"
|
||||
|
@ -1,48 +1,21 @@
|
||||
@database-defaults
|
||||
@javascript
|
||||
Feature: Manage users
|
||||
As a site administrator
|
||||
I want to create and manage user accounts on my site
|
||||
So that I can control access to the CMS
|
||||
|
||||
Background:
|
||||
Given there are the following Permission records
|
||||
"""
|
||||
admin:
|
||||
Code: ADMIN
|
||||
security-admin:
|
||||
Code: CMS_ACCESS_SecurityAdmin
|
||||
"""
|
||||
And there are the following Group records
|
||||
"""
|
||||
admingroup:
|
||||
Title: Admin Group
|
||||
Code: admin
|
||||
Permissions: =>Permission.admin
|
||||
staffgroup:
|
||||
Title: Staff Group
|
||||
Code: staffgroup
|
||||
"""
|
||||
And there are the following Member records
|
||||
"""
|
||||
admin:
|
||||
FirstName: Admin
|
||||
Email: admin@test.com
|
||||
Groups: =>Group.admingroup
|
||||
staffmember:
|
||||
FirstName: Staff
|
||||
Email: staffmember@test.com
|
||||
Groups: =>Group.staffgroup
|
||||
"""
|
||||
Given a "member" "Admin" belonging to "Admin Group" with "Email"="admin@test.com"
|
||||
And a "member" "Staff" belonging to "Staff Group" with "Email"="staffmember@test.com"
|
||||
And the "group" "Admin Group" has permissions "Full administrative rights"
|
||||
And I am logged in with "ADMIN" permissions
|
||||
And I go to "/admin/security"
|
||||
|
||||
@javascript
|
||||
Scenario: I can list all users regardless of group
|
||||
When I click the "Users" CMS tab
|
||||
Then I should see "admin@test.com" in the "#Root_Users" element
|
||||
And I should see "staffmember@test.com" in the "#Root_Users" element
|
||||
|
||||
@javascript
|
||||
Scenario: I can list all users in a specific group
|
||||
When I click the "Groups" CMS tab
|
||||
# TODO Please check how performant this is
|
||||
@ -50,7 +23,6 @@ Feature: Manage users
|
||||
Then I should see "admin@test.com" in the "#Root_Members" element
|
||||
And I should not see "staffmember@test.com" in the "#Root_Members" element
|
||||
|
||||
@javascript
|
||||
Scenario: I can add a user to the system
|
||||
When I click the "Users" CMS tab
|
||||
And I press the "Add Member" button
|
||||
@ -64,12 +36,10 @@ Feature: Manage users
|
||||
When I go to "admin/security/"
|
||||
Then I should see "john.doe@test.com" in the "#Root_Users" element
|
||||
|
||||
@javascript
|
||||
Scenario: I can edit an existing user and add him to an existing group
|
||||
When I click the "Users" CMS tab
|
||||
And I click "staffmember@test.com" in the "#Root_Users" element
|
||||
And I select "Admin Group" from "Groups"
|
||||
And I additionally select "Administrators" from "Groups"
|
||||
And I press the "Save" button
|
||||
Then I should see a "Saved Member" message
|
||||
|
||||
@ -78,7 +48,6 @@ Feature: Manage users
|
||||
And I click "Admin Group" in the "#Root_Groups" element
|
||||
Then I should see "staffmember@test.com"
|
||||
|
||||
@javascript
|
||||
Scenario: I can delete an existing user
|
||||
When I click the "Users" CMS tab
|
||||
And I click "staffmember@test.com" in the "#Root_Users" element
|
||||
|
@ -1,4 +1,3 @@
|
||||
@database-defaults
|
||||
Feature: My Profile
|
||||
As a CMS user
|
||||
I want to be able to change personal settings
|
||||
|
Loading…
x
Reference in New Issue
Block a user