mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
NEW Support for Behat tests, and initial set of tests
This commit is contained in:
parent
5edf86fe7a
commit
32f829d094
@ -18,5 +18,8 @@
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"composer/installers": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": ["tests/behat/features/bootstrap"]
|
||||
}
|
||||
}
|
@ -63,3 +63,6 @@ We can use string processing on the body of the response to then see if it fits
|
||||
|
||||
If you're testing for natural language responses like error messages, make sure to use [i18n](/topics/i18n) translations through
|
||||
the *_t()* method to avoid tests failing when i18n is enabled.
|
||||
|
||||
Note that for a more highlevel testing approach, SilverStripe also supports
|
||||
[behaviour-driven testing through Behat](https://github.com/silverstripe-labs/silverstripe-behat-extension). It interacts directly with your website or CMS interface by remote controlling an actual browser, driven by natural language assertions.
|
@ -146,6 +146,9 @@ For example, you could have a `phpunit-unit-tests.xml` and `phpunit-functional-t
|
||||
|
||||
**Assertion:** A predicate statement that must be true when a test runs.
|
||||
|
||||
**Behat:** A behaviour-driven testing library used with SilverStripe as a higher-level
|
||||
alternative to the `FunctionalTest` API, see [http://behat.org](http://behat.org).
|
||||
|
||||
**Test Case:** The atomic class type in most unit test frameworks. New unit tests are created by inheriting from the
|
||||
base test case.
|
||||
|
||||
|
1
tests/behat/README.md
Normal file
1
tests/behat/README.md
Normal file
@ -0,0 +1 @@
|
||||
See https://github.com/silverstripe-labs/silverstripe-behat-extension
|
0
tests/behat/_manifest_exclude
Normal file
0
tests/behat/_manifest_exclude
Normal file
38
tests/behat/features/bootstrap/FeatureContext.php
Normal file
38
tests/behat/features/bootstrap/FeatureContext.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Framework\Test\Behaviour;
|
||||
|
||||
use SilverStripe\BehatExtension\Context\SilverStripeContext,
|
||||
SilverStripe\BehatExtension\Context\BasicContext,
|
||||
SilverStripe\BehatExtension\Context\LoginContext,
|
||||
SilverStripe\Framework\Test\Behaviour\CmsFormsContext,
|
||||
SilverStripe\Framework\Test\Behaviour\CmsUiContext;
|
||||
|
||||
// PHPUnit
|
||||
require_once 'PHPUnit/Autoload.php';
|
||||
require_once 'PHPUnit/Framework/Assert/Functions.php';
|
||||
|
||||
/**
|
||||
* Features context
|
||||
*
|
||||
* Context automatically loaded by Behat.
|
||||
* Uses subcontexts to extend functionality.
|
||||
*/
|
||||
class FeatureContext extends SilverStripeContext
|
||||
{
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$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);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Framework\Test\Behaviour;
|
||||
|
||||
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';
|
||||
|
||||
/**
|
||||
* CmsFormsContext
|
||||
*
|
||||
* Context used to define steps related to forms inside CMS.
|
||||
*/
|
||||
class CmsFormsContext extends BehatContext
|
||||
{
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^I should see an edit page form$/
|
||||
*/
|
||||
public function stepIShouldSeeAnEditPageForm()
|
||||
{
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$form = $page->find('css', '#Form_EditForm');
|
||||
assertNotNull($form, 'I should see an edit page form');
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I fill in the content form with "([^"]*)"$/
|
||||
*/
|
||||
public function stepIFillInTheContentFormWith($content)
|
||||
{
|
||||
$this->getSession()->evaluateScript("tinyMCE.get('Form_EditForm_Content').setContent('$content')");
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^the content form should contain "([^"]*)"$/
|
||||
*/
|
||||
public function theContentFormShouldContain($content)
|
||||
{
|
||||
$this->getMainContext()->assertElementContains('#Form_EditForm_Content', $content);
|
||||
}
|
||||
}
|
@ -0,0 +1,256 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Framework\Test\Behaviour;
|
||||
|
||||
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';
|
||||
|
||||
/**
|
||||
* CmsUiContext
|
||||
*
|
||||
* Context used to define steps related to SilverStripe CMS UI like Tree or Panel.
|
||||
*/
|
||||
class CmsUiContext extends BehatContext
|
||||
{
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^I should see the CMS$/
|
||||
*/
|
||||
public function iShouldSeeTheCms()
|
||||
{
|
||||
$page = $this->getSession()->getPage();
|
||||
$cms_element = $page->find('css', '.cms');
|
||||
assertNotNull($cms_element, 'CMS not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^I should see a "([^"]*)" notice$/
|
||||
*/
|
||||
public function iShouldSeeANotice($notice)
|
||||
{
|
||||
$this->getMainContext()->assertElementContains('.notice-wrap', $notice);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^I should see a "([^"]*)" message$/
|
||||
*/
|
||||
public function iShouldSeeAMessage($message)
|
||||
{
|
||||
$this->getMainContext()->assertElementContains('.message', $message);
|
||||
}
|
||||
|
||||
protected function getCmsTabsElement()
|
||||
{
|
||||
$this->getSession()->wait(5000, "window.jQuery('.cms-content-header-tabs').size() > 0");
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
$cms_content_header_tabs = $page->find('css', '.cms-content-header-tabs');
|
||||
assertNotNull($cms_content_header_tabs, 'CMS tabs not found');
|
||||
|
||||
return $cms_content_header_tabs;
|
||||
}
|
||||
|
||||
protected function getCmsContentToolbarElement()
|
||||
{
|
||||
$this->getSession()->wait(
|
||||
5000,
|
||||
"window.jQuery('.cms-content-toolbar').size() > 0 "
|
||||
. "&& window.jQuery('.cms-content-toolbar').children().size() > 0"
|
||||
);
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
$cms_content_toolbar_element = $page->find('css', '.cms-content-toolbar');
|
||||
assertNotNull($cms_content_toolbar_element, 'CMS content toolbar not found');
|
||||
|
||||
return $cms_content_toolbar_element;
|
||||
}
|
||||
|
||||
protected function getCmsTreeElement()
|
||||
{
|
||||
$this->getSession()->wait(5000, "window.jQuery('.cms-tree').size() > 0");
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
$cms_tree_element = $page->find('css', '.cms-tree');
|
||||
assertNotNull($cms_tree_element, 'CMS tree not found');
|
||||
|
||||
return $cms_tree_element;
|
||||
}
|
||||
|
||||
protected function getGridfieldTable($title)
|
||||
{
|
||||
$page = $this->getSession()->getPage();
|
||||
$table_elements = $page->findAll('css', '.ss-gridfield-table');
|
||||
assertNotNull($table_elements, 'Table elements not found');
|
||||
|
||||
$table_element = null;
|
||||
foreach ($table_elements as $table) {
|
||||
$table_title_element = $table->find('css', '.title');
|
||||
if ($table_title_element->getText() === $title) {
|
||||
$table_element = $table;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertNotNull($table_element, sprintf('Table `%s` not found', $title));
|
||||
|
||||
return $table_element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^I should see a "([^"]*)" button in CMS Content Toolbar$/
|
||||
*/
|
||||
public function iShouldSeeAButtonInCmsContentToolbar($text)
|
||||
{
|
||||
$cms_content_toolbar_element = $this->getCmsContentToolbarElement();
|
||||
|
||||
$element = $cms_content_toolbar_element->find('named', array('link_or_button', "'$text'"));
|
||||
assertNotNull($element, sprintf('%s button not found', $text));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I should see "([^"]*)" in CMS Tree$/
|
||||
*/
|
||||
public function stepIShouldSeeInCmsTree($text)
|
||||
{
|
||||
$cms_tree_element = $this->getCmsTreeElement();
|
||||
|
||||
$element = $cms_tree_element->find('named', array('content', "'$text'"));
|
||||
assertNotNull($element, sprintf('%s not found', $text));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I should not see "([^"]*)" in CMS Tree$/
|
||||
*/
|
||||
public function stepIShouldNotSeeInCmsTree($text)
|
||||
{
|
||||
$cms_tree_element = $this->getCmsTreeElement();
|
||||
|
||||
$element = $cms_tree_element->find('named', array('content', "'$text'"));
|
||||
assertNull($element, sprintf('%s found', $text));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I expand the "([^"]*)" CMS Panel$/
|
||||
*/
|
||||
public function iExpandTheCmsPanel()
|
||||
{
|
||||
// TODO Make dynamic, currently hardcoded to first panel
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$panel_toggle_element = $page->find('css', '.cms-content > .cms-panel > .cms-panel-toggle > .toggle-expand');
|
||||
assertNotNull($panel_toggle_element, 'Panel toggle not found');
|
||||
|
||||
if ($panel_toggle_element->isVisible()) {
|
||||
$panel_toggle_element->click();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I click the "([^"]*)" CMS tab$/
|
||||
*/
|
||||
public function iClickTheCmsTab($tab)
|
||||
{
|
||||
$cms_tabs_element = $this->getCmsTabsElement();
|
||||
|
||||
$tab_element = $cms_tabs_element->find('named', array('link_or_button', "'$tab'"));
|
||||
assertNotNull($tab_element, sprintf('%s tab not found', $tab));
|
||||
|
||||
$tab_element->click();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^the "([^"]*)" table should contain "([^"]*)"$/
|
||||
*/
|
||||
public function theTableShouldContain($table, $text)
|
||||
{
|
||||
$table_element = $this->getGridfieldTable($table);
|
||||
var_dump($table_element);
|
||||
$element = $table_element->find('named', array('content', "'$text'"));
|
||||
assertNotNull($element, sprintf('Element containing `%s` not found in `%s` table', $text, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^the "([^"]*)" table should not contain "([^"]*)"$/
|
||||
*/
|
||||
public function theTableShouldNotContain($table, $text)
|
||||
{
|
||||
$table_element = $this->getGridfieldTable($table);
|
||||
|
||||
$element = $table_element->find('named', array('content', "'$text'"));
|
||||
assertNull($element, sprintf('Element containing `%s` not found in `%s` table', $text, $table));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^I click on "([^"]*)" in the "([^"]*)" table$/
|
||||
*/
|
||||
public function iClickOnInTheTable($text, $table)
|
||||
{
|
||||
$table_element = $this->getGridfieldTable($table);
|
||||
|
||||
$element = $table_element->find('xpath', sprintf('//*[count(*)=0 and contains(.,"%s")]', $text));
|
||||
assertNotNull($element, sprintf('Element containing `%s` not found', $text));
|
||||
$element->click();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^I can see the preview panel$/
|
||||
*/
|
||||
public function iCanSeeThePreviewPanel()
|
||||
{
|
||||
$this->getMainContext()->assertElementOnPage('.cms-preview');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^the preview contains "([^"]*)"$/
|
||||
*/
|
||||
public function thePreviewContains($content)
|
||||
{
|
||||
$driver = $this->getSession()->getDriver();
|
||||
$driver->switchToIFrame('cms-preview-iframe');
|
||||
|
||||
$this->getMainContext()->assertPageContainsText($content);
|
||||
$driver->switchToWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^the preview does not contain "([^"]*)"$/
|
||||
*/
|
||||
public function thePreviewDoesNotContain($content)
|
||||
{
|
||||
$driver = $this->getSession()->getDriver();
|
||||
$driver->switchToIFrame('cms-preview-iframe');
|
||||
|
||||
$this->getMainContext()->assertPageNotContainsText($content);
|
||||
$driver->switchToWindow();
|
||||
}
|
||||
}
|
BIN
tests/behat/features/files/file1.jpg
Normal file
BIN
tests/behat/features/files/file1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
tests/behat/features/files/file2.jpg
Normal file
BIN
tests/behat/features/files/file2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
tests/behat/features/files/testfile.jpg
Normal file
BIN
tests/behat/features/files/testfile.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
20
tests/behat/features/login.feature
Normal file
20
tests/behat/features/login.feature
Normal file
@ -0,0 +1,20 @@
|
||||
# features/login.feature
|
||||
Feature: Log in
|
||||
As an site owner
|
||||
I want to access to the CMS to be secure
|
||||
So that only my team can make content changes
|
||||
|
||||
Scenario: Bad login
|
||||
Given I log in with "bad@example.com" and "badpassword"
|
||||
Then I will see a bad log-in message
|
||||
|
||||
Scenario: Valid login
|
||||
Given I am logged in with "ADMIN" permissions
|
||||
When I go to "/admin/"
|
||||
Then I should see the CMS
|
||||
|
||||
Scenario: /admin/ redirect for not logged in user
|
||||
# disable automatic redirection so we can use the profiler
|
||||
When I go to "/admin/" without redirection
|
||||
Then I should be redirected to "/Security/login"
|
||||
And I should see a log-in form
|
84
tests/behat/features/manage-files.feature
Normal file
84
tests/behat/features/manage-files.feature
Normal file
@ -0,0 +1,84 @@
|
||||
@javascript @assets
|
||||
Feature: Manage files
|
||||
As a cms author
|
||||
I want to upload and manage files within the CMS
|
||||
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
|
||||
"""
|
||||
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
|
||||
Scenario: I can add a new folder
|
||||
Given I press the "Add folder" button
|
||||
And I type "newfolder" into the dialog
|
||||
And I confirm the dialog
|
||||
Then the "Files" table should contain "newfolder"
|
||||
|
||||
Scenario: I can list files in a folder
|
||||
Given I click on "folder1" in the "Files" table
|
||||
Then the "folder1" table should contain "file1"
|
||||
And the "folder1" table should not contain "file1.1"
|
||||
|
||||
Scenario: I can upload a file to a folder
|
||||
Given I click on "folder1" in the "Files" table
|
||||
And I press the "Upload" button
|
||||
And I attach the file "testfile.jpg" to "AssetUploadField" with HTML5
|
||||
And I wait for 5 seconds
|
||||
And I press the "Back to folder" button
|
||||
Then the "folder1" table should contain "testfile"
|
||||
|
||||
Scenario: I can edit a file
|
||||
Given I click on "folder1" in the "Files" table
|
||||
And I click on "file1" in the "folder1" table
|
||||
And I fill in "renamedfile" for "Title"
|
||||
And I press the "Save" button
|
||||
And I press the "Back" button
|
||||
Then the "folder1" table should not contain "testfile"
|
||||
And the "folder1" table should contain "renamedfile"
|
||||
|
||||
Scenario: I can delete a file
|
||||
Given I click on "folder1" in the "Files" table
|
||||
And I click on "file1" in the "folder1" table
|
||||
And I press the "Delete" button
|
||||
Then the "folder1" table should not contain "file1"
|
||||
|
||||
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 press the "Save" button
|
||||
# /show/0 is to ensure that we are on top level folder
|
||||
And I go to "/admin/assets/show/0"
|
||||
And I click on "folder2" in the "Files" table
|
||||
And the "folder2" table should contain "file1"
|
87
tests/behat/features/manage-users.feature
Normal file
87
tests/behat/features/manage-users.feature
Normal file
@ -0,0 +1,87 @@
|
||||
@database-defaults
|
||||
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
|
||||
"""
|
||||
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
|
||||
And I click "Admin Group" in the "#Root_Groups" element
|
||||
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
|
||||
And I fill in the following:
|
||||
| First Name | John |
|
||||
| Surname | Doe |
|
||||
| Email | john.doe@test.com |
|
||||
And I press the "Create" button
|
||||
Then I should see a "Saved member" message
|
||||
|
||||
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
|
||||
|
||||
When I go to "admin/security"
|
||||
And I click the "Groups" CMS tab
|
||||
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
|
||||
And I press the "Delete" button
|
||||
Then I should see "admin@test.com"
|
||||
And I should not see "staffmember@test.com"
|
Loading…
Reference in New Issue
Block a user