silverstripe-framework/tests/behat/features/bootstrap/SilverStripe/Framework/Test/Behaviour/CmsFormsContext.php

298 lines
8.6 KiB
PHP
Raw Normal View History

<?php
namespace SilverStripe\Framework\Test\Behaviour;
2016-01-25 16:17:57 +01:00
use Behat\Behat\Context\ClosuredContextInterface;
use Behat\Behat\Context\TranslatedContextInterface;
use Behat\Behat\Context\BehatContext;
use Behat\Behat\Context\Step;
use Behat\Behat\Exception\PendingException;
use Behat\Mink\Exception\ElementHtmlException;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext as MinkContext;
2013-09-15 01:50:10 +02:00
use Symfony\Component\DomCrawler\Crawler;
2016-11-29 13:45:41 +01:00
use Behat\Mink\Element\NodeElement;
use SilverStripe\SiteConfig\SiteConfig;
2013-09-15 01:50:10 +02:00
/**
* 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);
}
/**
* Returns fixed step argument (with \\" replaced back to ").
* Copied from {@see MinkContext}
*
* @param string $argument
* @return string
*/
protected function fixStepArgument($argument) {
return str_replace('\\"', '"', $argument);
}
/**
2013-12-02 18:35:21 +01:00
* @Then /^I should( not? |\s*)see an edit page form$/
*/
2013-12-02 18:35:21 +01:00
public function stepIShouldSeeAnEditPageForm($negative) {
$page = $this->getSession()->getPage();
$form = $page->find('css', '#Form_EditForm');
2013-12-02 18:35:21 +01:00
if(trim($negative)) {
assertNull($form, 'I should not see an edit page form');
} else {
2014-08-15 08:53:05 +02:00
assertNotNull($form, 'I should see an edit page form');
2013-12-02 18:35:21 +01:00
}
}
/**
2014-09-12 05:09:12 +02:00
* @When /^I fill in the "(?P<field>(?:[^"]|\\")*)" HTML field with "(?P<value>(?:[^"]|\\")*)"$/
* @When /^I fill in "(?P<value>(?:[^"]|\\")*)" for the "(?P<field>(?:[^"]|\\")*)" HTML field$/
*/
public function stepIFillInTheHtmlFieldWith($field, $value) {
$inputField = $this->getHtmlField($field);
$value = $this->fixStepArgument($value);
2014-09-12 05:09:12 +02:00
$this->getSession()->evaluateScript(sprintf(
"jQuery('#%s').entwine('ss').getEditor().setContent('%s')",
$inputField->getAttribute('id'),
addcslashes($value, "'")
));
}
/**
2014-09-12 05:09:12 +02:00
* @When /^I append "(?P<value>(?:[^"]|\\")*)" to the "(?P<field>(?:[^"]|\\")*)" HTML field$/
*/
public function stepIAppendTotheHtmlField($field, $value) {
$inputField = $this->getHtmlField($field);
$value = $this->fixStepArgument($value);
2014-09-12 05:09:12 +02:00
$this->getSession()->evaluateScript(sprintf(
"jQuery('#%s').entwine('ss').getEditor().insertContent('%s')",
$inputField->getAttribute('id'),
addcslashes($value, "'")
));
}
/**
2014-09-12 05:09:12 +02:00
* @Then /^the "(?P<locator>(?:[^"]|\\")*)" HTML field should(?P<negative> not? |\s*)contain "(?P<html>.*)"$/
*/
public function theHtmlFieldShouldContain($locator, $negative, $html) {
$element = $this->getHtmlField($locator);
$actual = $element->getValue();
$regex = '/'.preg_quote($html, '/').'/ui';
$failed = false;
if(trim($negative)) {
if (preg_match($regex, $actual)) {
$failed = true;
}
} else {
if (!preg_match($regex, $actual)) {
$failed = true;
}
}
if($failed) {
$message = sprintf(
'The string "%s" should%sbe found in the HTML of the element matching name "%s". Actual content: "%s"',
$html,
$negative,
$locator,
$actual
);
throw new ElementHtmlException($message, $this->getSession(), $element);
}
}
2013-04-09 09:39:06 +02:00
2014-03-30 08:51:38 +02:00
// @codingStandardsIgnoreStart
2013-09-15 01:50:10 +02:00
/**
* Checks formatting in the HTML field, by analyzing the HTML node surrounding
* the text for certain properties.
2014-08-15 08:53:05 +02:00
*
2013-09-15 01:50:10 +02:00
* Example: Given "my text" in the "Content" HTML field should be right aligned
* Example: Given "my text" in the "Content" HTML field should not be bold
*
* @todo Use an actual DOM parser for more accurate assertions
2014-08-15 08:53:05 +02:00
*
2014-09-12 05:09:12 +02:00
* @Given /^"(?P<text>([^"]*))" in the "(?P<field>(?:[^"]|\\")*)" HTML field should(?P<negate>(?: not)?) be (?P<formatting>(.*))$/
2013-09-15 01:50:10 +02:00
*/
public function stepContentInHtmlFieldShouldHaveFormatting($text, $field, $negate, $formatting) {
$inputField = $this->getHtmlField($field);
2013-09-15 01:50:10 +02:00
$crawler = new Crawler($inputField->getValue());
$matchedNode = null;
foreach($crawler->filterXPath('//*') as $node) {
if(
$node->firstChild
&& $node->firstChild->nodeType == XML_TEXT_NODE
&& stripos($node->firstChild->nodeValue, $text) !== FALSE
) {
$matchedNode = $node;
}
}
assertNotNull($matchedNode);
$assertFn = $negate ? 'assertNotEquals' : 'assertEquals';
if($formatting == 'bold') {
call_user_func($assertFn, 'strong', $matchedNode->nodeName);
} else if($formatting == 'left aligned') {
if($matchedNode->getAttribute('style')) {
2014-08-15 08:53:05 +02:00
call_user_func($assertFn, 'text-align: left;', $matchedNode->getAttribute('style'));
2013-09-15 01:50:10 +02:00
}
} else if($formatting == 'right aligned') {
2014-08-15 08:53:05 +02:00
call_user_func($assertFn, 'text-align: right;', $matchedNode->getAttribute('style'));
2013-09-15 01:50:10 +02:00
}
}
2014-03-30 08:51:38 +02:00
// @codingStandardsIgnoreEnd
2013-09-15 01:50:10 +02:00
2013-09-14 18:32:29 +02:00
/**
* Selects the first textual match in the HTML editor. Does not support
* selection across DOM node boundaries.
2014-08-15 08:53:05 +02:00
*
2014-09-12 05:09:12 +02:00
* @When /^I select "(?P<text>([^"]*))" in the "(?P<field>(?:[^"]|\\")*)" HTML field$/
2013-09-14 18:32:29 +02:00
*/
public function stepIHighlightTextInHtmlField($text, $field) {
$inputField = $this->getHtmlField($field);
2013-09-14 18:32:29 +02:00
$inputFieldId = $inputField->getAttribute('id');
$text = addcslashes($text, "'");
$js = <<<JS
// TODO <IE9 support
// TODO Allow text matches across nodes
2014-08-15 08:53:05 +02:00
var editor = jQuery('#$inputFieldId').entwine('ss').getEditor(),
doc = editor.getInstance().getDoc(),
2013-09-14 18:32:29 +02:00
sel = editor.getInstance().selection,
rng = document.createRange(),
matched = false;
2013-09-14 18:32:29 +02:00
jQuery(doc).find('body *').each(function() {
if(!matched) {
for(var i=0;i<this.childNodes.length;i++) {
if(!matched && this.childNodes[i].nodeValue && this.childNodes[i].nodeValue.match('$text')) {
rng.setStart(this.childNodes[i], this.childNodes[i].nodeValue.indexOf('$text'));
rng.setEnd(this.childNodes[i], this.childNodes[i].nodeValue.indexOf('$text') + '$text'.length);
sel.setRng(rng);
editor.getInstance().nodeChanged();
matched = true;
break;
}
}
2013-09-14 18:32:29 +02:00
}
});
JS;
$this->getSession()->executeScript($js);
2014-08-15 08:53:05 +02:00
}
2013-09-14 18:32:29 +02:00
2013-04-09 09:39:06 +02:00
/**
2013-12-02 18:35:21 +01:00
* Example: I should see a "Submit" button
* Example: I should not see a "Delete" button
2014-08-15 08:53:05 +02:00
*
2013-12-02 18:35:21 +01:00
* @Given /^I should( not? |\s*)see a "([^"]*)" button$/
2013-04-09 09:39:06 +02:00
*/
2013-12-02 18:35:21 +01:00
public function iShouldSeeAButton($negative, $text) {
2013-04-09 09:39:06 +02:00
$page = $this->getSession()->getPage();
$els = $page->findAll('named', array('link_or_button', "'$text'"));
$matchedEl = null;
foreach($els as $el) {
if($el->isVisible()) $matchedEl = $el;
}
2013-12-02 18:35:21 +01:00
if(trim($negative)) {
2014-08-15 08:53:05 +02:00
assertNull($matchedEl, sprintf('%s button found', $text));
2013-12-02 18:35:21 +01:00
} else {
assertNotNull($matchedEl, sprintf('%s button not found', $text));
}
2013-04-09 09:39:06 +02:00
}
/**
2013-12-02 18:35:21 +01:00
* @Given /^I should( not? |\s*)see a "([^"]*)" field$/
*/
2013-12-02 18:35:21 +01:00
public function iShouldSeeAField($negative, $text) {
$page = $this->getSession()->getPage();
2013-12-02 18:35:21 +01:00
$els = $page->findAll('named', array('field', "'$text'"));
$matchedEl = null;
foreach($els as $el) {
if($el->isVisible()) $matchedEl = $el;
}
2013-12-02 18:35:21 +01:00
if(trim($negative)) {
assertNull($matchedEl);
} else {
assertNotNull($matchedEl);
}
}
/**
* Click on the element with the provided CSS Selector
*
* @When /^I press the "([^"]*)" HTML field button$/
*/
public function iClickOnTheHtmlFieldButton($button)
{
$xpath = "//*[@aria-label='".$button."']";
$session = $this->getSession();
$element = $session->getPage()->find('xpath', $xpath);
if (null === $element) {
throw new \InvalidArgumentException(sprintf('Could not find element with xpath %s', $xpath));
}
$element->click();
}
Merge 3 into master # Conflicts: # .travis.yml # admin/css/ie7.css # admin/css/ie7.css.map # admin/css/ie8.css.map # admin/css/screen.css # admin/css/screen.css.map # admin/javascript/LeftAndMain.js # admin/scss/_style.scss # admin/scss/_uitheme.scss # control/HTTPRequest.php # core/Object.php # css/AssetUploadField.css # css/AssetUploadField.css.map # css/ConfirmedPasswordField.css.map # css/Form.css.map # css/GridField.css.map # css/TreeDropdownField.css.map # css/UploadField.css # css/UploadField.css.map # css/debug.css.map # dev/Debug.php # docs/en/00_Getting_Started/00_Server_Requirements.md # docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md # docs/en/02_Developer_Guides/06_Testing/index.md # docs/en/02_Developer_Guides/14_Files/02_Images.md # docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/How_Tos/Extend_CMS_Interface.md # filesystem/File.php # filesystem/Folder.php # filesystem/GD.php # filesystem/Upload.php # forms/ToggleField.php # forms/Validator.php # javascript/lang/en_GB.js # javascript/lang/fr.js # javascript/lang/src/en.js # javascript/lang/src/fr.js # model/Image.php # model/UnsavedRelationList.php # model/Versioned.php # model/connect/MySQLDatabase.php # model/fieldtypes/DBField.php # model/fieldtypes/Enum.php # scss/AssetUploadField.scss # scss/UploadField.scss # templates/email/ChangePasswordEmail.ss # templates/forms/DropdownField.ss # tests/behat/features/bootstrap/SilverStripe/Framework/Test/Behaviour/CmsFormsContext.php # tests/behat/features/bootstrap/SilverStripe/Framework/Test/Behaviour/CmsUiContext.php # tests/forms/EnumFieldTest.php # tests/security/MemberTest.php # tests/security/MemberTest.yml # tests/security/SecurityTest.php
2016-04-29 07:50:55 +02:00
/*
2014-11-13 05:42:14 +01:00
* @example Given the CMS settings has the following data
* | Title | My site title |
* | Theme | My site theme |
* @Given /^the CMS settings have the following data$/
*/
public function theCmsSettingsHasData(TableNode $fieldsTable) {
$fields = $fieldsTable->getRowsHash();
$siteConfig = SiteConfig::get()->first();
2014-11-13 05:42:14 +01:00
foreach($fields as $field => $value) {
$siteConfig->$field = $value;
}
$siteConfig->write();
$siteConfig->flushCache();
}
2016-11-29 12:39:58 +01:00
/**
* Locate an HTML editor field
*
* @param string $locator Raw html field identifier as passed from
* @return NodeElement
*/
protected function getHtmlField($locator)
{
$locator = $this->fixStepArgument($locator);
$page = $this->getSession()->getPage();
$element = $page->find('css', 'textarea.htmleditor[name=\'' . $locator . '\']');
assertNotNull($element, sprintf('HTML field "%s" not found', $locator));
return $element;
}
}