mirror of
https://github.com/silverstripe/silverstripe-behat-extension
synced 2024-06-17 02:01:47 +02:00
Merge c424b5f1fa
into 2a1e1e29d6
This commit is contained in:
commit
3ab1e93786
|
@ -3,9 +3,8 @@ language: php
|
|||
sudo: false
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
|
||||
script:
|
||||
- vendor/bin/phpunit tests
|
||||
|
|
16
README.md
16
README.md
|
@ -92,6 +92,10 @@ Now you can run the tests (for example for the `framework` module):
|
|||
In order to run specific tests only, use their feature file name:
|
||||
|
||||
vendor/bin/behat @framework/login.feature
|
||||
|
||||
Or even run a single scenario by it's name (supports regular expressions):
|
||||
|
||||
vendor/bin/behat --name 'My scenario title' @framework
|
||||
|
||||
This will start a Firefox browser by default. Other browsers and profiles can be configured in `behat.yml`.
|
||||
|
||||
|
@ -580,13 +584,17 @@ It's based on the `vendor/bin/behat -di @cms` output.
|
|||
|
||||
Given /^I press the "([^"]*)" button$/
|
||||
|
||||
Given /^I click "([^"]*)" in the "([^"]*)" element$/
|
||||
Given /^I (click|double click) "([^"]*)" in the "([^"]*)" element$/
|
||||
|
||||
Given /^I type "([^"]*)" into the dialog$/
|
||||
|
||||
Given /^I (?:press|follow) the "([^"]*)" (?:button|link), confirming the dialog$/
|
||||
|
||||
Given /^I (?:press|follow) the "([^"]*)" (?:button|link), dismissing the dialog$/
|
||||
|
||||
Given /^I (click|double click) "([^"]*)" in the "([^"]*)" element, confirming the dialog$/
|
||||
|
||||
Given /^I (click|double click) "([^"]*)" in the "([^"]*)" element, dismissing the dialog$/
|
||||
|
||||
Given /^I confirm the dialog$/
|
||||
|
||||
|
@ -701,6 +709,12 @@ It's based on the `vendor/bin/behat -di @cms` output.
|
|||
Then /^the email should (not |)contain the following data:$/
|
||||
Example: Then the email should contain the following data:
|
||||
|
||||
Then /^there should (not |)be an email titled "([^"]*)"$/
|
||||
|
||||
Then /^the email should (not |)be sent from "([^"]*)"$/
|
||||
|
||||
Then /^the email should (not |)be sent to "([^"]*)"$/
|
||||
|
||||
### Transformations
|
||||
|
||||
Behat [transformations](http://docs.behat.org/guides/2.definitions.html#step-argument-transformations)
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
"symfony/yaml": "~2.0",
|
||||
"symfony/finder": "~2.0",
|
||||
"silverstripe/testsession": "*",
|
||||
"silverstripe/framework": ">=3.1.0"
|
||||
"silverstripe/framework": "^4.0.0"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
|
@ -50,5 +50,10 @@
|
|||
"vendor/phpunit/phpunit"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ If you would like to run Behat Tests using Google Chrome here are a few steps I
|
|||
```
|
||||
default_session: selenium2
|
||||
javascript_session: selenium2
|
||||
goutte: ~
|
||||
selenium2:
|
||||
browser: chrome
|
||||
SilverStripe\BehatExtension\Extension:
|
||||
|
@ -27,4 +26,4 @@ java -jar selenium-server.jar -Dwebdriver.chrome.driver="/path/to/chromedriver"
|
|||
|
||||
```
|
||||
behat @mysite --profile=chrome
|
||||
```
|
||||
```
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
|
||||
namespace SilverStripe\BehatExtension\Context;
|
||||
|
||||
use Behat\Behat\Context\ClosuredContextInterface,
|
||||
Behat\Behat\Context\TranslatedContextInterface,
|
||||
Behat\Behat\Context\BehatContext,
|
||||
use Behat\Behat\Context\BehatContext,
|
||||
Behat\Behat\Context\Step,
|
||||
Behat\Behat\Event\StepEvent,
|
||||
Behat\Behat\Event\ScenarioEvent,
|
||||
Behat\Behat\Exception\PendingException;
|
||||
Behat\Behat\Event\ScenarioEvent;
|
||||
|
||||
use Behat\Mink\Driver\Selenium2Driver;
|
||||
|
||||
|
@ -268,8 +265,9 @@ JS;
|
|||
*/
|
||||
public function cleanAssetsAfterScenario(ScenarioEvent $event) {
|
||||
foreach(\File::get() as $file) {
|
||||
if(file_exists($file->getFullPath())) $file->delete();
|
||||
$file->delete();
|
||||
}
|
||||
\Filesystem::removeFolder(ASSETS_PATH, true);
|
||||
}
|
||||
|
||||
public function takeScreenshot(StepEvent $event) {
|
||||
|
@ -383,19 +381,42 @@ JS;
|
|||
}
|
||||
|
||||
/**
|
||||
* @Given /^I click "([^"]*)" in the "([^"]*)" element$/
|
||||
* @Given /^I (click|double click) "([^"]*)" in the "([^"]*)" element$/
|
||||
*/
|
||||
public function iClickInTheElement($text, $selector) {
|
||||
public function iClickInTheElement($clickType, $text, $selector) {
|
||||
$clickTypeMap = array(
|
||||
"double click" => "doubleclick",
|
||||
"click" => "click"
|
||||
);
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$parentElement = $page->find('css', $selector);
|
||||
assertNotNull($parentElement, sprintf('"%s" element not found', $selector));
|
||||
|
||||
$element = $parentElement->find('xpath', sprintf('//*[count(*)=0 and contains(.,"%s")]', $text));
|
||||
assertNotNull($element, sprintf('"%s" not found', $text));
|
||||
|
||||
$element->click();
|
||||
$clickTypeFn = $clickTypeMap[$clickType];
|
||||
$element->$clickTypeFn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Needs to be in single command to avoid "unexpected alert open" errors in Selenium.
|
||||
* Example: I click "Delete" in the ".actions" element, confirming the dialog
|
||||
*
|
||||
* @Given /^I (click|double click) "([^"]*)" in the "([^"]*)" element, confirming the dialog$/
|
||||
*/
|
||||
public function iClickInTheElementConfirmingTheDialog($clickType, $text, $selector) {
|
||||
$this->iClickInTheElement($clickType, $text, $selector);
|
||||
$this->iConfirmTheDialog();
|
||||
}
|
||||
/**
|
||||
* Needs to be in single command to avoid "unexpected alert open" errors in Selenium.
|
||||
* Example: I click "Delete" in the ".actions" element, dismissing the dialog
|
||||
*
|
||||
* @Given /^I (click|double click) "([^"]*)" in the "([^"]*)" element, dismissing the dialog$/
|
||||
*/
|
||||
public function iClickInTheElementDismissingTheDialog($clickType, $text, $selector) {
|
||||
$this->iClickInTheElement($clickType, $text, $selector);
|
||||
$this->iDismissTheDialog();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^I type "([^"]*)" into the dialog$/
|
||||
|
|
|
@ -134,6 +134,28 @@ class EmailContext extends BehatContext
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Given the email contains "Thank you for <strong>registering!<strong>".
|
||||
* Then the email should contain plain text "Thank you for registering!"
|
||||
* Assumes an email has been identified by a previous step,
|
||||
* e.g. through 'Given there should be an email to "test@test.com"'.
|
||||
*
|
||||
* @Given /^the email should contain plain text "([^"]*)"$/
|
||||
*/
|
||||
public function thereTheEmailContainsPlainText($content)
|
||||
{
|
||||
if(!$this->lastMatchedEmail) {
|
||||
throw new \LogicException('No matched email found from previous step');
|
||||
}
|
||||
|
||||
$email = $this->lastMatchedEmail;
|
||||
$emailContent = ($email->Content) ? ($email->Content) : ($email->PlainContent);
|
||||
$emailPlainText = strip_tags($emailContent);
|
||||
$emailPlainText = preg_replace("/\h+/", " ", $emailPlainText);
|
||||
|
||||
assertContains($content, $emailPlainText);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I click on the "([^"]*)" link in the email (to|from) "([^"]*)"$/
|
||||
*/
|
||||
|
@ -223,6 +245,7 @@ class EmailContext extends BehatContext
|
|||
}
|
||||
// Convert html content to plain text
|
||||
$emailContent = strip_tags($emailContent);
|
||||
$emailContent = preg_replace("/\h+/", " ", $emailContent);
|
||||
$rows = $table->getRows();
|
||||
|
||||
// For "should not contain"
|
||||
|
@ -236,4 +259,56 @@ class EmailContext extends BehatContext
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^there should (not |)be an email titled "([^"]*)"$/
|
||||
*/
|
||||
public function thereIsAnEmailTitled($negate, $subject)
|
||||
{
|
||||
$match = $this->mailer->findEmail(null, null, $subject);
|
||||
if(trim($negate)) {
|
||||
assertNull($match);
|
||||
} else {
|
||||
$msg = sprintf(
|
||||
'Could not find email titled "%s".',
|
||||
$subject
|
||||
);
|
||||
assertNotNull($match,$msg);
|
||||
}
|
||||
$this->lastMatchedEmail = $match;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^the email should (not |)be sent from "([^"]*)"$/
|
||||
*/
|
||||
public function theEmailSentFrom($negate, $from)
|
||||
{
|
||||
if(!$this->lastMatchedEmail) {
|
||||
throw new \LogicException('No matched email found from previous step');
|
||||
}
|
||||
|
||||
$match = $this->lastMatchedEmail;
|
||||
if(trim($negate)) {
|
||||
assertNotContains($from, $match->From);
|
||||
} else {
|
||||
assertContains($from, $match->From);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^the email should (not |)be sent to "([^"]*)"$/
|
||||
*/
|
||||
public function theEmailSentTo($negate, $to)
|
||||
{
|
||||
if(!$this->lastMatchedEmail) {
|
||||
throw new \LogicException('No matched email found from previous step');
|
||||
}
|
||||
|
||||
$match = $this->lastMatchedEmail;
|
||||
if(trim($negate)) {
|
||||
assertNotContains($to, $match->To);
|
||||
} else {
|
||||
assertContains($to, $match->To);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,11 @@
|
|||
|
||||
namespace SilverStripe\BehatExtension\Context;
|
||||
|
||||
use Behat\Behat\Context\ClosuredContextInterface,
|
||||
Behat\Behat\Context\TranslatedContextInterface,
|
||||
Behat\Behat\Context\BehatContext,
|
||||
Behat\Behat\Context\Step,
|
||||
Behat\Behat\Event\StepEvent,
|
||||
Behat\Behat\Event\FeatureEvent,
|
||||
use Behat\Behat\Context\BehatContext,
|
||||
Behat\Behat\Event\ScenarioEvent,
|
||||
Behat\Behat\Exception\PendingException,
|
||||
Behat\Mink\Driver\Selenium2Driver,
|
||||
Behat\Gherkin\Node\PyStringNode,
|
||||
Behat\Gherkin\Node\TableNode;
|
||||
Behat\Gherkin\Node\TableNode,
|
||||
SilverStripe\Filesystem\Storage\AssetStore;
|
||||
|
||||
// PHPUnit
|
||||
require_once 'PHPUnit/Autoload.php';
|
||||
|
@ -548,14 +542,17 @@ class FixtureContext extends BehatContext
|
|||
protected function prepareAsset($class, $identifier, $data = null) {
|
||||
if(!$data) $data = array();
|
||||
$relativeTargetPath = (isset($data['Filename'])) ? $data['Filename'] : $identifier;
|
||||
$relativeTargetPath = preg_replace('/^' . ASSETS_DIR . '/', '', $relativeTargetPath);
|
||||
$targetPath = $this->joinPaths(ASSETS_PATH, $relativeTargetPath);
|
||||
$relativeTargetPath = preg_replace('/^' . ASSETS_DIR . '\/?/', '', $relativeTargetPath);
|
||||
$sourcePath = $this->joinPaths($this->getFilesPath(), basename($relativeTargetPath));
|
||||
|
||||
// Create file or folder on filesystem
|
||||
$parent = null;
|
||||
if($class == 'Folder' || is_subclass_of($class, 'Folder')) {
|
||||
$parent = \Folder::find_or_make($relativeTargetPath);
|
||||
$targetPath = $this->joinPaths(ASSETS_PATH, $relativeTargetPath);
|
||||
$data['ID'] = $parent->ID;
|
||||
} else {
|
||||
$parent = \Folder::find_or_make(dirname($relativeTargetPath));
|
||||
if(!file_exists($sourcePath)) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Source file for "%s" cannot be found in "%s"',
|
||||
|
@ -563,18 +560,41 @@ class FixtureContext extends BehatContext
|
|||
$sourcePath
|
||||
));
|
||||
}
|
||||
$parent = \Folder::find_or_make(dirname($relativeTargetPath));
|
||||
copy($sourcePath, $targetPath);
|
||||
$data['ParentID'] = $parent->ID;
|
||||
|
||||
// Load file into APL and retrieve tuple
|
||||
$asset = $this->getAssetStore()->setFromLocalFile(
|
||||
$sourcePath,
|
||||
$relativeTargetPath,
|
||||
null,
|
||||
null,
|
||||
AssetStore::CONFLICT_OVERWRITE
|
||||
);
|
||||
$data['FileFilename'] = $asset['Filename'];
|
||||
$data['FileHash'] = $asset['Hash'];
|
||||
$data['FileVariant'] = $asset['Variant'];
|
||||
|
||||
// Strip base from url to get dir relative to base
|
||||
$url = $this->getAssetStore()->getAsURL($asset['Filename'], $asset['Hash'], $asset['Variant']);
|
||||
$targetPath = $this->joinPaths(BASE_PATH, substr($url, strlen(\Director::baseURL())));
|
||||
}
|
||||
if(!isset($data['Name'])) {
|
||||
$data['Name'] = basename($relativeTargetPath);
|
||||
}
|
||||
$data['Filename'] = $this->joinPaths(ASSETS_DIR, $relativeTargetPath);
|
||||
if(!isset($data['Name'])) $data['Name'] = basename($relativeTargetPath);
|
||||
if($parent) $data['ParentID'] = $parent->ID;
|
||||
|
||||
$this->createdFilesPaths[] = $targetPath;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return AssetStore
|
||||
*/
|
||||
protected function getAssetStore() {
|
||||
return singleton('AssetStore');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a natural language class description to an actual class name.
|
||||
* Respects {@link DataObject::$singular_name} variations.
|
||||
|
|
|
@ -83,13 +83,13 @@ class SilverStripeAwareInitializer implements InitializerInterface
|
|||
|
||||
public function __destruct()
|
||||
{
|
||||
file_put_contents('php://stdout', "Killing test session environment...");
|
||||
|
||||
// Add condition here as register_shutdown_function() also calls this in __construct()
|
||||
if($this->testSessionEnvironment) {
|
||||
file_put_contents('php://stdout', "Killing test session environment...");
|
||||
$this->testSessionEnvironment->endTestSession();
|
||||
$this->testSessionEnvironment = null;
|
||||
file_put_contents('php://stdout', " done!" . PHP_EOL);
|
||||
}
|
||||
|
||||
file_put_contents('php://stdout', " done!" . PHP_EOL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -203,7 +203,7 @@ class SilverStripeContext extends MinkContext implements SilverStripeAwareContex
|
|||
}
|
||||
|
||||
// Fixtures
|
||||
$fixtureFile = (!empty($params['fixture'])) ? $params['fixture'] : null;
|
||||
$fixtureFile = (!empty($state['fixture'])) ? $state['fixture'] : null;
|
||||
if($fixtureFile) {
|
||||
$this->testSessionEnvironment->loadFixtureIntoDb($fixtureFile);
|
||||
}
|
||||
|
|
0
tests/Context/FixtureContextTest.php
Normal file
0
tests/Context/FixtureContextTest.php
Normal file
Loading…
Reference in New Issue
Block a user