\ No newline at end of file
diff --git a/src/Codeception/PHPUnit/Runner.php b/src/Codeception/PHPUnit/Runner.php
deleted file mode 100644
index 2b36a3914c..0000000000
--- a/src/Codeception/PHPUnit/Runner.php
+++ /dev/null
@@ -1,184 +0,0 @@
- false,
- 'html' => false,
- 'tap' => false,
- 'json' => false,
- 'report' => false
- ];
-
- protected $config = [];
-
- protected $logDir = null;
-
- public function __construct()
- {
- $this->config = Configuration::config();
- $this->logDir = Configuration::outputDir(); // prepare log dir
- $this->phpUnitOverriders();
- parent::__construct();
- }
-
- public function phpUnitOverriders()
- {
- require_once __DIR__ . DIRECTORY_SEPARATOR . 'Overrides/Filter.php';
- }
-
- /**
- * @return null|\PHPUnit_TextUI_ResultPrinter
- */
- public function getPrinter()
- {
- return $this->printer;
- }
-
- public function prepareSuite(\PHPUnit_Framework_Test $suite, array &$arguments)
- {
- $this->handleConfiguration($arguments);
-
- $filterFactory = new \PHPUnit_Runner_Filter_Factory();
- if ($arguments['groups']) {
- $filterFactory->addFilter(
- new \ReflectionClass('PHPUnit_Runner_Filter_Group_Include'),
- $arguments['groups']
- );
- }
-
- if ($arguments['excludeGroups']) {
- $filterFactory->addFilter(
- new \ReflectionClass('PHPUnit_Runner_Filter_Group_Exclude'),
- $arguments['excludeGroups']
- );
- }
-
- if ($arguments['filter']) {
- $filterFactory->addFilter(
- new \ReflectionClass('Codeception\PHPUnit\FilterTest'),
- $arguments['filter']
- );
- }
-
- $suite->injectFilter($filterFactory);
- }
-
- public function doEnhancedRun(
- \PHPUnit_Framework_Test $suite,
- \PHPUnit_Framework_TestResult $result,
- array $arguments = []
- ) {
- unset($GLOBALS['app']); // hook for not to serialize globals
-
- $result->convertErrorsToExceptions(false);
-
- if (isset($arguments['report_useless_tests'])) {
- $result->beStrictAboutTestsThatDoNotTestAnything((bool)$arguments['report_useless_tests']);
- }
-
- if (isset($arguments['disallow_test_output'])) {
- $result->beStrictAboutOutputDuringTests((bool)$arguments['disallow_test_output']);
- }
-
- if (empty(self::$persistentListeners)) {
- $this->applyReporters($result, $arguments);
- }
-
- if (class_exists('\Symfony\Bridge\PhpUnit\SymfonyTestsListener')) {
- $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : [];
- $arguments['listeners'][] = new \Symfony\Bridge\PhpUnit\SymfonyTestsListener();
- }
-
- $arguments['listeners'][] = $this->printer;
-
- // clean up listeners between suites
- foreach ($arguments['listeners'] as $listener) {
- $result->addListener($listener);
- }
-
- $suite->run($result);
- unset($suite);
-
- foreach ($arguments['listeners'] as $listener) {
- $result->removeListener($listener);
- }
-
- return $result;
- }
-
- /**
- * @param \PHPUnit_Framework_TestResult $result
- * @param array $arguments
- *
- * @return array
- */
- protected function applyReporters(\PHPUnit_Framework_TestResult $result, array $arguments)
- {
- foreach ($this->defaultListeners as $listener => $value) {
- if (!isset($arguments[$listener])) {
- $arguments[$listener] = $value;
- }
- }
-
- if ($arguments['report']) {
- self::$persistentListeners[] = $this->instantiateReporter('report');
- }
-
- if ($arguments['html']) {
- codecept_debug('Printing HTML report into ' . $arguments['html']);
- self::$persistentListeners[] = $this->instantiateReporter(
- 'html',
- [$this->absolutePath($arguments['html'])]
- );
- }
- if ($arguments['xml']) {
- codecept_debug('Printing JUNIT report into ' . $arguments['xml']);
- self::$persistentListeners[] = $this->instantiateReporter(
- 'xml',
- [$this->absolutePath($arguments['xml']), (bool)$arguments['log_incomplete_skipped']]
- );
- }
- if ($arguments['tap']) {
- codecept_debug('Printing TAP report into ' . $arguments['tap']);
- self::$persistentListeners[] = $this->instantiateReporter('tap', [$this->absolutePath($arguments['tap'])]);
- }
- if ($arguments['json']) {
- codecept_debug('Printing JSON report into ' . $arguments['json']);
- self::$persistentListeners[] = $this->instantiateReporter(
- 'json',
- [$this->absolutePath($arguments['json'])]
- );
- }
-
- foreach (self::$persistentListeners as $listener) {
- if ($listener instanceof ConsolePrinter) {
- $this->printer = $listener;
- continue;
- }
- $result->addListener($listener);
- }
- }
-
- protected function instantiateReporter($name, $args = [])
- {
- if (!isset($this->config['reporters'][$name])) {
- throw new ConfigurationException("Reporter $name not defined");
- }
- return (new \ReflectionClass($this->config['reporters'][$name]))->newInstanceArgs($args);
- }
-
- private function absolutePath($path)
- {
- if ((strpos($path, '/') === 0) or (strpos($path, ':') === 1)) { // absolute path
- return $path;
- }
- return $this->logDir . $path;
- }
-}
diff --git a/src/Codeception/README.md b/src/Codeception/README.md
index a6cc8828f6..db54b5072a 100644
--- a/src/Codeception/README.md
+++ b/src/Codeception/README.md
@@ -7,4 +7,4 @@ The most important classes are defined in root of Codeception.
* `TestLoader` - loads tests from files
* `Configuration` - loads YAML configuration
* `Events` - defines all Codeception events
-* `TestCase` - applies Codeception feature to `PHPUnit_Framework_TestCase` class.
\ No newline at end of file
+* `TestCase` - applies Codeception feature to `PHPUnit\Framework\TestCase` class.
\ No newline at end of file
diff --git a/src/Codeception/Scenario.php b/src/Codeception/Scenario.php
index 60fb72596f..22535020f7 100644
--- a/src/Codeception/Scenario.php
+++ b/src/Codeception/Scenario.php
@@ -136,12 +136,12 @@ public function comment($comment)
public function skip($message = '')
{
- throw new \PHPUnit_Framework_SkippedTestError($message);
+ throw new \PHPUnit\Framework\SkippedTestError($message);
}
public function incomplete($message = '')
{
- throw new \PHPUnit_Framework_IncompleteTestError($message);
+ throw new \PHPUnit\Framework\IncompleteTestError($message);
}
public function __call($method, $args)
diff --git a/src/Codeception/Step/ConditionalAssertion.php b/src/Codeception/Step/ConditionalAssertion.php
index 2940e61c92..574af549b9 100644
--- a/src/Codeception/Step/ConditionalAssertion.php
+++ b/src/Codeception/Step/ConditionalAssertion.php
@@ -10,7 +10,7 @@ public function run(ModuleContainer $container = null)
{
try {
parent::run($container);
- } catch (\PHPUnit_Framework_AssertionFailedError $e) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $e) {
throw new ConditionalAssertionFailed($e->getMessage(), $e->getCode(), $e);
}
}
diff --git a/src/Codeception/Step/Incomplete.php b/src/Codeception/Step/Incomplete.php
index f3c11c78ad..3db8d949e4 100644
--- a/src/Codeception/Step/Incomplete.php
+++ b/src/Codeception/Step/Incomplete.php
@@ -8,7 +8,7 @@ class Incomplete extends CodeceptionStep
{
public function run(ModuleContainer $container = null)
{
- throw new \PHPUnit_Framework_IncompleteTestError($this->getAction());
+ throw new \PHPUnit\Framework\IncompleteTestError($this->getAction());
}
public function __toString()
diff --git a/src/Codeception/Step/Skip.php b/src/Codeception/Step/Skip.php
index 10b84c0dd8..558f31080e 100644
--- a/src/Codeception/Step/Skip.php
+++ b/src/Codeception/Step/Skip.php
@@ -8,7 +8,7 @@ class Skip extends CodeceptionStep
{
public function run(ModuleContainer $container = null)
{
- throw new \PHPUnit_Framework_SkippedTestError($this->getAction());
+ throw new \PHPUnit\Framework\SkippedTestError($this->getAction());
}
public function __toString()
diff --git a/src/Codeception/Subscriber/BeforeAfterTest.php b/src/Codeception/Subscriber/BeforeAfterTest.php
index c5d8466ea2..414b1aa2a7 100644
--- a/src/Codeception/Subscriber/BeforeAfterTest.php
+++ b/src/Codeception/Subscriber/BeforeAfterTest.php
@@ -21,14 +21,14 @@ class BeforeAfterTest implements EventSubscriberInterface
public function beforeClass(SuiteEvent $e)
{
foreach ($e->getSuite()->tests() as $test) {
- /** @var $test \PHPUnit_Framework_Test * */
- if ($test instanceof \PHPUnit_Framework_TestSuite_DataProvider) {
+ /** @var $test \PHPUnit\Framework\Test * */
+ if ($test instanceof \PHPUnit\Framework\TestSuite\DataProvider) {
$potentialTestClass = strstr($test->getName(), '::', true);
- $this->hooks[$potentialTestClass] = \PHPUnit_Util_Test::getHookMethods($potentialTestClass);
+ $this->hooks[$potentialTestClass] = \PHPUnit\Util\Test::getHookMethods($potentialTestClass);
}
$testClass = get_class($test);
- $this->hooks[$testClass] = \PHPUnit_Util_Test::getHookMethods($testClass);
+ $this->hooks[$testClass] = \PHPUnit\Util\Test::getHookMethods($testClass);
}
$this->runHooks('beforeClass');
}
diff --git a/src/Codeception/Subscriber/Console.php b/src/Codeception/Subscriber/Console.php
index ddf9f99d99..707f3ddd87 100644
--- a/src/Codeception/Subscriber/Console.php
+++ b/src/Codeception/Subscriber/Console.php
@@ -362,7 +362,7 @@ public function printFail(FailEvent $e)
public function printException($e, $cause = null)
{
- if ($e instanceof \PHPUnit_Framework_SkippedTestError or $e instanceof \PHPUnit_Framework_IncompleteTestError) {
+ if ($e instanceof \PHPUnit\Framework\SkippedTestError or $e instanceof \PHPUnit\Framework_IncompleteTestError) {
if ($e->getMessage()) {
$this->message(OutputFormatter::escape($e->getMessage()))->prepend("\n")->writeln();
}
@@ -370,7 +370,7 @@ public function printException($e, $cause = null)
return;
}
- $class = $e instanceof \PHPUnit_Framework_ExceptionWrapper
+ $class = $e instanceof \PHPUnit\Framework\ExceptionWrapper
? $e->getClassname()
: get_class($e);
@@ -381,16 +381,16 @@ public function printException($e, $cause = null)
$this->output->writeln('');
$message = $this->message(OutputFormatter::escape($e->getMessage()));
- if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) {
+ if ($e instanceof \PHPUnit\Framework\ExpectationFailedException) {
$comparisonFailure = $e->getComparisonFailure();
if ($comparisonFailure) {
$message->append($this->messageFactory->prepareComparisonFailureMessage($comparisonFailure));
}
}
- $isFailure = $e instanceof \PHPUnit_Framework_AssertionFailedError
- || $class === 'PHPUnit_Framework_ExpectationFailedException'
- || $class === 'PHPUnit_Framework_AssertionFailedError';
+ $isFailure = $e instanceof \PHPUnit\Framework\AssertionFailedError
+ || $class === 'PHPUnit\Framework\ExpectationFailedException'
+ || $class === 'PHPUnit\Framework\AssertionFailedError';
if (!$isFailure) {
$message->prepend("[$class] ")->block('error');
@@ -423,7 +423,7 @@ public function printScenarioFail(ScenarioDriven $failedTest, $fail)
return;
}
- if (!$fail instanceof \PHPUnit_Framework_AssertionFailedError) {
+ if (!$fail instanceof \PHPUnit\Framework\AssertionFailedError) {
$this->printExceptionTrace($fail);
return;
@@ -434,17 +434,17 @@ public function printExceptionTrace(\Exception $e)
{
static $limit = 10;
- if ($e instanceof \PHPUnit_Framework_SkippedTestError or $e instanceof \PHPUnit_Framework_IncompleteTestError) {
+ if ($e instanceof \PHPUnit\Framework\SkippedTestError or $e instanceof \PHPUnit\Framework_IncompleteTestError) {
return;
}
if ($this->rawStackTrace) {
- $this->message(OutputFormatter::escape(\PHPUnit_Util_Filter::getFilteredStacktrace($e, true, false)))->writeln();
+ $this->message(OutputFormatter::escape(\PHPUnit\Util\Filter::getFilteredStacktrace($e, true, false)))->writeln();
return;
}
- $trace = \PHPUnit_Util_Filter::getFilteredStacktrace($e, false);
+ $trace = \PHPUnit\Util\Filter::getFilteredStacktrace($e, false);
$i = 0;
foreach ($trace as $step) {
@@ -555,10 +555,10 @@ private function isWin()
}
/**
- * @param \PHPUnit_Framework_SelfDescribing $test
+ * @param \PHPUnit\Framework\SelfDescribing $test
* @param bool $inProgress
*/
- protected function writeCurrentTest(\PHPUnit_Framework_SelfDescribing $test, $inProgress = true)
+ protected function writeCurrentTest(\PHPUnit\Framework\SelfDescribing $test, $inProgress = true)
{
$prefix = ($this->output->isInteractive() and !$this->isDetailed($test) and $inProgress) ? '- ' : '';
diff --git a/src/Codeception/Subscriber/ErrorHandler.php b/src/Codeception/Subscriber/ErrorHandler.php
index e8b380201d..9d1f3d7e59 100644
--- a/src/Codeception/Subscriber/ErrorHandler.php
+++ b/src/Codeception/Subscriber/ErrorHandler.php
@@ -80,7 +80,7 @@ public function errorHandler($errno, $errstr, $errfile, $errline, $context = arr
return false;
}
- throw new \PHPUnit_Framework_Exception($errstr, $errno);
+ throw new \PHPUnit\Framework\Exception($errstr, $errno);
}
public function shutdownHandler()
@@ -117,7 +117,7 @@ public function shutdownHandler()
private function registerDeprecationErrorHandler()
{
if (class_exists('\Symfony\Bridge\PhpUnit\DeprecationErrorHandler') && 'disabled' !== getenv('SYMFONY_DEPRECATIONS_HELPER')) {
- // DeprecationErrorHandler only will be installed if array('PHPUnit_Util_ErrorHandler', 'handleError')
+ // DeprecationErrorHandler only will be installed if array('PHPUnit\Util\ErrorHandler', 'handleError')
// is installed or no other error handlers are installed.
// So we will remove Symfony\Component\Debug\ErrorHandler if it's installed.
$old = set_error_handler('var_dump');
diff --git a/src/Codeception/Suite.php b/src/Codeception/Suite.php
index e1acf80e30..509e66627c 100644
--- a/src/Codeception/Suite.php
+++ b/src/Codeception/Suite.php
@@ -4,7 +4,7 @@
use Codeception\Test\Descriptor;
use Codeception\Test\Interfaces\Dependent;
-class Suite extends \PHPUnit_Framework_TestSuite
+class Suite extends \PHPUnit\Framework\TestSuite
{
protected $modules;
protected $baseName;
diff --git a/src/Codeception/SuiteManager.php b/src/Codeception/SuiteManager.php
index deaa1dd610..748ca8f114 100644
--- a/src/Codeception/SuiteManager.php
+++ b/src/Codeception/SuiteManager.php
@@ -16,7 +16,7 @@ class SuiteManager
public static $name;
/**
- * @var \PHPUnit_Framework_TestSuite
+ * @var \PHPUnit\Framework\TestSuite
*/
protected $suite = null;
@@ -108,7 +108,7 @@ protected function addToSuite($test)
{
$this->configureTest($test);
- if ($test instanceof \PHPUnit_Framework_TestSuite_DataProvider) {
+ if ($test instanceof \PHPUnit\Framework\DataProviderTestSuite) {
foreach ($test->tests() as $t) {
$this->addToSuite($t);
}
@@ -150,7 +150,7 @@ protected function createSuite($name)
}
- public function run(PHPUnit\Runner $runner, \PHPUnit_Framework_TestResult $result, $options)
+ public function run(PHPUnit\Runner $runner, \PHPUnit\Framework\TestResult $result, $options)
{
$runner->prepareSuite($this->suite, $options);
$this->dispatcher->dispatch(Events::SUITE_BEFORE, new Event\SuiteEvent($this->suite, $result, $this->settings));
diff --git a/src/Codeception/Test/Cest.php b/src/Codeception/Test/Cest.php
index 85028ebd9c..cb2a130f83 100644
--- a/src/Codeception/Test/Cest.php
+++ b/src/Codeception/Test/Cest.php
@@ -98,7 +98,7 @@ protected function executeHook($I, $hook)
protected function executeBeforeMethods($testMethod, $I)
{
- $annotations = \PHPUnit_Util_Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
+ $annotations = \PHPUnit\Util\Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
if (!empty($annotations['method']['before'])) {
foreach ($annotations['method']['before'] as $m) {
$this->executeContextMethod(trim($m), $I);
@@ -107,7 +107,7 @@ protected function executeBeforeMethods($testMethod, $I)
}
protected function executeAfterMethods($testMethod, $I)
{
- $annotations = \PHPUnit_Util_Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
+ $annotations = \PHPUnit\Util\Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
if (!empty($annotations['method']['after'])) {
foreach ($annotations['method']['after'] as $m) {
$this->executeContextMethod(trim($m), $I);
@@ -203,7 +203,7 @@ public function getLinesToBeCovered()
$class = get_class($this->getTestClass());
$method = $this->getTestMethod();
- return \PHPUnit_Util_Test::getLinesToBeCovered($class, $method);
+ return \PHPUnit\Util\Test::getLinesToBeCovered($class, $method);
}
public function getLinesToBeUsed()
@@ -211,6 +211,6 @@ public function getLinesToBeUsed()
$class = get_class($this->getTestClass());
$method = $this->getTestMethod();
- return \PHPUnit_Util_Test::getLinesToBeUsed($class, $method);
+ return \PHPUnit\Util\Test::getLinesToBeUsed($class, $method);
}
}
diff --git a/src/Codeception/Test/Descriptor.php b/src/Codeception/Test/Descriptor.php
index 9050e76682..c68a6e0ef3 100644
--- a/src/Codeception/Test/Descriptor.php
+++ b/src/Codeception/Test/Descriptor.php
@@ -10,15 +10,15 @@ class Descriptor
/**
* Provides a test name which can be located by
*
- * @param \PHPUnit_Framework_SelfDescribing $testCase
+ * @param \PHPUnit\Framework\SelfDescribing $testCase
* @return string
*/
- public static function getTestSignature(\PHPUnit_Framework_SelfDescribing $testCase)
+ public static function getTestSignature(\PHPUnit\Framework\SelfDescribing $testCase)
{
if ($testCase instanceof Descriptive) {
return $testCase->getSignature();
}
- if ($testCase instanceof \PHPUnit_Framework_TestCase) {
+ if ($testCase instanceof \PHPUnit\Framework\TestCase) {
return get_class($testCase) . ':' . $testCase->getName(false);
}
return $testCase->toString();
@@ -27,10 +27,10 @@ public static function getTestSignature(\PHPUnit_Framework_SelfDescribing $testC
/**
* Provides a test name which is unique for individual iterations of tests using examples
*
- * @param \PHPUnit_Framework_SelfDescribing $testCase
+ * @param \PHPUnit\Framework\SelfDescribing $testCase
* @return string
*/
- public static function getTestSignatureUnique(\PHPUnit_Framework_SelfDescribing $testCase)
+ public static function getTestSignatureUnique(\PHPUnit\Framework\SelfDescribing $testCase)
{
$example = null;
@@ -43,9 +43,9 @@ public static function getTestSignatureUnique(\PHPUnit_Framework_SelfDescribing
return self::getTestSignature($testCase) . $example;
}
- public static function getTestAsString(\PHPUnit_Framework_SelfDescribing $testCase)
+ public static function getTestAsString(\PHPUnit\Framework\SelfDescribing $testCase)
{
- if ($testCase instanceof \PHPUnit_Framework_TestCase) {
+ if ($testCase instanceof \PHPUnit\Framework\TestCase) {
$text = $testCase->getName();
$text = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\\1 \\2', $text);
$text = preg_replace('/([a-z\d])([A-Z])/', '\\1 \\2', $text);
@@ -61,10 +61,10 @@ public static function getTestAsString(\PHPUnit_Framework_SelfDescribing $testCa
/**
* Provides a test file name relative to Codeception root
*
- * @param \PHPUnit_Framework_SelfDescribing $testCase
+ * @param \PHPUnit\Framework\SelfDescribing $testCase
* @return mixed
*/
- public static function getTestFileName(\PHPUnit_Framework_SelfDescribing $testCase)
+ public static function getTestFileName(\PHPUnit\Framework\SelfDescribing $testCase)
{
if ($testCase instanceof Descriptive) {
return codecept_relative_path(realpath($testCase->getFileName()));
@@ -73,10 +73,10 @@ public static function getTestFileName(\PHPUnit_Framework_SelfDescribing $testCa
}
/**
- * @param \PHPUnit_Framework_SelfDescribing $testCase
+ * @param \PHPUnit\Framework\SelfDescribing $testCase
* @return mixed|string
*/
- public static function getTestFullName(\PHPUnit_Framework_SelfDescribing $testCase)
+ public static function getTestFullName(\PHPUnit\Framework\SelfDescribing $testCase)
{
if ($testCase instanceof Plain) {
return self::getTestFileName($testCase);
@@ -85,7 +85,7 @@ public static function getTestFullName(\PHPUnit_Framework_SelfDescribing $testCa
$signature = $testCase->getSignature(); // cut everything before ":" from signature
return self::getTestFileName($testCase) . ':' . preg_replace('~^(.*?):~', '', $signature);
}
- if ($testCase instanceof \PHPUnit_Framework_TestCase) {
+ if ($testCase instanceof \PHPUnit\Framework\TestCase) {
return self::getTestFileName($testCase) . ':' . $testCase->getName(false);
}
return self::getTestFileName($testCase) . ':' . $testCase->toString();
diff --git a/src/Codeception/Test/Feature/AssertionCounter.php b/src/Codeception/Test/Feature/AssertionCounter.php
index 22d1f6c607..ad7c292893 100644
--- a/src/Codeception/Test/Feature/AssertionCounter.php
+++ b/src/Codeception/Test/Feature/AssertionCounter.php
@@ -12,11 +12,11 @@ public function getNumAssertions()
protected function assertionCounterStart()
{
- \PHPUnit_Framework_Assert::resetCount();
+ \PHPUnit\Framework\Assert::resetCount();
}
protected function assertionCounterEnd()
{
- $this->numAssertions = \PHPUnit_Framework_Assert::getCount();
+ $this->numAssertions = \PHPUnit\Framework\Assert::getCount();
}
}
diff --git a/src/Codeception/Test/Feature/CodeCoverage.php b/src/Codeception/Test/Feature/CodeCoverage.php
index 4c5d4a2202..4357068b77 100644
--- a/src/Codeception/Test/Feature/CodeCoverage.php
+++ b/src/Codeception/Test/Feature/CodeCoverage.php
@@ -7,7 +7,7 @@
trait CodeCoverage
{
/**
- * @return \PHPUnit_Framework_TestResult
+ * @return \PHPUnit\Framework\TestResult
*/
abstract public function getTestResultObject();
diff --git a/src/Codeception/Test/Feature/ErrorLogger.php b/src/Codeception/Test/Feature/ErrorLogger.php
index 7400d13e09..7b1b846c9c 100644
--- a/src/Codeception/Test/Feature/ErrorLogger.php
+++ b/src/Codeception/Test/Feature/ErrorLogger.php
@@ -6,7 +6,7 @@
trait ErrorLogger
{
/**
- * @return \PHPUnit_Framework_TestResult
+ * @return \PHPUnit\Framework\TestResult
*/
abstract public function getTestResultObject();
diff --git a/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php b/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php
index eebdb04f4c..63ce3a04c0 100644
--- a/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php
+++ b/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php
@@ -13,7 +13,7 @@ abstract protected function getMetadata();
abstract protected function ignore($ignored);
/**
- * @return \PHPUnit_Framework_TestResult
+ * @return \PHPUnit\Framework\TestResult
*/
abstract protected function getTestResultObject();
@@ -26,11 +26,11 @@ protected function ignoreIfMetadataBlockedStart()
$this->ignore(true);
if ($this->getMetadata()->getSkip() !== null) {
- $this->getTestResultObject()->addFailure($this, new \PHPUnit_Framework_SkippedTestError((string)$this->getMetadata()->getSkip()), 0);
+ $this->getTestResultObject()->addFailure($this, new \PHPUnit\Framework\SkippedTestError((string)$this->getMetadata()->getSkip()), 0);
return;
}
if ($this->getMetadata()->getIncomplete() !== null) {
- $this->getTestResultObject()->addFailure($this, new \PHPUnit_Framework_IncompleteTestError((string)$this->getMetadata()->getIncomplete()), 0);
+ $this->getTestResultObject()->addFailure($this, new \PHPUnit\Framework\IncompleteTestError((string)$this->getMetadata()->getIncomplete()), 0);
return;
}
}
diff --git a/src/Codeception/Test/Interfaces/Descriptive.php b/src/Codeception/Test/Interfaces/Descriptive.php
index 015748d836..fa1b2e0454 100644
--- a/src/Codeception/Test/Interfaces/Descriptive.php
+++ b/src/Codeception/Test/Interfaces/Descriptive.php
@@ -1,7 +1,7 @@
$example) {
if ($example === null) {
throw new TestParseException(
diff --git a/src/Codeception/Test/Loader/Unit.php b/src/Codeception/Test/Loader/Unit.php
index d72984e177..3e1235a5d5 100644
--- a/src/Codeception/Test/Loader/Unit.php
+++ b/src/Codeception/Test/Loader/Unit.php
@@ -43,12 +43,12 @@ public function getTests()
protected function createTestFromPhpUnitMethod(\ReflectionClass $class, \ReflectionMethod $method)
{
- if (!\PHPUnit_Framework_TestSuite::isTestMethod($method)) {
+ if (!\PHPUnit\Framework\TestSuite::isTestMethod($method)) {
return;
}
- $test = \PHPUnit_Framework_TestSuite::createTest($class, $method->name);
+ $test = \PHPUnit\Framework\TestSuite::createTest($class, $method->name);
- if ($test instanceof \PHPUnit_Framework_TestSuite_DataProvider) {
+ if ($test instanceof \PHPUnit\Framework\DataProviderTestSuite) {
foreach ($test->tests() as $t) {
$this->enhancePhpunitTest($t);
}
@@ -59,11 +59,11 @@ protected function createTestFromPhpUnitMethod(\ReflectionClass $class, \Reflect
return $test;
}
- protected function enhancePhpunitTest(\PHPUnit_Framework_TestCase $test)
+ protected function enhancePhpunitTest(\PHPUnit\Framework\Test $test)
{
$className = get_class($test);
$methodName = $test->getName(false);
- $dependencies = \PHPUnit_Util_Test::getDependencies($className, $methodName);
+ $dependencies = \PHPUnit\Util\Test::getDependencies($className, $methodName);
$test->setDependencies($dependencies);
if ($test instanceof UnitFormat) {
$test->getMetadata()->setParamsFromAnnotations(Annotation::forMethod($test, $methodName)->raw());
diff --git a/src/Codeception/Test/Test.php b/src/Codeception/Test/Test.php
index 49490480a1..773f7a3aa8 100644
--- a/src/Codeception/Test/Test.php
+++ b/src/Codeception/Test/Test.php
@@ -3,6 +3,7 @@
use Codeception\TestInterface;
use Codeception\Util\ReflectionHelper;
+use SebastianBergmann\Timer\Timer;
/**
* The most simple testcase (with only one test in it) which can be executed by PHPUnit/Codeception.
@@ -60,10 +61,10 @@ abstract public function toString();
* Runs a test and collects its result in a TestResult instance.
* Executes before/after hooks coming from traits.
*
- * @param \PHPUnit_Framework_TestResult $result
- * @return \PHPUnit_Framework_TestResult
+ * @param \PHPUnit\Framework\TestResult $result
+ * @return \PHPUnit\Framework\TestResult
*/
- final public function run(\PHPUnit_Framework_TestResult $result = null)
+ final public function run(\PHPUnit\Framework\TestResult $result = null)
{
$this->testResult = $result;
@@ -82,22 +83,23 @@ final public function run(\PHPUnit_Framework_TestResult $result = null)
$failedToStart = ReflectionHelper::readPrivateProperty($result, 'lastTestFailed');
if (!$this->ignored && !$failedToStart) {
- \PHP_Timer::start();
+
+ Timer::start();
try {
$this->test();
$status = self::STATUS_OK;
- } catch (\PHPUnit_Framework_AssertionFailedError $e) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $e) {
$status = self::STATUS_FAIL;
- } catch (\PHPUnit_Framework_Exception $e) {
+ } catch (\PHPUnit\Framework\Exception $e) {
$status = self::STATUS_ERROR;
} catch (\Throwable $e) {
- $e = new \PHPUnit_Framework_ExceptionWrapper($e);
+ $e = new \PHPUnit\Framework\ExceptionWrapper($e);
$status = self::STATUS_ERROR;
} catch (\Exception $e) {
- $e = new \PHPUnit_Framework_ExceptionWrapper($e);
+ $e = new \PHPUnit\Framework\ExceptionWrapper($e);
$status = self::STATUS_ERROR;
}
- $time = \PHP_Timer::stop();
+ $time = Timer::stop();
}
foreach (array_reverse($this->hooks) as $hook) {
diff --git a/src/Codeception/Test/Unit.php b/src/Codeception/Test/Unit.php
index ab64e69eb5..c85acbfa8c 100644
--- a/src/Codeception/Test/Unit.php
+++ b/src/Codeception/Test/Unit.php
@@ -11,7 +11,7 @@
/**
* Represents tests from PHPUnit compatible format.
*/
-class Unit extends \PHPUnit_Framework_TestCase implements
+class Unit extends \PHPUnit\Framework\TestCase implements
Interfaces\Reported,
Interfaces\Dependent,
TestInterface
diff --git a/src/Codeception/TestInterface.php b/src/Codeception/TestInterface.php
index 1974e97cf5..c8f7c09c5f 100644
--- a/src/Codeception/TestInterface.php
+++ b/src/Codeception/TestInterface.php
@@ -4,7 +4,7 @@
use Codeception\Test\Metadata;
-interface TestInterface extends \PHPUnit_Framework_Test
+interface TestInterface extends \PHPUnit\Framework\Test
{
/**
* @return Metadata
diff --git a/src/Codeception/Util/Shared/Asserts.php b/src/Codeception/Util/Shared/Asserts.php
index 2b199b8e99..2c4958bed7 100644
--- a/src/Codeception/Util/Shared/Asserts.php
+++ b/src/Codeception/Util/Shared/Asserts.php
@@ -16,7 +16,7 @@ protected function assert($arguments, $not = false)
$not = '';
}
- call_user_func_array(['\PHPUnit_Framework_Assert', 'assert' . $not . $method], $arguments);
+ call_user_func_array(['\PHPUnit\Framework\Assert', 'assert' . $not . $method], $arguments);
}
protected function assertNot($arguments)
@@ -34,7 +34,7 @@ protected function assertNot($arguments)
*/
protected function assertEquals($expected, $actual, $message = '', $delta = 0.0)
{
- \PHPUnit_Framework_Assert::assertEquals($expected, $actual, $message, $delta);
+ \PHPUnit\Framework\Assert::assertEquals($expected, $actual, $message, $delta);
}
/**
@@ -47,7 +47,7 @@ protected function assertEquals($expected, $actual, $message = '', $delta = 0.0)
*/
protected function assertNotEquals($expected, $actual, $message = '', $delta = 0.0)
{
- \PHPUnit_Framework_Assert::assertNotEquals($expected, $actual, $message, $delta);
+ \PHPUnit\Framework\Assert::assertNotEquals($expected, $actual, $message, $delta);
}
/**
@@ -59,7 +59,7 @@ protected function assertNotEquals($expected, $actual, $message = '', $delta = 0
*/
protected function assertSame($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertSame($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertSame($expected, $actual, $message);
}
/**
@@ -71,7 +71,7 @@ protected function assertSame($expected, $actual, $message = '')
*/
protected function assertNotSame($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertNotSame($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertNotSame($expected, $actual, $message);
}
/**
@@ -83,7 +83,7 @@ protected function assertNotSame($expected, $actual, $message = '')
*/
protected function assertGreaterThan($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertGreaterThan($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertGreaterThan($expected, $actual, $message);
}
/**
@@ -91,7 +91,7 @@ protected function assertGreaterThan($expected, $actual, $message = '')
*/
protected function assertGreaterThen($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertGreaterThan($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertGreaterThan($expected, $actual, $message);
}
/**
@@ -103,7 +103,7 @@ protected function assertGreaterThen($expected, $actual, $message = '')
*/
protected function assertGreaterThanOrEqual($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertGreaterThanOrEqual($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertGreaterThanOrEqual($expected, $actual, $message);
}
/**
@@ -111,7 +111,7 @@ protected function assertGreaterThanOrEqual($expected, $actual, $message = '')
*/
protected function assertGreaterThenOrEqual($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertGreaterThanOrEqual($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertGreaterThanOrEqual($expected, $actual, $message);
}
/**
@@ -123,7 +123,7 @@ protected function assertGreaterThenOrEqual($expected, $actual, $message = '')
*/
protected function assertLessThan($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertLessThan($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertLessThan($expected, $actual, $message);
}
/**
@@ -135,7 +135,7 @@ protected function assertLessThan($expected, $actual, $message = '')
*/
protected function assertLessThanOrEqual($expected, $actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertLessThanOrEqual($expected, $actual, $message);
+ \PHPUnit\Framework\Assert::assertLessThanOrEqual($expected, $actual, $message);
}
@@ -148,7 +148,7 @@ protected function assertLessThanOrEqual($expected, $actual, $message = '')
*/
protected function assertContains($needle, $haystack, $message = '')
{
- \PHPUnit_Framework_Assert::assertContains($needle, $haystack, $message);
+ \PHPUnit\Framework\Assert::assertContains($needle, $haystack, $message);
}
/**
@@ -160,7 +160,7 @@ protected function assertContains($needle, $haystack, $message = '')
*/
protected function assertNotContains($needle, $haystack, $message = '')
{
- \PHPUnit_Framework_Assert::assertNotContains($needle, $haystack, $message);
+ \PHPUnit\Framework\Assert::assertNotContains($needle, $haystack, $message);
}
/**
@@ -172,7 +172,7 @@ protected function assertNotContains($needle, $haystack, $message = '')
*/
protected function assertRegExp($pattern, $string, $message = '')
{
- \PHPUnit_Framework_Assert::assertRegExp($pattern, $string, $message);
+ \PHPUnit\Framework\Assert::assertRegExp($pattern, $string, $message);
}
/**
@@ -184,7 +184,7 @@ protected function assertRegExp($pattern, $string, $message = '')
*/
protected function assertNotRegExp($pattern, $string, $message = '')
{
- \PHPUnit_Framework_Assert::assertNotRegExp($pattern, $string, $message);
+ \PHPUnit\Framework\Assert::assertNotRegExp($pattern, $string, $message);
}
/**
@@ -196,7 +196,7 @@ protected function assertNotRegExp($pattern, $string, $message = '')
*/
protected function assertStringStartsWith($prefix, $string, $message = '')
{
- \PHPUnit_Framework_Assert::assertStringStartsWith($prefix, $string, $message);
+ \PHPUnit\Framework\Assert::assertStringStartsWith($prefix, $string, $message);
}
/**
@@ -208,7 +208,7 @@ protected function assertStringStartsWith($prefix, $string, $message = '')
*/
protected function assertStringStartsNotWith($prefix, $string, $message = '')
{
- \PHPUnit_Framework_Assert::assertStringStartsNotWith($prefix, $string, $message);
+ \PHPUnit\Framework\Assert::assertStringStartsNotWith($prefix, $string, $message);
}
@@ -220,7 +220,7 @@ protected function assertStringStartsNotWith($prefix, $string, $message = '')
*/
protected function assertEmpty($actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertEmpty($actual, $message);
+ \PHPUnit\Framework\Assert::assertEmpty($actual, $message);
}
/**
@@ -231,7 +231,7 @@ protected function assertEmpty($actual, $message = '')
*/
protected function assertNotEmpty($actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertNotEmpty($actual, $message);
+ \PHPUnit\Framework\Assert::assertNotEmpty($actual, $message);
}
/**
@@ -242,7 +242,7 @@ protected function assertNotEmpty($actual, $message = '')
*/
protected function assertNull($actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertNull($actual, $message);
+ \PHPUnit\Framework\Assert::assertNull($actual, $message);
}
/**
@@ -253,7 +253,7 @@ protected function assertNull($actual, $message = '')
*/
protected function assertNotNull($actual, $message = '')
{
- \PHPUnit_Framework_Assert::assertNotNull($actual, $message);
+ \PHPUnit\Framework\Assert::assertNotNull($actual, $message);
}
/**
@@ -264,7 +264,7 @@ protected function assertNotNull($actual, $message = '')
*/
protected function assertTrue($condition, $message = '')
{
- \PHPUnit_Framework_Assert::assertTrue($condition, $message);
+ \PHPUnit\Framework\Assert::assertTrue($condition, $message);
}
/**
@@ -275,7 +275,7 @@ protected function assertTrue($condition, $message = '')
*/
protected function assertFalse($condition, $message = '')
{
- \PHPUnit_Framework_Assert::assertFalse($condition, $message);
+ \PHPUnit\Framework\Assert::assertFalse($condition, $message);
}
/**
@@ -286,7 +286,7 @@ protected function assertFalse($condition, $message = '')
*/
protected function assertThat($haystack, $constraint, $message = '')
{
- \PHPUnit_Framework_Assert::assertThat($haystack, $constraint, $message);
+ \PHPUnit\Framework\Assert::assertThat($haystack, $constraint, $message);
}
/**
@@ -298,8 +298,8 @@ protected function assertThat($haystack, $constraint, $message = '')
*/
protected function assertThatItsNot($haystack, $constraint, $message = '')
{
- $constraint = new \PHPUnit_Framework_Constraint_Not($constraint);
- \PHPUnit_Framework_Assert::assertThat($haystack, $constraint, $message);
+ $constraint = new \PHPUnit\Framework\Constraint\LogicalNot($constraint);
+ \PHPUnit\Framework\Assert::assertThat($haystack, $constraint, $message);
}
@@ -311,7 +311,7 @@ protected function assertThatItsNot($haystack, $constraint, $message = '')
*/
protected function assertFileExists($filename, $message = '')
{
- \PHPUnit_Framework_Assert::assertFileExists($filename, $message);
+ \PHPUnit\Framework\Assert::assertFileExists($filename, $message);
}
@@ -323,7 +323,7 @@ protected function assertFileExists($filename, $message = '')
*/
protected function assertFileNotExists($filename, $message = '')
{
- \PHPUnit_Framework_Assert::assertFileNotExists($filename, $message);
+ \PHPUnit\Framework\Assert::assertFileNotExists($filename, $message);
}
/**
@@ -333,7 +333,7 @@ protected function assertFileNotExists($filename, $message = '')
*/
protected function assertGreaterOrEquals($expected, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertGreaterThanOrEqual($expected, $actual, $description);
+ \PHPUnit\Framework\Assert::assertGreaterThanOrEqual($expected, $actual, $description);
}
/**
@@ -343,7 +343,7 @@ protected function assertGreaterOrEquals($expected, $actual, $description = '')
*/
protected function assertLessOrEquals($expected, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertLessThanOrEqual($expected, $actual, $description);
+ \PHPUnit\Framework\Assert::assertLessThanOrEqual($expected, $actual, $description);
}
/**
@@ -352,7 +352,7 @@ protected function assertLessOrEquals($expected, $actual, $description = '')
*/
protected function assertIsEmpty($actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertEmpty($actual, $description);
+ \PHPUnit\Framework\Assert::assertEmpty($actual, $description);
}
/**
@@ -362,7 +362,7 @@ protected function assertIsEmpty($actual, $description = '')
*/
protected function assertArrayHasKey($key, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertArrayHasKey($key, $actual, $description);
+ \PHPUnit\Framework\Assert::assertArrayHasKey($key, $actual, $description);
}
/**
@@ -372,7 +372,7 @@ protected function assertArrayHasKey($key, $actual, $description = '')
*/
protected function assertArrayNotHasKey($key, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertArrayNotHasKey($key, $actual, $description);
+ \PHPUnit\Framework\Assert::assertArrayNotHasKey($key, $actual, $description);
}
/**
@@ -385,7 +385,7 @@ protected function assertArrayNotHasKey($key, $actual, $description = '')
*/
protected function assertArraySubset($subset, $array, $strict = false, $message = '')
{
- \PHPUnit_Framework_Assert::assertArraySubset($subset, $array, $strict, $message);
+ \PHPUnit\Framework\Assert::assertArraySubset($subset, $array, $strict, $message);
}
/**
@@ -395,7 +395,7 @@ protected function assertArraySubset($subset, $array, $strict = false, $message
*/
protected function assertCount($expectedCount, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertCount($expectedCount, $actual, $description);
+ \PHPUnit\Framework\Assert::assertCount($expectedCount, $actual, $description);
}
/**
@@ -405,7 +405,7 @@ protected function assertCount($expectedCount, $actual, $description = '')
*/
protected function assertInstanceOf($class, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertInstanceOf($class, $actual, $description);
+ \PHPUnit\Framework\Assert::assertInstanceOf($class, $actual, $description);
}
/**
@@ -415,7 +415,7 @@ protected function assertInstanceOf($class, $actual, $description = '')
*/
protected function assertNotInstanceOf($class, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertNotInstanceOf($class, $actual, $description);
+ \PHPUnit\Framework\Assert::assertNotInstanceOf($class, $actual, $description);
}
/**
@@ -425,7 +425,7 @@ protected function assertNotInstanceOf($class, $actual, $description = '')
*/
protected function assertInternalType($type, $actual, $description = '')
{
- \PHPUnit_Framework_Assert::assertInternalType($type, $actual, $description);
+ \PHPUnit\Framework\Assert::assertInternalType($type, $actual, $description);
}
/**
@@ -435,6 +435,6 @@ protected function assertInternalType($type, $actual, $description = '')
*/
protected function fail($message)
{
- \PHPUnit_Framework_Assert::fail($message);
+ \PHPUnit\Framework\Assert::fail($message);
}
}
diff --git a/tests/cli/RunCest.php b/tests/cli/RunCest.php
index 9f29c477cc..2115a1ebdb 100644
--- a/tests/cli/RunCest.php
+++ b/tests/cli/RunCest.php
@@ -92,19 +92,6 @@ public function runXmlReportsInStrictMode(\CliGuy $I)
$I->dontSeeInThisFile('feature="');
}
- /**
- * @group reports
- *
- * @param CliGuy $I
- */
- public function runReportMode(\CliGuy $I)
- {
- $I->wantTo('try the reporting mode');
- $I->executeCommand('run dummy --report');
- $I->seeInShellOutput('FileExistsCept');
- $I->seeInShellOutput('........Ok');
- }
-
/**
* @group reports
*
@@ -112,7 +99,9 @@ public function runReportMode(\CliGuy $I)
*/
public function runCustomReport(\CliGuy $I)
{
- $I->wantTo('try the reporting mode');
+ if (\PHPUnit\Runner\Version::series() >= 7) {
+ throw new \Codeception\Exception\Skip('Not for PHPUnit 7');
+ }
$I->executeCommand('run dummy --report -c codeception_custom_report.yml');
$I->seeInShellOutput('FileExistsCept: Check config exists');
$I->dontSeeInShellOutput('Ok');
diff --git a/tests/cli/SecondTestIsExecutedWhenTheFirstTestFailsCest.php b/tests/cli/SecondTestIsExecutedWhenTheFirstTestFailsCest.php
index 8f47dc2322..846e8f48d3 100644
--- a/tests/cli/SecondTestIsExecutedWhenTheFirstTestFailsCest.php
+++ b/tests/cli/SecondTestIsExecutedWhenTheFirstTestFailsCest.php
@@ -14,6 +14,9 @@ public function testIsExecuted(CliGuy $I)
public function endTestEventIsEmitted(CliGuy $I)
{
+ if (\PHPUnit\Runner\Version::series() >= 7) {
+ throw new \Codeception\Exception\Skip('Not for PHPUnit 7');
+ }
$I->wantTo('see that all start and end events are emitted');
$I->amInPath('tests/data/first_test_fails');
$I->executeFailCommand('run --xml --no-ansi --report -o "reporters: report: CustomReporter"');
diff --git a/tests/cli/UnitCept.php b/tests/cli/UnitCept.php
index b7f67db005..02bd136769 100644
--- a/tests/cli/UnitCept.php
+++ b/tests/cli/UnitCept.php
@@ -12,7 +12,7 @@
$I->seeInThisFile('seeInThisFile('seeInThisFile('FailingTest::testMe');
} else {
$I->seeInThisFile('FailingTest::testMe');
diff --git a/tests/data/SimpleTest.php b/tests/data/SimpleTest.php
index 9dfbe781f0..74ef65cbe8 100755
--- a/tests/data/SimpleTest.php
+++ b/tests/data/SimpleTest.php
@@ -1,5 +1,5 @@
assertTrue(true);
diff --git a/tests/data/app/db b/tests/data/app/db
index c856afcf97..609cdc8eb1 100644
--- a/tests/data/app/db
+++ b/tests/data/app/db
@@ -1 +1 @@
-a:0:{}
\ No newline at end of file
+a:1:{s:6:"params";a:0:{}}
\ No newline at end of file
diff --git a/tests/data/claypit/c3.php b/tests/data/claypit/c3.php
index 9eedd0b471..80330a1ccd 100644
--- a/tests/data/claypit/c3.php
+++ b/tests/data/claypit/c3.php
@@ -19,7 +19,7 @@
$cookie = json_decode($cookie, true);
}
- if ($cookie) {
+ if ($cookie) {
foreach ($cookie as $key => $value) {
$_SERVER["HTTP_X_CODECEPTION_" . strtoupper($key)] = $value;
}
@@ -49,16 +49,20 @@ function __c3_error($message)
}
// phpunit codecoverage shimming
-if (class_exists('SebastianBergmann\CodeCoverage\CodeCoverage') and !class_exists('PHP_CodeCoverage')) {
- class_alias('SebastianBergmann\CodeCoverage\CodeCoverage', 'PHP_CodeCoverage');
- class_alias('SebastianBergmann\CodeCoverage\Report\Text', 'PHP_CodeCoverage_Report_Text');
- class_alias('SebastianBergmann\CodeCoverage\Report\PHP', 'PHP_CodeCoverage_Report_PHP');
- class_alias('SebastianBergmann\CodeCoverage\Report\Clover', 'PHP_CodeCoverage_Report_Clover');
- class_alias('SebastianBergmann\CodeCoverage\Report\Crap4j', 'PHP_CodeCoverage_Report_Crap4j');
- class_alias('SebastianBergmann\CodeCoverage\Report\Html\Facade', 'PHP_CodeCoverage_Report_HTML');
- class_alias('SebastianBergmann\CodeCoverage\Report\Xml\Facade', 'PHP_CodeCoverage_Report_XML');
- class_alias('SebastianBergmann\CodeCoverage\Exception', 'PHP_CodeCoverage_Exception');
+if (!class_exists('PHP_CodeCoverage') and class_exists('SebastianBergmann\CodeCoverage\CodeCoverage')) {
+ class_alias('SebastianBergmann\CodeCoverage\CodeCoverage', 'PHP_CodeCoverage');
+ class_alias('SebastianBergmann\CodeCoverage\Report\Text', 'PHP_CodeCoverage_Report_Text');
+ class_alias('SebastianBergmann\CodeCoverage\Report\PHP', 'PHP_CodeCoverage_Report_PHP');
+ class_alias('SebastianBergmann\CodeCoverage\Report\Clover', 'PHP_CodeCoverage_Report_Clover');
+ class_alias('SebastianBergmann\CodeCoverage\Report\Crap4j', 'PHP_CodeCoverage_Report_Crap4j');
+ class_alias('SebastianBergmann\CodeCoverage\Report\Html\Facade', 'PHP_CodeCoverage_Report_HTML');
+ class_alias('SebastianBergmann\CodeCoverage\Report\Xml\Facade', 'PHP_CodeCoverage_Report_XML');
+ class_alias('SebastianBergmann\CodeCoverage\Exception', 'PHP_CodeCoverage_Exception');
}
+// phpunit version
+if (!class_exists('PHPUnit_Runner_Version') && class_exists('PHPUnit\Runner\Version')) {
+ class_alias('PHPUnit\Runner\Version', 'PHPUnit_Runner_Version');
+}
// Autoload Codeception classes
if (!class_exists('\\Codeception\\Codecept')) {
@@ -205,14 +209,28 @@ function __c3_send_file($filename)
/**
* @param $filename
- * @return null|PHP_CodeCoverage
+ * @param bool $lock Lock the file for writing?
+ * @return [null|PHP_CodeCoverage|\SebastianBergmann\CodeCoverage\CodeCoverage, resource]
*/
- function __c3_factory($filename)
+ function __c3_factory($filename, $lock=false)
{
- $phpCoverage = is_readable($filename)
- ? unserialize(file_get_contents($filename))
- : new PHP_CodeCoverage();
-
+ $file = null;
+ if ($filename !== null && is_readable($filename)) {
+ if ($lock) {
+ $file = fopen($filename, 'r+');
+ if (flock($file, LOCK_EX)) {
+ $phpCoverage = unserialize(stream_get_contents($file));
+ } else {
+ __c3_error("Failed to acquire write-lock for $filename");
+ }
+ } else {
+ $phpCoverage = unserialize(file_get_contents($filename));
+ }
+
+ return array($phpCoverage, $file);
+ } else {
+ $phpCoverage = new PHP_CodeCoverage();
+ }
if (isset($_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_SUITE'])) {
$suite = $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_SUITE'];
@@ -233,7 +251,7 @@ function __c3_factory($filename)
__c3_error($e->getMessage());
}
- return $phpCoverage;
+ return array($phpCoverage, $file);
}
function __c3_exit()
@@ -267,12 +285,12 @@ function __c3_clear()
$route = ltrim(strrchr($_SERVER['REQUEST_URI'], '/'), '/');
- if ($route == 'clear') {
+ if ($route === 'clear') {
__c3_clear();
return __c3_exit();
}
- $codeCoverage = __c3_factory($complete_report);
+ list($codeCoverage, ) = __c3_factory($complete_report);
switch ($route) {
case 'html':
@@ -313,9 +331,9 @@ function __c3_clear()
}
} else {
- $codeCoverage = __c3_factory($current_report);
+ list($codeCoverage, ) = __c3_factory(null);
$codeCoverage->start(C3_CODECOVERAGE_TESTNAME);
- if (!array_key_exists('HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG', $_SERVER)) {
+ if (!array_key_exists('HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG', $_SERVER)) {
register_shutdown_function(
function () use ($codeCoverage, $current_report) {
@@ -326,7 +344,31 @@ function () use ($codeCoverage, $current_report) {
}
}
- file_put_contents($current_report, serialize($codeCoverage));
+ // This will either lock the existing report for writing and return it along with a file pointer,
+ // or return a fresh PHP_CodeCoverage object without a file pointer. We'll merge the current request
+ // into that coverage object, write it to disk, and release the lock. By doing this in the end of
+ // the request, we avoid this scenario, where Request 2 overwrites the changes from Request 1:
+ //
+ // Time ->
+ // Request 1 [ ]
+ // Request 2 [ ]
+ //
+ // In addition, by locking the file for exclusive writing, we make sure no other request try to
+ // read/write to the file at the same time as this request (leading to a corrupt file). flock() is a
+ // blocking call, so it waits until an exclusive lock can be acquired before continuing.
+
+ list($existingCodeCoverage, $file) = __c3_factory($current_report, true);
+ $existingCodeCoverage->merge($codeCoverage);
+
+ if ($file === null) {
+ file_put_contents($current_report, serialize($existingCodeCoverage), LOCK_EX);
+ } else {
+ fseek($file, 0);
+ fwrite($file, serialize($existingCodeCoverage));
+ fflush($file);
+ flock($file, LOCK_UN);
+ fclose($file);
+ }
}
);
}
diff --git a/tests/data/claypit/composer.json b/tests/data/claypit/composer.json
index 7943da330b..cbd6aa6713 100644
--- a/tests/data/claypit/composer.json
+++ b/tests/data/claypit/composer.json
@@ -1,5 +1,5 @@
{
"require-dev": {
- "codeception/c3": "@dev"
+ "codeception/c3": "2.0.x-dev"
}
}
\ No newline at end of file
diff --git a/tests/data/claypit/composer.lock b/tests/data/claypit/composer.lock
index 58142e547d..8d03452074 100644
--- a/tests/data/claypit/composer.lock
+++ b/tests/data/claypit/composer.lock
@@ -4,28 +4,32 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "2b7a5d38446cbc8d5d27c7192506b3bd",
- "content-hash": "6a872dd1556c4dbb351b2c49717ada75",
+ "hash": "eef34880c17415a11aaa8fa92231b4fc",
+ "content-hash": "1dcee5d81a786ce03ba3dcd9e47b7251",
"packages": [],
"packages-dev": [
{
"name": "codeception/c3",
- "version": "dev-master",
+ "version": "2.0.x-dev",
"source": {
"type": "git",
"url": "https://github.com/Codeception/c3.git",
- "reference": "0b67a51b109a0748aa76a7d71fe1b409903ecf54"
+ "reference": "c7348bbc82da82834fe237c5fb754003ac0fe782"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Codeception/c3/zipball/0b67a51b109a0748aa76a7d71fe1b409903ecf54",
- "reference": "0b67a51b109a0748aa76a7d71fe1b409903ecf54",
+ "url": "https://api.github.com/repos/Codeception/c3/zipball/c7348bbc82da82834fe237c5fb754003ac0fe782",
+ "reference": "c7348bbc82da82834fe237c5fb754003ac0fe782",
"shasum": ""
},
"require": {
+ "composer-plugin-api": "^1.0",
"php": ">=5.4.0"
},
- "type": "library",
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Codeception\\c3\\Installer"
+ },
"autoload": {
"psr-4": {
"Codeception\\c3\\": "."
@@ -36,9 +40,13 @@
"MIT"
],
"authors": [
+ {
+ "name": "Tiger Seo",
+ "email": "tiger.seo@gmail.com"
+ },
{
"name": "Michael Bodnarchuk",
- "email": "davert.php@resend.cc",
+ "email": "davert.php@codegyre.com",
"homepage": "http://codegyre.com"
}
],
@@ -48,7 +56,7 @@
"code coverage",
"codecoverage"
],
- "time": "2014-10-02 23:18:47"
+ "time": "2018-02-19 11:27:45"
}
],
"aliases": [],
diff --git a/tests/data/claypit/tests/_bootstrap.php b/tests/data/claypit/tests/_bootstrap.php
index 72f5b3a351..6ce6debfa1 100644
--- a/tests/data/claypit/tests/_bootstrap.php
+++ b/tests/data/claypit/tests/_bootstrap.php
@@ -1,7 +1,10 @@
testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
+ if ($this->testStatus == \PHPUnit\Runner\BaseTestRunner::STATUS_FAILURE) {
$this->write('×');
} else {
- if ($this->testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED) {
+ if ($this->testStatus == \PHPUnit\Runner\BaseTestRunner::STATUS_SKIPPED) {
$this->write('S');
} else {
- if ($this->testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE) {
+ if ($this->testStatus == \PHPUnit\Runner\BaseTestRunner::STATUS_INCOMPLETE) {
$this->write('I');
} else {
- if ($this->testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR) {
+ if ($this->testStatus == \PHPUnit\Runner\BaseTestRunner::STATUS_ERROR) {
$this->write('E');
} else {
$this->write('✔');
@@ -31,7 +31,7 @@ public function endTest(PHPUnit_Framework_Test $test, $time)
$this->write(" $name \n");
}
- public function printResult(\PHPUnit_Framework_TestResult $result)
+ public function printResult(\PHPUnit\Framework\TestResult $result)
{
}
diff --git a/tests/data/claypit/tests/dummy/AnotherTest.php b/tests/data/claypit/tests/dummy/AnotherTest.php
index b721615544..48491a8c78 100755
--- a/tests/data/claypit/tests/dummy/AnotherTest.php
+++ b/tests/data/claypit/tests/dummy/AnotherTest.php
@@ -1,5 +1,5 @@
assertTrue(true);
diff --git a/tests/data/claypit/tests/order/ParsedLoadedTest.php b/tests/data/claypit/tests/order/ParsedLoadedTest.php
index 24c47f2e9f..44c699b98d 100644
--- a/tests/data/claypit/tests/order/ParsedLoadedTest.php
+++ b/tests/data/claypit/tests/order/ParsedLoadedTest.php
@@ -1,7 +1,7 @@
write("\nSTARTED: $testName\n");
}
- public function endTest(PHPUnit_Framework_Test $test, $time)
+ public function endTest(PHPUnit\Framework\Test $test, $time)
{
$testName = \Codeception\Test\Descriptor::getTestAsString($test);
$this->write("\nENDED: $testName\n");
diff --git a/tests/data/included/jazz/pianist/tests/_helpers/TestHelper.php b/tests/data/included/jazz/pianist/tests/_helpers/TestHelper.php
index e9125517f5..6514a23997 100644
--- a/tests/data/included/jazz/pianist/tests/_helpers/TestHelper.php
+++ b/tests/data/included/jazz/pianist/tests/_helpers/TestHelper.php
@@ -6,6 +6,6 @@
class TestHelper extends \Codeception\Module
{
public function seeEquals($expected, $actual) {
- \PHPUnit_Framework_Assert::assertEquals($expected, $actual);
+ $this->assertEquals($expected, $actual);
}
}
diff --git a/tests/data/included/jazz/tests/_helpers/TestHelper.php b/tests/data/included/jazz/tests/_helpers/TestHelper.php
index 44c5968051..3ab1b26daf 100644
--- a/tests/data/included/jazz/tests/_helpers/TestHelper.php
+++ b/tests/data/included/jazz/tests/_helpers/TestHelper.php
@@ -6,6 +6,6 @@
class TestHelper extends \Codeception\Module
{
public function seeEquals($expected, $actual) {
- \PHPUnit_Framework_Assert::assertEquals($expected, $actual);
+ $this->assertEquals($expected, $actual);
}
}
diff --git a/tests/data/included_mix/tests/unit/SimpleTest.php b/tests/data/included_mix/tests/unit/SimpleTest.php
index 720ac2b98d..cec69fdfcb 100644
--- a/tests/data/included_mix/tests/unit/SimpleTest.php
+++ b/tests/data/included_mix/tests/unit/SimpleTest.php
@@ -1,6 +1,6 @@
assertEquals('PHPUnit_Framework_TestCase', PHPUnit_Framework_TestCase::class);
diff --git a/tests/data/php70Test b/tests/data/php70Test
index f16447a376..b25bca5cb3 100644
--- a/tests/data/php70Test
+++ b/tests/data/php70Test
@@ -1,6 +1,6 @@
nzWsQ(1-$6LWGf
z=J}2ll8W$&Ad12+A%Y;>W3McGU2ZbVNS8b8w;0RM%H9(;|2to1wTpLt7nH|$-`qW1
ze!0At`#D!+1=t_}0SG_<0uX=z1R(Hn3yicySyff>;?vMN?NiV1QJ*K-{g$Dd1~K)$
znnCisEKk;#2+7;MJgGKJ<7=Zu8cmZl+O--vYE|oc>x6u3oNPn~xt2ro9soxi4lxnoak+{S#7X$>qf&Q*Q3iqd1li-8~DkH
z7JifXycvDZuRIK>AMhlTyf80|E}57QtU2mfcK@n5R?zjS71CbE3iITE%{;SOH^_nU
zSZ~)%vfpmCSVWzu@YvMrM}<)#%@r;*9>9S5jvWNH=LWH?lnf?T^Pvh+f8wLh0>2us
z%Qpop^S%D{>@OUp7Sv)=r=~qjXovVG}vo4Ylhx<|8a}f<|*Y*LHUOz*dPD_2tWV=
z5P$##AOHafKmY;|m`8yxQW@d1#maN*#S6!Bw@T%$%@X@5ldbYj`O(gU(&u7E(6W`T
z$NrEQOw~W!*)EOO|E~n)jq++9JBXMd009U<00Izz00bZa0SG_<0uXp70VS1Q6=U~W
z$V*~c6DM~kMC*S^c_}Ebm4B7LSq2*fAOHafKmY;|fB*y_009U<00MI>kdrg)KlfEB
zW%V4}UCu;%S~}%W=al+6c9(#d)h2s)*ewCstTwJ1um2l@@|W_5@~hIA+YTZy2tWV=
z5P$##AOHafKmY;|fWX`cY)aBfxpHdzz3z{e-?!=R!1B+if1f?M;>OMQm9L6vNi9|!
zyH5k2?Dnjm?BJ~jZ*6~>l2+C#uH8M0Uc1rr8txCR8?BbNi=w0zDy%8$hvRhS!KDY$
z`ky`Y4;us^009U<00Izz00bZa0SG_<0=HOTDe4>6|F?LA(KQG_00Izz00bZa0SG_<
z0uX?JAmICd%mN5N00Izz00bZa0SG_<0uX?}?H7o?{}+|l?D>DUzpv;a1Rwwb2tWV=
c5P$##AOHafK;R=1$Vu6i754Z5*Bemxe=^p*-2eap
diff --git a/tests/facebook/FacebookTest.php b/tests/facebook/FacebookTest.php
index 23c636244b..001e39e450 100644
--- a/tests/facebook/FacebookTest.php
+++ b/tests/facebook/FacebookTest.php
@@ -8,7 +8,7 @@
use Codeception\Lib\Driver\Facebook as FacebookDriver;
use Codeception\Util\Stub;
-class FacebookTest extends \PHPUnit_Framework_TestCase
+class FacebookTest extends \PHPUnit\Framework\TestCase
{
protected $config = array(
'app_id' => '460287924057084',
diff --git a/tests/unit/C3Test.php b/tests/unit/C3Test.php
index 69b3bd0f3b..7bef8086d6 100644
--- a/tests/unit/C3Test.php
+++ b/tests/unit/C3Test.php
@@ -2,7 +2,7 @@
use Codeception\Configuration;
-class C3Test extends PHPUnit_Framework_TestCase
+class C3Test extends \PHPUnit\Framework\TestCase
{
/**
* @var string
diff --git a/tests/unit/Codeception/ApplicationTest.php b/tests/unit/Codeception/ApplicationTest.php
index f3b1d76997..5dc8c1b9cf 100644
--- a/tests/unit/Codeception/ApplicationTest.php
+++ b/tests/unit/Codeception/ApplicationTest.php
@@ -2,7 +2,7 @@
namespace Codeception;
-class ApplicationTest extends \PHPUnit_Framework_TestCase
+class ApplicationTest extends \PHPUnit\Framework\TestCase
{
public static function setUpBeforeClass()
diff --git a/tests/unit/Codeception/Command/BaseCommandRunner.php b/tests/unit/Codeception/Command/BaseCommandRunner.php
index 710e96b185..84c18dcd18 100644
--- a/tests/unit/Codeception/Command/BaseCommandRunner.php
+++ b/tests/unit/Codeception/Command/BaseCommandRunner.php
@@ -3,7 +3,7 @@
use Codeception\Application;
use Symfony\Component\Console\Tester\CommandTester;
-class BaseCommandRunner extends \PHPUnit_Framework_TestCase
+class BaseCommandRunner extends \PHPUnit\Framework\TestCase
{
/**
diff --git a/tests/unit/Codeception/Command/MyCustomCommandTest.php b/tests/unit/Codeception/Command/MyCustomCommandTest.php
index d4288e4471..0dd8a4fc0e 100644
--- a/tests/unit/Codeception/Command/MyCustomCommandTest.php
+++ b/tests/unit/Codeception/Command/MyCustomCommandTest.php
@@ -1,7 +1,7 @@
Bye world
Bye warcraft
');
try {
$this->constraint->evaluate($nodes->filter('p'), 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains(
"Failed asserting that any element by 'selector' on page /user",
$fail->getMessage()
@@ -44,7 +44,7 @@ public function testFailMessageResponseWhenMoreNodes()
$nodes = new Symfony\Component\DomCrawler\Crawler($html);
try {
$this->constraint->evaluate($nodes->filter('p'), 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains(
"Failed asserting that any element by 'selector' on page /user",
$fail->getMessage()
@@ -63,7 +63,7 @@ public function testFailMessageResponseWithoutUrl()
$nodes = new Symfony\Component\DomCrawler\Crawler('
Bye world
Bye warcraft
');
try {
$this->constraint->evaluate($nodes->filter('p'), 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains("Failed asserting that any element by 'selector'", $fail->getMessage());
$this->assertNotContains("Failed asserting that any element by 'selector' on page", $fail->getMessage());
return;
diff --git a/tests/unit/Codeception/Constraints/CrawlerNotConstraintTest.php b/tests/unit/Codeception/Constraints/CrawlerNotConstraintTest.php
index 21e90a7b84..17302e01ed 100644
--- a/tests/unit/Codeception/Constraints/CrawlerNotConstraintTest.php
+++ b/tests/unit/Codeception/Constraints/CrawlerNotConstraintTest.php
@@ -1,5 +1,5 @@
Bye world
Bye warcraft
');
try {
$this->constraint->evaluate($nodes->filter('p'), 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains("There was 'selector' element on page /user", $fail->getMessage());
$this->assertNotContains('+
Bye world
', $fail->getMessage());
$this->assertContains('+
Bye warcraft
', $fail->getMessage());
@@ -41,7 +41,7 @@ public function testFailMessageResponseWhenMoreNodes()
$nodes = new Symfony\Component\DomCrawler\Crawler($html);
try {
$this->constraint->evaluate($nodes->filter('p'), 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains("There was 'selector' element on page /user", $fail->getMessage());
$this->assertContains('+
warcraft 0
', $fail->getMessage());
$this->assertContains('+
warcraft 14
', $fail->getMessage());
@@ -56,7 +56,7 @@ public function testFailMessageResponseWithoutUrl()
$nodes = new Symfony\Component\DomCrawler\Crawler('
Bye world
Bye warcraft
');
try {
$this->constraint->evaluate($nodes->filter('p'), 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains("There was 'selector' element", $fail->getMessage());
$this->assertNotContains("There was 'selector' element on page /user", $fail->getMessage());
return;
diff --git a/tests/unit/Codeception/Constraints/WebDriverConstraintTest.php b/tests/unit/Codeception/Constraints/WebDriverConstraintTest.php
index 52da852d86..0560630c6b 100644
--- a/tests/unit/Codeception/Constraints/WebDriverConstraintTest.php
+++ b/tests/unit/Codeception/Constraints/WebDriverConstraintTest.php
@@ -1,7 +1,7 @@
constraint->evaluate($nodes, 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains(
"Failed asserting that any element by 'selector' on page /user",
$fail->getMessage()
@@ -42,7 +42,7 @@ public function testFailMessageResponseWithArraySelector()
$nodes = array(new TestedWebElement('Bye warcraft'));
try {
$this->constraint->evaluate($nodes, ['css' => 'p.mocked']);
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains(
"Failed asserting that any element by css 'p.mocked' on page /user",
$fail->getMessage()
@@ -61,7 +61,7 @@ public function testFailMessageResponseWhenMoreNodes()
}
try {
$this->constraint->evaluate($nodes, 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains(
"Failed asserting that any element by 'selector' on page /user",
$fail->getMessage()
@@ -80,7 +80,7 @@ public function testFailMessageResponseWithoutUrl()
$nodes = array(new TestedWebElement('Bye warcraft'), new TestedWebElement('Bye world'));
try {
$this->constraint->evaluate($nodes, 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains("Failed asserting that any element by 'selector'", $fail->getMessage());
$this->assertNotContains("Failed asserting that any element by 'selector' on page", $fail->getMessage());
return;
diff --git a/tests/unit/Codeception/Constraints/WebDriverNotConstraintTest.php b/tests/unit/Codeception/Constraints/WebDriverNotConstraintTest.php
index 51f1d2d94f..6e8bbe95ed 100644
--- a/tests/unit/Codeception/Constraints/WebDriverNotConstraintTest.php
+++ b/tests/unit/Codeception/Constraints/WebDriverNotConstraintTest.php
@@ -1,7 +1,7 @@
constraint->evaluate($nodes, 'selector');
- } catch (PHPUnit_Framework_AssertionFailedError $fail) {
+ } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
$this->assertContains("There was 'selector' element on page /user", $fail->getMessage());
$this->assertNotContains('+
diff --git a/docs/modules/AngularJS.md b/docs/modules/AngularJS.md
index e8396ce3de..e929cc721e 100644
--- a/docs/modules/AngularJS.md
+++ b/docs/modules/AngularJS.md
@@ -1,5 +1,6 @@
# AngularJS
+
Module for AngularJS testing, based on [WebDriver module](http://codeception.com/docs/modules/WebDriver) and [Protractor](http://angular.github.io/protractor/).
Performs **synchronization to ensure that page content is fully rendered**.
@@ -21,6 +22,7 @@ The same as for [WebDriver](http://codeception.com/docs/modules/WebDriver#Config
browser: firefox
script_timeout: 10
+
### Additional Features
Can perform matching elements by model. In this case you should provide a strict locator with `model` set.
@@ -36,15 +38,16 @@ $I->selectOption(['model' => 'customerId'], '3');
### _backupSession
*hidden API method, expected to be used from Helper classes*
-
+
Returns current WebDriver session for saving
* `return` RemoteWebDriver
+
### _capabilities
*hidden API method, expected to be used from Helper classes*
-
+
Change capabilities of WebDriver. Should be executed before starting a new browser session.
This method expects a function to be passed which returns array or [WebDriver Desired Capabilities](https://github.com/facebook/php-webdriver/blob/community/lib/Remote/DesiredCapabilities.php) object.
Additional [Chrome options](https://github.com/facebook/php-webdriver/wiki/ChromeOptions) (like adding extensions) can be passed as well.
@@ -87,10 +90,11 @@ In this case, please ensure that `\Helper\Acceptance` is loaded before WebDriver
* `param \Closure` $capabilityFunction
+
### _closeSession
*hidden API method, expected to be used from Helper classes*
-
+
Manually closes current WebDriver session.
```php
@@ -104,10 +108,11 @@ $this->getModule('WebDriver')->_closeSession($webDriver);
* `param` $webDriver (optional) a specific webdriver session instance
+
### _findClickable
*hidden API method, expected to be used from Helper classes*
-
+
Locates a clickable element.
Use it in Helpers or GroupObject or Extension classes:
@@ -129,10 +134,11 @@ $el = $module->_findClickable($topBar, 'Click Me');
* `param` $link a link text or locator to click
* `return` WebDriverElement
+
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -156,26 +162,29 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getCurrentUri
*hidden API method, expected to be used from Helper classes*
-
+
Uri of currently opened page.
* `return` string
@throws ModuleException
+
### _getUrl
*hidden API method, expected to be used from Helper classes*
-
+
Returns URL of a host.
@throws ModuleConfigException
+
### _initializeSession
*hidden API method, expected to be used from Helper classes*
-
+
Manually starts a new browser session.
```php
@@ -183,18 +192,21 @@ Manually starts a new browser session.
$this->getModule('WebDriver')->_initializeSession();
```
+
+
### _loadSession
*hidden API method, expected to be used from Helper classes*
-
+
Loads current RemoteWebDriver instance as a session
* `param RemoteWebDriver` $session
+
### _restart
*hidden API method, expected to be used from Helper classes*
-
+
Restarts a web browser.
Can be used with `_reconfigure` to open browser with different configuration
@@ -207,17 +219,19 @@ $this->getModule('WebDriver')->_restart(['browser' => $browser]); // reconfigure
* `param array` $config
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves HTML source of a page to a file
* `param` $filename
+
### _saveScreenshot
*hidden API method, expected to be used from Helper classes*
-
+
Saves screenshot of current page to a file
```php
@@ -225,19 +239,22 @@ $this->getModule('AngularJS')->_saveScreenshot(codecept_output_dir().'screenshot
```
* `param` $filename
-### acceptPopup
+### acceptPopup
+
Accepts the active JavaScript native popup window, as created by `window.alert`|`window.confirm`|`window.prompt`.
Don't confuse popups with modal windows,
as created by [various libraries](http://jster.net/category/windows-modals-popups).
-### amInsideAngularApp
+### amInsideAngularApp
+
Enables Angular mode (enabled by default).
Waits for Angular to finish rendering after each action.
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -250,8 +267,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnSubdomain
+### amOnSubdomain
+
Changes the subdomain for the 'url' configuration parameter.
Does not open a page; use `amOnPage` for that.
@@ -269,8 +287,10 @@ $I->amOnPage('/');
* `param` $subdomain
-### amOnUrl
+
+### amOnUrl
+
Open web page at the given absolute URL and sets its hostname as the base host.
``` php
@@ -280,14 +300,16 @@ $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart
?>
```
-### amOutsideAngularApp
+### amOutsideAngularApp
+
Disabled Angular mode.
Falls back to original WebDriver, in case web page does not contain Angular app.
-### appendField
+### appendField
+
Append the given text to the given element.
Can also add a selection to a select box.
@@ -302,8 +324,9 @@ $I->appendField('#myTextField', 'appended');
* `param string` $value
@throws \Codeception\Exception\ElementNotFound
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -316,12 +339,14 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### cancelPopup
+### cancelPopup
+
Dismisses the active JavaScript popup, as created by `window.alert`, `window.confirm`, or `window.prompt`.
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -332,8 +357,21 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### clearField
+
+Clears given field which isn't empty.
+
+``` php
+clearField('#username');
+```
+
+ * `param` $field
+
+
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -364,8 +402,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### clickWithLeftButton
+### clickWithLeftButton
+
Performs click with the left mouse button on an element.
If the first parameter `null` then the offset is relative to the actual mouse position.
If the second and third parameters are given,
@@ -386,8 +425,9 @@ $I->clickWithLeftButton(['css' => '.checkout'], 20, 50);
@throws \Codeception\Exception\ElementNotFound
-### clickWithRightButton
+### clickWithRightButton
+
Performs contextual click with the right mouse button on an element.
If the first parameter `null` then the offset is relative to the actual mouse position.
If the second and third parameters are given,
@@ -403,13 +443,14 @@ $I->clickWithRightButton(['css' => '.checkout'], 20, 50);
```
* `param string` $cssOrXPath css or xpath of the web element (body by default).
- * `param int` $offsetX
- * `param int` $offsetY
+ * `param int` $offsetX
+ * `param int` $offsetY
@throws \Codeception\Exception\ElementNotFound
-### closeTab
+### closeTab
+
Closes current browser tab and switches to previous active tab.
```php
@@ -419,14 +460,16 @@ $I->closeTab();
Can't be used with PhantomJS
-### debugWebDriverLogs
+### debugWebDriverLogs
+
Print out latest Selenium Logs in debug mode
* `param TestInterface` $test
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -455,8 +498,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -468,8 +512,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -477,8 +522,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -491,8 +537,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -504,8 +551,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -521,15 +569,17 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeElementInDOM
+### dontSeeElementInDOM
+
Opposite of `seeElementInDOM`.
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -540,8 +590,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -559,8 +610,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -601,14 +653,16 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInPageSource
+### dontSeeInPageSource
+
Checks that the page source doesn't contain the given string.
* `param` $text
-### dontSeeInPopup
+### dontSeeInPopup
+
Checks that the active JavaScript popup,
as created by `window.alert`|`window.confirm`|`window.prompt`, does NOT contain the given string.
@@ -616,8 +670,9 @@ as created by `window.alert`|`window.confirm`|`window.prompt`, does NOT contain
@throws \Codeception\Exception\ModuleException
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -628,14 +683,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -649,8 +707,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -662,15 +721,18 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### doubleClick
+
+### doubleClick
+
Performs a double-click on an element matched by CSS or XPath.
* `param` $cssOrXPath
@throws \Codeception\Exception\ElementNotFound
-### dragAndDrop
+### dragAndDrop
+
Performs a simple mouse drag-and-drop operation.
``` php
@@ -682,8 +744,28 @@ $I->dragAndDrop('#drag', '#drop');
* `param string` $source (CSS ID or XPath)
* `param string` $target (CSS ID or XPath)
-### executeInSelenium
+### executeAsyncJS
+
+Executes asynchronous JavaScript.
+A callback should be executed by JavaScript to exit from a script.
+Callback is passed as a last element in `arguments` array.
+Additional arguments can be passed as array in second parameter.
+
+```js
+// wait for 1200 milliseconds my running `setTimeout`
+* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
+
+$seconds = 1200; // or seconds are passed as argument
+$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
+```
+
+ * `param` $script
+ * `param array` $arguments
+
+
+### executeInSelenium
+
Low-level API method.
If Codeception commands are not enough, this allows you to use Selenium WebDriver methods directly:
@@ -700,8 +782,9 @@ If Codeception lacks a feature you need, please implement it and submit a patch.
* `param callable` $function
-### executeJS
+### executeJS
+
Executes custom JavaScript.
This example uses jQuery to get a value and assigns that value to a PHP variable:
@@ -709,13 +792,18 @@ This example uses jQuery to get a value and assigns that value to a PHP variable
```php
executeJS('return $("#myField").val()');
-?>
+
+// additional arguments can be passed as array
+// Example shows `Hello World` alert:
+$I->executeJS("window.alert(arguments[0])", ['Hello world']);
```
* `param` $script
+ * `param array` $arguments
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -728,8 +816,9 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -742,8 +831,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -751,8 +842,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -765,8 +857,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -790,16 +884,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -814,8 +910,10 @@ $value = $I->grabTextFrom('~grabValueFrom(['name' => 'username']);
* `param` $field
-### loadSessionSnapshot
+
+### loadSessionSnapshot
+
* `param string` $name
* `return` bool
-### makeScreenshot
+### makeScreenshot
+
Takes a screenshot of the current window and saves it to `tests/_output/debug`.
``` php
@@ -850,20 +951,24 @@ $I->makeScreenshot();
* `param` $name
-### maximizeWindow
+### maximizeWindow
+
Maximizes the current window.
-### moveBack
+### moveBack
+
Moves back in history.
-### moveForward
+### moveForward
+
Moves forward in history.
-### moveMouseOver
+### moveMouseOver
+
Move mouse over the first element matched by the given locator.
If the first parameter null then the page is used.
If the second and third parameters are given,
@@ -884,8 +989,9 @@ $I->moveMouseOver(['css' => '.checkout'], 20, 50);
@throws \Codeception\Exception\ElementNotFound
-### openNewTab
+### openNewTab
+
Opens a new browser tab (wherever it is possible) and switches to it.
```php
@@ -897,16 +1003,19 @@ Please note, that adblock can restrict creating such tabs.
Can't be used with PhantomJS
-### pauseExecution
+
+### pauseExecution
+
Pauses test execution in debug mode.
To proceed test press "ENTER" in console.
This method is useful while writing tests,
since it allows you to inspect the current page in the middle of a test case.
-### performOn
+### performOn
+
Waits for element and runs a sequence of actions inside its context.
Actions can be defined with array, callback, or `Codeception\Util\ActionSequence` instance.
@@ -949,8 +1058,9 @@ In 3rd argument you can set number a seconds to wait for element to appear
* `param` $actions
* `param int` $timeout
-### pressKey
+### pressKey
+
Presses the given key on the given element.
To specify a character and modifier (e.g. ctrl, alt, shift, meta), pass an array for $char with
the modifier as the first element and the character as the second.
@@ -971,12 +1081,14 @@ $I->pressKey('#name', array('ctrl', 'a'), \Facebook\WebDriver\WebDriverKeys::DEL
* `param` $char string|array Can be char or array with modifier. You can provide several chars.
@throws \Codeception\Exception\ElementNotFound
-### reloadPage
+### reloadPage
+
Reloads the current page.
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -984,8 +1096,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### resizeWindow
+### resizeWindow
+
Resize the current window.
``` php
@@ -997,12 +1110,14 @@ $I->resizeWindow(800, 600);
* `param int` $width
* `param int` $height
-### saveSessionSnapshot
+### saveSessionSnapshot
+
* `param string` $name
-### scrollTo
+### scrollTo
+
Move to the middle of the given element matched by the given locator.
Extra shift, calculated from the top-left corner of the element,
can be set by passing $offsetX and $offsetY parameters.
@@ -1017,8 +1132,9 @@ $I->scrollTo(['css' => '.checkout'], 20, 50);
* `param int` $offsetX
* `param int` $offsetY
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -1049,8 +1165,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -1063,8 +1180,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -1077,8 +1195,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -1091,8 +1210,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -1104,8 +1224,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -1125,8 +1246,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeElementInDOM
+### seeElementInDOM
+
Checks that the given element exists on the page, even it is invisible.
``` php
@@ -1138,8 +1260,9 @@ $I->seeElementInDOM('//form/input[type=hidden]');
* `param` $selector
* `param array` $attributes
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -1153,8 +1276,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -1172,8 +1296,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -1234,8 +1359,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInPageSource
+### seeInPageSource
+
Checks that the page source contains the given string.
```php
@@ -1245,8 +1371,9 @@ $I->seeInPageSource('seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -1278,8 +1407,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -1293,8 +1424,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -1306,11 +1438,13 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
+
### seeNumberOfElementsInDOM
__not documented__
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -1322,8 +1456,10 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### selectOption
+
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1354,8 +1490,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1369,8 +1506,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, optionally with the given form
values. Give the form fields values as an array. Note that hidden fields
can't be accessed.
@@ -1529,8 +1668,9 @@ For example, given the following HTML:
* `param` $params
* `param` $button
-### switchToIFrame
+### switchToIFrame
+
Switch to another frame on the page.
Example:
@@ -1550,8 +1690,9 @@ $I->switchToIFrame();
* `param string|null` $name
-### switchToNextTab
+### switchToNextTab
+
Switches to next browser tab.
An offset can be specified.
@@ -1567,8 +1708,9 @@ Can't be used with PhantomJS
* `param int` $offset 1
-### switchToPreviousTab
+### switchToPreviousTab
+
Switches to previous browser tab.
An offset can be specified.
@@ -1584,8 +1726,9 @@ Can't be used with PhantomJS
* `param int` $offset 1
-### switchToWindow
+### switchToWindow
+
Switch to another window identified by name.
The window can only be identified by name. If the $name parameter is blank, the parent window will be used.
@@ -1621,16 +1764,18 @@ $I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webd
* `param string|null` $name
-### typeInPopup
+### typeInPopup
+
Enters text into a native JavaScript prompt popup, as created by `window.prompt`.
* `param` $keys
@throws \Codeception\Exception\ModuleException
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1641,22 +1786,25 @@ $I->uncheckOption('#notify');
* `param` $option
-### unselectOption
+### unselectOption
+
Unselect an option in the given select box.
* `param` $select
* `param` $option
-### wait
+### wait
+
Wait for $timeout seconds.
* `param int|float` $timeout secs
@throws \Codeception\Exception\TestRuntimeException
-### waitForElement
+### waitForElement
+
Waits up to $timeout seconds for an element to appear on the page.
If the element doesn't appear, a timeout exception is thrown.
@@ -1671,8 +1819,9 @@ $I->click('#agree_button');
* `param int` $timeout seconds
@throws \Exception
-### waitForElementChange
+### waitForElementChange
+
Waits up to $timeout seconds for the given element to change.
Element "change" is determined by a callback function which is called repeatedly
until the return value evaluates to true.
@@ -1691,8 +1840,9 @@ $I->waitForElementChange('#menu', function(WebDriverElement $el) {
* `param int` $timeout seconds
@throws \Codeception\Exception\ElementNotFound
-### waitForElementNotVisible
+### waitForElementNotVisible
+
Waits up to $timeout seconds for the given element to become invisible.
If element stays visible, a timeout exception is thrown.
@@ -1706,8 +1856,9 @@ $I->waitForElementNotVisible('#agree_button', 30); // secs
* `param int` $timeout seconds
@throws \Exception
-### waitForElementVisible
+### waitForElementVisible
+
Waits up to $timeout seconds for the given element to be visible on the page.
If element doesn't appear, a timeout exception is thrown.
@@ -1722,8 +1873,9 @@ $I->click('#agree_button');
* `param int` $timeout seconds
@throws \Exception
-### waitForJS
+### waitForJS
+
Executes JavaScript and waits up to $timeout seconds for it to return true.
In this example we will wait up to 60 seconds for all jQuery AJAX requests to finish.
@@ -1737,8 +1889,9 @@ $I->waitForJS("return $.active == 0;", 60);
* `param string` $script
* `param int` $timeout seconds
-### waitForText
+### waitForText
+
Waits up to $timeout seconds for the given string to appear on the page.
Can also be passed a selector to search in, be as specific as possible when using selectors.
@@ -1757,4 +1910,4 @@ $I->waitForText('foo', 30, '.title'); // secs
* `param string` $selector optional
@throws \Exception
-
diff --git a/docs/modules/Apc.md b/docs/modules/Apc.md
index 56bf326cf7..f0e08816f2 100644
--- a/docs/modules/Apc.md
+++ b/docs/modules/Apc.md
@@ -1,5 +1,6 @@
# Apc
+
This module interacts with the [Alternative PHP Cache (APC)](http://php.net/manual/en/intro.apcu.php)
using either _APCu_ or _APC_ extension.
@@ -20,10 +21,11 @@ Performs a cleanup by flushing all values after each test run.
Be sure you don't use the production server to connect.
+
## Actions
### dontSeeInApc
-
+
Checks item in APC(u) doesn't exist or is the same as expected.
Examples:
@@ -41,12 +43,14 @@ $I->dontSeeInApc('users_count', 200);
* `param string|string[]` $key
* `param mixed` $value
-### flushApc
+### flushApc
+
Clears the APC(u) cache
-### grabValueFromApc
+### grabValueFromApc
+
Grabs value from APC(u) by key.
Example:
@@ -59,8 +63,9 @@ $users_count = $I->grabValueFromApc('users_count');
* `param string|string[]` $key
-### haveInApc
+### haveInApc
+
Stores an item `$value` with `$key` on the APC(u).
Examples:
@@ -87,8 +92,9 @@ $I->haveInApc($entries, null);
* `param mixed` $value
* `param int` $expiration
-### seeInApc
+### seeInApc
+
Checks item in APC(u) exists and the same as expected.
Examples:
@@ -106,4 +112,4 @@ $I->seeInApc('users_count', 200);
* `param string|string[]` $key
* `param mixed` $value
-
diff --git a/docs/modules/DataFactory.md b/docs/modules/DataFactory.md
index c6b6908d6a..a1ac2161b6 100644
--- a/docs/modules/DataFactory.md
+++ b/docs/modules/DataFactory.md
@@ -1,5 +1,6 @@
# DataFactory
+
DataFactory allows you to easily generate and create test data using [**FactoryMuffin**](https://github.com/thephpleague/factory-muffin).
DataFactory uses an ORM of your application to define, save and cleanup data. Thus, should be used with ORM or Framework modules.
@@ -8,7 +9,6 @@ This module requires packages installed:
```json
{
"league/factory-muffin": "^3.0",
- "league/factory-muffin-faker": "^1.0"
}
```
@@ -29,7 +29,7 @@ $fm->define(User::class)->setDefinitions([
// generate a profile and return its Id
'profile_id' => 'factory|Profile'
-);
+]);
```
Configure this module to load factory definitions from a directory.
@@ -48,7 +48,7 @@ modules:
(you can also use Laravel5 and Phalcon).
In this example factories are loaded from `tests/_support/factories` directory. Please note that this directory is relative from the codeception.yml file (so for Yii2 it would be codeception/_support/factories).
- * You should create this directory manually and create PHP files in it with factories definitions following [official documentation](https://github.com/thephpleague/factory-muffin#usage).
+You should create this directory manually and create PHP files in it with factories definitions following [official documentation](https://github.com/thephpleague/factory-muffin#usage).
In cases you want to use data from database inside your factory definitions you can define them in Helper.
For instance, if you use Doctrine, this allows you to access `EntityManager` inside a definition.
@@ -113,7 +113,7 @@ In case your ORM expects a related record itself (Doctrine) then you should use
## Actions
### have
-
+
Generates and saves a record,.
```php
@@ -123,13 +123,14 @@ $I->have('User', ['is_active' => true]); // creates active user
Returns an instance of created user.
- * `param` $name
+ * `param string` $name
* `param array` $extraAttrs
* `return` object
-### haveMultiple
+### haveMultiple
+
Generates and saves a record multiple times.
```php
@@ -137,10 +138,29 @@ $I->haveMultiple('User', 10); // create 10 users
$I->haveMultiple('User', 10, ['is_active' => true]); // create 10 active users
```
- * `param` $name
- * `param` $times
+ * `param string` $name
+ * `param int` $times
* `param array` $extraAttrs
* `return` \object[]
-
+
+### make
+
+Generates a record instance.
+
+This does not save it in the database. Use `have` for that.
+
+```php
+$user = $I->make('User'); // return User instance
+$activeUser = $I->make('User', ['is_active' => true]); // return active user instance
+```
+
+Returns an instance of created user without creating a record in database.
+
+ * `param string` $name
+ * `param array` $extraAttrs
+
+ * `return` object
+
+
diff --git a/docs/modules/Db.md b/docs/modules/Db.md
index 73af2a0217..38015e04c4 100644
--- a/docs/modules/Db.md
+++ b/docs/modules/Db.md
@@ -1,5 +1,6 @@
# Db
+
Access a database.
The most important function of this module is to clean a database before each test.
@@ -169,10 +170,11 @@ SELECT COUNT(*) FROM `users` WHERE `name` = 'Davert' AND `email` LIKE 'davert%'
* dbh - contains the PDO connection
* driver - contains the Connection Driver
+
## Actions
### dontSeeInDatabase
-
+
Effect is opposite to ->seeInDatabase
Asserts that there is no record with the given column values in a database.
@@ -197,8 +199,9 @@ Supported operators: `<`, `>`, `>=`, `<=`, `!=`, `like`.
* `param string` $table
* `param array` $criteria
-### grabColumnFromDatabase
+### grabColumnFromDatabase
+
Fetches all values from the column in database.
Provide table name, desired column and criteria.
@@ -213,8 +216,9 @@ $mails = $I->grabColumnFromDatabase('users', 'email', array('name' => 'RebOOter'
* `return` array
-### grabFromDatabase
+### grabFromDatabase
+
Fetches a single column value from a database.
Provide table name, desired column and criteria.
@@ -226,7 +230,7 @@ Comparison expressions can be used as well:
```php
grabFromDatabase('posts', ['num_comments >=' => 100']);
+$post = $I->grabFromDatabase('posts', ['num_comments >=' => 100]);
$user = $I->grabFromDatabase('users', ['email like' => 'miles%']);
```
@@ -236,8 +240,10 @@ Supported operators: `<`, `>`, `>=`, `<=`, `!=`, `like`.
* `param string` $column
* `param array` $criteria
-### grabNumRecords
+
+### grabNumRecords
+
Returns the number of rows in a database
* `param string` $table Table name
@@ -245,8 +251,9 @@ Returns the number of rows in a database
* `return` int
-### haveInDatabase
+### haveInDatabase
+
Inserts an SQL record into a database. This record will be erased after the test.
```php
@@ -260,11 +267,13 @@ $I->haveInDatabase('users', array('name' => 'miles', 'email' => 'miles@davis.com
* `return integer` $id
+
### isPopulated
__not documented__
-### seeInDatabase
+### seeInDatabase
+
Asserts that a row with the given column values exists.
Provide table name and column values.
@@ -287,8 +296,9 @@ Supported operators: `<`, `>`, `>=`, `<=`, `!=`, `like`.
* `param string` $table
* `param array` $criteria
-### seeNumRecords
+### seeNumRecords
+
Asserts that the given number of records were found in the database.
```php
@@ -301,8 +311,9 @@ $I->seeNumRecords(1, 'users', ['name' => 'davert'])
* `param string` $table Table name
* `param array` $criteria Search criteria [Optional]
-### updateInDatabase
+### updateInDatabase
+
Update an SQL record into a database.
```php
@@ -315,4 +326,4 @@ $I->updateInDatabase('users', array('isAdmin' => true), array('email' => 'miles@
* `param array` $data
* `param array` $criteria
-
diff --git a/docs/modules/Doctrine2.md b/docs/modules/Doctrine2.md
index ad96027ae1..0defeecd03 100644
--- a/docs/modules/Doctrine2.md
+++ b/docs/modules/Doctrine2.md
@@ -1,5 +1,6 @@
# Doctrine2
+
Access the database using [Doctrine2 ORM](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/).
When used with Zend Framework 2 or Symfony2, Doctrine's Entity Manager is automatically retrieved from Service Locator.
@@ -45,18 +46,20 @@ tests will run much faster and will be isolated from each other.
## Actions
### dontSeeInRepository
-
+
Flushes changes to database and performs `findOneBy()` call for current repository.
* `param` $entity
* `param array` $params
-### flushToDatabase
+### flushToDatabase
+
Performs $em->flush();
-### grabEntitiesFromRepository
+### grabEntitiesFromRepository
+
Selects entities from repository.
It builds query based on array of parameters.
You can use entity associations to build complex queries.
@@ -74,8 +77,9 @@ $users = $I->grabEntitiesFromRepository('AppBundle:User', array('name' => 'daver
* `param array` $params
* `return` array
-### grabEntityFromRepository
+### grabEntityFromRepository
+
Selects a single entity from repository.
It builds query based on array of parameters.
You can use entity associations to build complex queries.
@@ -93,8 +97,9 @@ $user = $I->grabEntityFromRepository('User', array('id' => '1234'));
* `param array` $params
* `return` object
-### grabFromRepository
+### grabFromRepository
+
Selects field value from repository.
It builds query based on array of parameters.
You can use entity associations to build complex queries.
@@ -113,8 +118,9 @@ $email = $I->grabFromRepository('User', 'email', array('name' => 'davert'));
* `param array` $params
* `return` array
-### haveFakeRepository
+### haveFakeRepository
+
Mocks the repository.
With this action you can redefine any method of any repository.
@@ -135,8 +141,9 @@ which will always return the NULL value.
* `param` $classname
* `param array` $methods
-### haveInRepository
+### haveInRepository
+
Persists record into repository.
This method crates an entity, and sets its properties directly (via reflection).
Setters of entity won't be executed, but you can create almost any entity and save it to database.
@@ -146,8 +153,9 @@ Returns id using `getId` of newly created entity.
$I->haveInRepository('Entity\User', array('name' => 'davert'));
```
-### persistEntity
+### persistEntity
+
Adds entity to repository and flushes. You can redefine it's properties with the second parameter.
Example:
@@ -161,8 +169,9 @@ $I->persistEntity($user, array('name' => 'Miles'));
* `param` $obj
* `param array` $values
-### seeInRepository
+### seeInRepository
+
Flushes changes to database, and executes a query with parameters defined in an array.
You can use entity associations to build complex queries.
@@ -181,4 +190,4 @@ Fails if record for given criteria can\'t be found,
* `param` $entity
* `param array` $params
-
diff --git a/docs/modules/FTP.md b/docs/modules/FTP.md
index 9a5c164300..f6558008da 100644
--- a/docs/modules/FTP.md
+++ b/docs/modules/FTP.md
@@ -1,5 +1,7 @@
# FTP
+
+
Works with SFTP/FTP servers.
In order to test the contents of a specific file stored on any remote FTP/SFTP system
@@ -79,18 +81,20 @@ For SFTP, add [phpseclib](http://phpseclib.sourceforge.net/) to require list.
tmp: 'tests/_data/ftp'
cleanup: false
+
This module extends the Filesystem module, file contents methods are inherited from this module.
## Actions
### amInPath
-
+
Enters a directory on the ftp system - FTP root directory is used by default
* `param` $path
-### cleanDir
+### cleanDir
+
Erases directory contents on the FTP/SFTP server
``` php
@@ -101,15 +105,17 @@ $I->cleanDir('logs');
* `param` $dirname
-### copyDir
+### copyDir
+
Currently not supported in this module, overwrite inherited method
* `param` $src
* `param` $dst
-### deleteDir
+### deleteDir
+
Deletes directory with all subdirectories on the remote FTP/SFTP server
``` php
@@ -120,8 +126,9 @@ $I->deleteDir('vendor');
* `param` $dirname
-### deleteFile
+### deleteFile
+
Deletes a file on the remote FTP/SFTP system
``` php
@@ -132,27 +139,31 @@ $I->deleteFile('composer.lock');
* `param` $filename
-### deleteThisFile
+### deleteThisFile
+
Deletes a file
-### dontSeeFileFound
+### dontSeeFileFound
+
Checks if file does not exist in path on the remote FTP/SFTP system
* `param` $filename
* `param string` $path
-### dontSeeFileFoundMatches
+### dontSeeFileFoundMatches
+
Checks if file does not exist in path on the remote FTP/SFTP system, using regular expression as filename.
DOES NOT OPEN the file when it's exists
* `param` $regex
* `param string` $path
-### dontSeeInThisFile
+### dontSeeInThisFile
+
Checks If opened file doesn't contain `text` in it
``` php
@@ -164,8 +175,9 @@ $I->dontSeeInThisFile('codeception/codeception');
* `param string` $text
-### grabDirectory
+### grabDirectory
+
Grabber method to return current working directory
```php
@@ -176,8 +188,9 @@ $pwd = $I->grabDirectory();
* `return` string
-### grabFileCount
+### grabFileCount
+
Grabber method for returning file/folders count in directory
```php
@@ -191,8 +204,9 @@ $count = $I->grabFileCount('TEST', false); // Include . .. .thumbs.db
* `param bool` $ignore - suppress '.', '..' and '.thumbs.db'
* `return` int
-### grabFileList
+### grabFileList
+
Grabber method for returning file/folders listing in an array
```php
@@ -206,8 +220,9 @@ $count = $I->grabFileList('TEST', false); // Include . .. .thumbs.db
* `param bool` $ignore - suppress '.', '..' and '.thumbs.db'
* `return` array
-### grabFileModified
+### grabFileModified
+
Grabber method to return last modified timestamp
```php
@@ -219,8 +234,9 @@ $time = $I->grabFileModified('test.txt');
* `param` $filename
* `return` bool
-### grabFileSize
+### grabFileSize
+
Grabber method to return file size
```php
@@ -232,8 +248,9 @@ $size = $I->grabFileSize('test.txt');
* `param` $filename
* `return` bool
-### loginAs
+### loginAs
+
Change the logged in user mid-way through your test, this closes the
current connection to the server and initialises and new connection.
@@ -250,8 +267,9 @@ $I->loginAs('user','password');
* `param String` $user
* `param String` $password
-### makeDir
+### makeDir
+
Create a directory on the server
``` php
@@ -262,8 +280,9 @@ $I->makeDir('vendor');
* `param` $dirname
-### openFile
+### openFile
+
Opens a file (downloads from the remote FTP/SFTP system to a tmp directory for processing)
and stores it's content.
@@ -278,8 +297,9 @@ $I->seeInThisFile('codeception/codeception');
* `param` $filename
-### renameDir
+### renameDir
+
Rename/Move directory on the FTP/SFTP server
``` php
@@ -291,8 +311,9 @@ $I->renameDir('vendor', 'vendor_old');
* `param` $dirname
* `param` $rename
-### renameFile
+### renameFile
+
Rename/Move file on the FTP/SFTP server
``` php
@@ -304,8 +325,9 @@ $I->renameFile('composer.lock', 'composer_old.lock');
* `param` $filename
* `param` $rename
-### seeFileContentsEqual
+### seeFileContentsEqual
+
Checks the strict matching of file contents.
Unlike `seeInThisFile` will fail if file has something more than expected lines.
Better to use with HEREDOC strings.
@@ -320,8 +342,9 @@ $I->seeFileContentsEqual('3192');
* `param string` $text
-### seeFileFound
+### seeFileFound
+
Checks if file exists in path on the remote FTP/SFTP system.
DOES NOT OPEN the file when it's exists
@@ -334,8 +357,9 @@ $I->seeFileFound('UserModel.php','app/models');
* `param` $filename
* `param string` $path
-### seeFileFoundMatches
+### seeFileFoundMatches
+
Checks if file exists in path on the remote FTP/SFTP system, using regular expression as filename.
DOES NOT OPEN the file when it's exists
@@ -348,8 +372,9 @@ $I->seeFileFoundMatches('/^UserModel_([0-9]{6}).php$/','app/models');
* `param` $regex
* `param string` $path
-### seeInThisFile
+### seeInThisFile
+
Checks If opened file has `text` in it.
Usage:
@@ -363,8 +388,9 @@ $I->seeInThisFile('codeception/codeception');
* `param string` $text
-### seeNumberNewLines
+### seeNumberNewLines
+
Checks If opened file has the `number` of new lines.
Usage:
@@ -378,14 +404,16 @@ $I->seeNumberNewLines(5);
* `param int` $number New lines
-### seeThisFileMatches
+### seeThisFileMatches
+
Checks that contents of currently opened file matches $regex
* `param string` $regex
-### writeToFile
+### writeToFile
+
Saves contents to tmp file and uploads the FTP/SFTP system.
Overwrites current file on server if exists.
@@ -398,4 +426,4 @@ $I->writeToFile('composer.json', 'some data here');
* `param` $filename
* `param` $contents
-
diff --git a/docs/modules/Facebook.md b/docs/modules/Facebook.md
index 0b60d0ccb7..76a61b8dc5 100644
--- a/docs/modules/Facebook.md
+++ b/docs/modules/Facebook.md
@@ -1,5 +1,6 @@
# Facebook
+
Provides testing for projects integrated with Facebook API.
Relies on Facebook's tool Test User API.
@@ -74,69 +75,79 @@ $I->see('Welcome, ' . $fbUserFirstName);
## Actions
### grabFacebookTestUserAccessToken
-
+
Returns the test user access token.
* `return` string
-### grabFacebookTestUserEmail
+### grabFacebookTestUserEmail
+
Returns the test user email.
* `return` string
-### grabFacebookTestUserId
+### grabFacebookTestUserId
+
Returns the test user id.
* `return` string
-### grabFacebookTestUserLoginUrl
+### grabFacebookTestUserLoginUrl
+
Returns URL for test user auto-login.
* `return` string
-### grabFacebookTestUserName
+### grabFacebookTestUserName
+
Returns the test user name.
* `return` string
+
### grabFacebookTestUserPassword
__not documented__
-### haveFacebookTestUserAccount
+### haveFacebookTestUserAccount
+
Get facebook test user be created.
*Please, note that the test user is created only at first invoke, unless $renew arguments is true.*
* `param bool` $renew true if the test user should be recreated
-### haveTestUserLoggedInOnFacebook
+### haveTestUserLoggedInOnFacebook
+
Get facebook test user be logged in on facebook.
This is done by going to facebook.com
@throws ModuleConfigException
-### postToFacebookAsTestUser
+### postToFacebookAsTestUser
+
Please, note that you must have publish_actions permission to be able to publish to user's feed.
* `param array` $params
+
### seePostOnFacebookWithAttachedPlace
Please, note that you must have publish_actions permission to be able to publish to user's feed.
* `param string` $placeId Place identifier to be verified against user published posts
+
### seePostOnFacebookWithMessage
Please, note that you must have publish_actions permission to be able to publish to user's feed.
* `param string` $message published post to be verified against the actual post on facebook
-
diff --git a/docs/modules/Laravel5.md b/docs/modules/Laravel5.md
index 21cb6566da..3275146e2c 100644
--- a/docs/modules/Laravel5.md
+++ b/docs/modules/Laravel5.md
@@ -1,5 +1,7 @@
# Laravel5
+
+
This module allows you to run functional tests for Laravel 5.1+
It should **not** be used for acceptance tests.
See the Acceptance tests section below for more details.
@@ -86,7 +88,7 @@ modules:
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -110,10 +112,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -130,10 +133,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -153,10 +157,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -184,10 +189,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -195,15 +201,17 @@ $this->getModule('Laravel5')->_savePageSource(codecept_output_dir().'page.html')
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amLoggedAs
+### amLoggedAs
+
Set the currently logged in user for the application.
Takes either an object that implements the User interface or
an array of credentials.
@@ -223,8 +231,9 @@ $I->amLoggedAs( new User );
* `param` string|null $driver The authentication driver for Laravel <= 5.1.*, guard name for Laravel >= 5.2
* `return` void
-### amOnAction
+### amOnAction
+
Opens web page by action name
``` php
@@ -236,8 +245,9 @@ $I->amOnAction('PostsController@index');
* `param` $action
* `param array` $params
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -250,8 +260,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnRoute
+### amOnRoute
+
Opens web page using route name and parameters.
``` php
@@ -263,8 +274,9 @@ $I->amOnRoute('posts.create');
* `param` $routeName
* `param array` $params
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -277,8 +289,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### callArtisan
+### callArtisan
+
Call an Artisan command.
``` php
@@ -291,8 +304,9 @@ $I->callArtisan('command:name', ['parameter' => 'value']);
* `param string` $command
* `param array` $parameters
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -303,8 +317,9 @@ $I->checkOption('#agree');
* `param` $option
-### clearApplicationHandlers
+### clearApplicationHandlers
+
Clear the registered application handlers.
``` php
@@ -313,8 +328,10 @@ $I->clearApplicationHandlers();
?>
```
-### click
+
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -345,8 +362,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -363,8 +381,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### disableEvents
+### disableEvents
+
Disable events for the next requests.
This method does not disable model events.
To disable model events you have to use the disableModelEvents() method.
@@ -375,8 +394,9 @@ $I->disableEvents();
?>
```
-### disableExceptionHandling
+### disableExceptionHandling
+
Disable Laravel exception handling.
``` php
@@ -385,8 +405,9 @@ $I->disableExceptionHandling();
?>
```
-### disableMiddleware
+### disableMiddleware
+
Disable middleware for the next requests.
``` php
@@ -395,8 +416,9 @@ $I->disableMiddleware();
?>
```
-### disableModelEvents
+### disableModelEvents
+
Disable model events for the next requests.
``` php
@@ -405,8 +427,9 @@ $I->disableModelEvents();
?>
```
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -435,14 +458,16 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeAuthentication
+### dontSeeAuthentication
+
Check that user is not authenticated.
You can specify the guard that should be use for Laravel >= 5.2.
* `param string|null` $guard
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -454,8 +479,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -463,8 +489,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -477,8 +504,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -490,8 +518,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -507,8 +536,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeEventTriggered
+### dontSeeEventTriggered
+
Make sure events did not fire during the test.
``` php
@@ -521,8 +551,9 @@ $I->dontSeeEventTriggered(['App\MyEvent', 'App\MyOtherEvent']);
```
* `param` $events
-### dontSeeFormErrors
+### dontSeeFormErrors
+
Assert that there are no form errors bound to the View.
``` php
@@ -533,8 +564,9 @@ $I->dontSeeFormErrors();
* `return` bool
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -545,8 +577,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -564,8 +597,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -606,8 +640,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -618,14 +653,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -639,8 +677,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -652,8 +691,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeRecord
+
+### dontSeeRecord
+
Checks that record does not exist in database.
You can pass the name of a database table or the class name of an Eloquent model as the first argument.
@@ -668,8 +709,9 @@ $I->dontSeeRecord('App\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### dontSeeResponseCodeIs
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -681,8 +723,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### enableExceptionHandling
+### enableExceptionHandling
+
Enable Laravel exception handling.
``` php
@@ -691,8 +734,9 @@ $I->enableExceptionHandling();
?>
```
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -705,14 +749,16 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### getApplication
+### getApplication
+
Provides access the Laravel application object.
* `return` \Illuminate\Foundation\Application
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -725,8 +771,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -734,8 +782,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -748,8 +797,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -773,8 +824,9 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabNumRecords
+### grabNumRecords
+
Retrieves number of records from database
You can pass the name of a database table or the class name of an Eloquent model as the first argument.
@@ -790,16 +842,18 @@ $I->grabNumRecords('App\User', array('name' => 'davert'));
* `return` integer
* `[Part]` orm
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabRecord
+### grabRecord
+
Retrieves record from database
If you pass the name of a database table as the first argument, this method returns an array.
You can also pass the class name of an Eloquent model, in that case this method returns an Eloquent model.
@@ -816,8 +870,9 @@ $record = $I->grabRecord('App\User', array('name' => 'davert')); // returns Eloq
* `return` array|EloquentModel
* `[Part]` orm
-### grabService
+### grabService
+
Return an instance of a class from the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -838,8 +893,9 @@ $service = $I->grabService('foo');
* `param` string $class
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -854,14 +910,17 @@ $value = $I->grabTextFrom('~have('App\User', [], 'admin');
* `param string` $name
* `[Part]` orm
-### haveApplicationHandler
+### haveApplicationHandler
+
Register a handler than can be used to modify the Laravel application object after it is initialized.
The Laravel application object will be passed as an argument to the handler.
@@ -894,8 +954,9 @@ $I->haveApplicationHandler(function($app) {
* `param` $handler
-### haveBinding
+### haveBinding
+
Add a binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -908,8 +969,9 @@ $I->haveBinding('My\Interface', 'My\Implementation');
* `param` $abstract
* `param` $concrete
-### haveContextualBinding
+### haveContextualBinding
+
Add a contextual binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -928,8 +990,9 @@ $app->when('My\Class')
* `param` $abstract
* `param` $implementation
-### haveHttpHeader
+### haveHttpHeader
+
Sets the HTTP header to the passed value - which is used on
subsequent HTTP requests through PhpBrowser.
@@ -956,8 +1019,9 @@ $I->haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### haveInstance
+### haveInstance
+
Add an instance binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -970,8 +1034,9 @@ $I->haveInstance('My\Class', new My\Class());
* `param` $abstract
* `param` $instance
-### haveMultiple
+### haveMultiple
+
Use Laravel's model factory to create multiple models.
Can only be used with Laravel 5.1 and later.
@@ -990,8 +1055,9 @@ $I->haveMultiple('App\User', 10, [], 'admin');
* `param string` $name
* `[Part]` orm
-### haveRecord
+### haveRecord
+
Inserts record into the database.
If you pass the name of a database table as the first argument, this method returns an integer ID.
You can also pass the class name of an Eloquent model, in that case this method returns an Eloquent model.
@@ -1008,8 +1074,9 @@ $user = $I->haveRecord('App\User', array('name' => 'Davert')); // returns Eloque
* `return` integer|EloquentModel
* `[Part]` orm
-### haveSingleton
+### haveSingleton
+
Add a singleton binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -1022,18 +1089,21 @@ $I->haveSingleton('My\Interface', 'My\Singleton');
* `param` $abstract
* `param` $concrete
-### logout
+### logout
+
Logout user.
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -1041,8 +1111,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -1073,14 +1144,16 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeAuthentication
+### seeAuthentication
+
Checks that a user is authenticated.
You can specify the guard that should be use for Laravel >= 5.2.
* `param string|null` $guard
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -1093,8 +1166,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -1107,8 +1181,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentActionIs
+### seeCurrentActionIs
+
Checks that current url matches action
``` php
@@ -1119,8 +1194,9 @@ $I->seeCurrentActionIs('PostsController@index');
* `param` $action
-### seeCurrentRouteIs
+### seeCurrentRouteIs
+
Checks that current url matches route
``` php
@@ -1130,8 +1206,9 @@ $I->seeCurrentRouteIs('posts.index');
```
* `param` $routeName
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -1144,8 +1221,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -1157,8 +1235,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -1178,8 +1257,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeEventTriggered
+### seeEventTriggered
+
Make sure events fired during the test.
``` php
@@ -1192,8 +1272,9 @@ $I->seeEventTriggered(['App\MyEvent', 'App\MyOtherEvent']);
```
* `param` $events
-### seeFormErrorMessage
+### seeFormErrorMessage
+
Assert that a specific form error message is set in the view.
If you want to assert that there is a form error message for a specific key
@@ -1211,8 +1292,9 @@ $I->seeFormErrorMessage('username', 'Invalid Username');
* `param string` $key
* `param string|null` $expectedErrorMessage
-### seeFormErrorMessages
+### seeFormErrorMessages
+
Assert that specific form error messages are set in the view.
This method calls `seeFormErrorMessage` for each entry in the `$bindings` array.
@@ -1227,8 +1309,9 @@ $I->seeFormErrorMessages([
```
* `param array` $bindings
-### seeFormHasErrors
+### seeFormHasErrors
+
Assert that form errors are bound to the View.
``` php
@@ -1239,8 +1322,9 @@ $I->seeFormHasErrors();
* `return` bool
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -1254,8 +1338,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -1273,8 +1358,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -1335,8 +1421,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSession
+### seeInSession
+
Assert that a session variable exists.
``` php
@@ -1350,8 +1437,9 @@ $I->seeInSession('key', 'value');
* `param` mixed|null $value
* `return` void
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -1362,8 +1450,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -1374,8 +1463,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -1389,8 +1480,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumRecords
+### seeNumRecords
+
Checks that number of given records were found in database.
You can pass the name of a database table or the class name of an Eloquent model as the first argument.
@@ -1406,8 +1498,9 @@ $I->seeNumRecords(1, 'App\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -1419,8 +1512,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -1432,12 +1526,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeRecord
+### seeRecord
+
Checks that record exists in database.
You can pass the name of a database table or the class name of an Eloquent model as the first argument.
@@ -1452,8 +1549,9 @@ $I->seeRecord('App\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -1466,8 +1564,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### seeSessionHasValues
+### seeSessionHasValues
+
Assert that the session has a given list of values.
``` php
@@ -1480,8 +1579,9 @@ $I->seeSessionHasValues(['key1' => 'value1', 'key2' => 'value2']);
* `param` array $bindings
* `return` void
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1512,8 +1612,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1522,8 +1623,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1543,8 +1645,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1562,12 +1665,14 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setApplication
+### setApplication
+
* `param` $app
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1581,8 +1686,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1753,8 +1860,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1770,8 +1878,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1782,4 +1891,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/Lumen.md b/docs/modules/Lumen.md
index ba4f8cd863..9b463ec1aa 100644
--- a/docs/modules/Lumen.md
+++ b/docs/modules/Lumen.md
@@ -1,5 +1,7 @@
# Lumen
+
+
This module allows you to run functional tests for Lumen.
Please try it and leave your feedback.
@@ -41,7 +43,7 @@ Please try it and leave your feedback.
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -65,10 +67,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -85,10 +88,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -108,10 +112,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -139,10 +144,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -150,15 +156,17 @@ $this->getModule('Lumen')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amLoggedAs
+### amLoggedAs
+
Set the authenticated user for the next request.
This will not persist between multiple requests.
@@ -166,8 +174,9 @@ This will not persist between multiple requests.
* `param` string|null $driver The authentication driver for Lumen <= 5.1.*, guard name for Lumen >= 5.2
* `return` void
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -180,8 +189,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnRoute
+### amOnRoute
+
Opens web page using route name and parameters.
```php
@@ -193,8 +203,9 @@ $I->amOnRoute('homepage');
* `param` $routeName
* `param array` $params
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -207,8 +218,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -219,8 +231,9 @@ $I->checkOption('#agree');
* `param` $option
-### clearApplicationHandlers
+### clearApplicationHandlers
+
Clear the registered application handlers.
``` php
@@ -229,8 +242,10 @@ $I->clearApplicationHandlers();
?>
```
-### click
+
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -261,8 +276,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -279,8 +295,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -309,12 +326,14 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeAuthentication
+### dontSeeAuthentication
+
Check that user is not authenticated.
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -326,8 +345,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -335,8 +355,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -349,8 +370,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -362,8 +384,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -379,8 +402,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -391,8 +415,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -410,8 +435,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -452,8 +478,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -464,14 +491,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -485,8 +515,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -498,8 +529,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeRecord
+
+### dontSeeRecord
+
Checks that record does not exist in database.
You can pass the name of a database table or the class name of an Eloquent model as the first argument.
@@ -514,8 +547,9 @@ $I->dontSeeRecord('App\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### dontSeeResponseCodeIs
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -527,8 +561,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -541,14 +576,16 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### getApplication
+### getApplication
+
Provides access the Lumen application object.
* `return` \Laravel\Lumen\Application
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -561,8 +598,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -570,8 +609,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -584,8 +624,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -609,16 +651,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabRecord
+### grabRecord
+
Retrieves record from database
If you pass the name of a database table as the first argument, this method returns an array.
You can also pass the class name of an Eloquent model, in that case this method returns an Eloquent model.
@@ -635,8 +679,9 @@ $record = $I->grabRecord('App\User', array('name' => 'davert')); // returns Eloq
* `return` array|EloquentModel
* `[Part]` orm
-### grabService
+### grabService
+
Return an instance of a class from the IoC Container.
Example
@@ -657,8 +702,9 @@ $service = $I->grabService('foo');
* `param` string $class
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -673,14 +719,17 @@ $value = $I->grabTextFrom('~have('App\User', [], 'admin');
* `param string` $name
* `[Part]` orm
-### haveApplicationHandler
+### haveApplicationHandler
+
Register a handler than can be used to modify the Laravel application object after it is initialized.
The Laravel application object will be passed as an argument to the handler.
@@ -713,8 +763,9 @@ $I->haveApplicationHandler(function($app) {
* `param` $handler
-### haveBinding
+### haveBinding
+
Add a binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -727,8 +778,9 @@ $I->haveBinding('My\Interface', 'My\Implementation');
* `param` $abstract
* `param` $concrete
-### haveContextualBinding
+### haveContextualBinding
+
Add a contextual binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -747,8 +799,9 @@ $app->when('My\Class')
* `param` $abstract
* `param` $implementation
-### haveHttpHeader
+### haveHttpHeader
+
Sets the HTTP header to the passed value - which is used on
subsequent HTTP requests through PhpBrowser.
@@ -775,8 +828,9 @@ $I->haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### haveInstance
+### haveInstance
+
Add an instance binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -789,8 +843,9 @@ $I->haveInstance('My\Class', new My\Class());
* `param` $abstract
* `param` $instance
-### haveMultiple
+### haveMultiple
+
Use Laravel's model factory to create multiple models.
Can only be used with Lumen 5.1 and later.
@@ -809,8 +864,9 @@ $I->haveMultiple('App\User', 10, [], 'admin');
* `param string` $name
* `[Part]` orm
-### haveRecord
+### haveRecord
+
Inserts record into the database.
If you pass the name of a database table as the first argument, this method returns an integer ID.
You can also pass the class name of an Eloquent model, in that case this method returns an Eloquent model.
@@ -827,8 +883,9 @@ $user = $I->haveRecord('App\User', array('name' => 'Davert')); // returns Eloque
* `return` integer|EloquentModel
* `[Part]` orm
-### haveSingleton
+### haveSingleton
+
Add a singleton binding to the Laravel service container.
(https://laravel.com/docs/master/container)
@@ -841,14 +898,16 @@ $I->haveSingleton('My\Interface', 'My\Singleton');
* `param` $abstract
* `param` $concrete
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -856,8 +915,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -888,12 +948,14 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeAuthentication
+### seeAuthentication
+
Checks that user is authenticated.
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -906,8 +968,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -920,8 +983,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -934,8 +998,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -947,8 +1012,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -968,8 +1034,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -983,8 +1050,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -1002,8 +1070,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -1064,8 +1133,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -1076,8 +1146,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -1088,8 +1159,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -1103,8 +1176,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -1116,8 +1190,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -1129,12 +1204,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeRecord
+### seeRecord
+
Checks that record exists in database.
You can pass the name of a database table or the class name of an Eloquent model as the first argument.
@@ -1149,8 +1227,9 @@ $I->seeRecord('App\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -1163,8 +1242,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1195,8 +1275,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1205,8 +1286,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1226,8 +1308,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1245,12 +1328,14 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setApplication
+### setApplication
+
* `param \Laravel\Lumen\Application` $app
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1264,8 +1349,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1436,8 +1523,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1453,8 +1541,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1465,4 +1554,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/Memcache.md b/docs/modules/Memcache.md
index cef10c55c7..94b0665620 100644
--- a/docs/modules/Memcache.md
+++ b/docs/modules/Memcache.md
@@ -1,5 +1,6 @@
# Memcache
+
Connects to [memcached](http://www.memcached.org/) using either _Memcache_ or _Memcached_ extension.
Performs a cleanup by flushing all values after each test run.
@@ -30,14 +31,16 @@ Be sure you don't use the production server to connect.
* **memcache** - instance of _Memcache_ or _Memcached_ object
+
## Actions
### clearMemcache
-
+
Flushes all Memcached data.
-### dontSeeInMemcached
+### dontSeeInMemcached
+
Checks item in Memcached doesn't exist or is the same as expected.
Examples:
@@ -55,8 +58,9 @@ $I->dontSeeInMemcached('users_count', 200);
* `param` $key
* `param` $value
-### grabValueFromMemcached
+### grabValueFromMemcached
+
Grabs value from memcached by key.
Example:
@@ -70,16 +74,18 @@ $users_count = $I->grabValueFromMemcached('users_count');
* `param` $key
* `return` array|string
-### haveInMemcached
+### haveInMemcached
+
Stores an item `$value` with `$key` on the Memcached server.
* `param string` $key
* `param mixed` $value
* `param int` $expiration
-### seeInMemcached
+### seeInMemcached
+
Checks item in Memcached exists and the same as expected.
Examples:
@@ -97,4 +103,4 @@ $I->seeInMemcached('users_count', 200);
* `param` $key
* `param` $value
-
diff --git a/docs/modules/Phalcon.md b/docs/modules/Phalcon.md
index c4da09e670..7106ebf920 100644
--- a/docs/modules/Phalcon.md
+++ b/docs/modules/Phalcon.md
@@ -1,5 +1,6 @@
# Phalcon
+
This module provides integration with [Phalcon framework](http://www.phalconphp.com/) (3.x).
Please try it and leave your feedback.
@@ -70,7 +71,7 @@ modules:
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -94,10 +95,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -114,10 +116,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -137,10 +140,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -168,10 +172,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -179,8 +184,9 @@ $this->getModule('Phalcon')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### addServiceToContainer
+### addServiceToContainer
+
Registers a service in the services container and resolve it. This record will be erased after the test.
Recommended to use for unit testing.
@@ -199,15 +205,17 @@ $filter = $I->addServiceToContainer('answer', function () {
* `return` mixed|null
* `[Part]` services
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -220,8 +228,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnRoute
+### amOnRoute
+
Opens web page using route name and parameters.
``` php
@@ -233,8 +242,9 @@ $I->amOnRoute('posts.create');
* `param string` $routeName
* `param array` $params
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -247,8 +257,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -259,8 +270,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -291,8 +303,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -309,8 +322,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -339,8 +353,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -352,8 +367,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -361,8 +377,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -375,8 +392,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -388,8 +406,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -405,8 +424,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -417,8 +437,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -436,8 +457,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -478,8 +500,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -490,14 +513,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -511,8 +537,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -524,8 +551,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeRecord
+
+### dontSeeRecord
+
Checks that record does not exist in database.
``` php
@@ -538,8 +567,9 @@ $I->dontSeeRecord('App\Models\Categories', ['name' => 'Testing']);
* `param array` $attributes Model attributes
* `[Part]` orm
-### dontSeeResponseCodeIs
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -551,8 +581,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -565,15 +596,17 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### getApplication
+### getApplication
+
Provides access the Phalcon application object.
@see \Codeception\Lib\Connector\Phalcon::getApplication
* `return` \Phalcon\Application|\Phalcon\Mvc\Micro
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -586,8 +619,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -595,8 +630,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -609,8 +645,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -634,16 +672,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabRecord
+### grabRecord
+
Retrieves record from database
``` php
@@ -656,8 +696,9 @@ $category = $I->grabRecord('App\Models\Categories', ['name' => 'Testing']);
* `param array` $attributes Model attributes
* `[Part]` orm
-### grabServiceFromContainer
+### grabServiceFromContainer
+
Resolves the service based on its configuration from Phalcon's DI container
Recommended to use for unit testing.
@@ -665,8 +706,9 @@ Recommended to use for unit testing.
* `param array` $parameters Parameters [Optional]
* `[Part]` services
-### grabServiceFromDi
+### grabServiceFromDi
+
Alias for `grabServiceFromContainer`.
Note: Deprecated. Will be removed in Codeception 2.3.
@@ -675,8 +717,9 @@ Note: Deprecated. Will be removed in Codeception 2.3.
* `param array` $parameters Parameters [Optional]
* `[Part]` services
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -691,14 +734,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### haveInSession
+### haveInSession
+
Sets value to session. Use for authorization.
* `param string` $key
* `param mixed` $val
-### haveRecord
+### haveRecord
+
Inserts record into the database.
``` php
@@ -747,8 +795,9 @@ $I->haveRecord('App\Models\Categories', ['name' => 'Testing']');
* `param array` $attributes Model attributes
* `[Part]` orm
-### haveServiceInDi
+### haveServiceInDi
+
Alias for `addServiceToContainer`.
Note: Deprecated. Will be removed in Codeception 2.3.
@@ -759,14 +808,16 @@ Note: Deprecated. Will be removed in Codeception 2.3.
* `return` mixed|null
* `[Part]` services
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -774,8 +825,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -806,8 +858,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -820,8 +873,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -834,8 +888,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentRouteIs
+### seeCurrentRouteIs
+
Checks that current url matches route
``` php
@@ -845,8 +900,9 @@ $I->seeCurrentRouteIs('posts.index');
```
* `param string` $routeName
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -859,8 +915,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -872,8 +929,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -893,8 +951,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -908,8 +967,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -927,8 +987,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -989,8 +1050,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSession
+### seeInSession
+
Checks that session contains value.
If value is `null` checks that session has key.
@@ -1004,8 +1066,9 @@ $I->seeInSession('key', 'value');
* `param string` $key
* `param mixed` $value
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -1016,8 +1079,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -1028,8 +1092,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -1043,8 +1109,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -1056,8 +1123,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -1069,12 +1137,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeRecord
+### seeRecord
+
Checks that record exists in database.
``` php
@@ -1087,8 +1158,9 @@ $I->seeRecord('App\Models\Categories', ['name' => 'Testing']);
* `param array` $attributes Model attributes
* `[Part]` orm
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -1101,8 +1173,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### seeSessionHasValues
+### seeSessionHasValues
+
Assert that the session has a given list of values.
``` php
@@ -1115,8 +1188,9 @@ $I->seeSessionHasValues(['key1' => 'value1', 'key2' => 'value2']);
* `param` array $bindings
* `return` void
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1147,8 +1221,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1157,8 +1232,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1178,8 +1254,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1197,8 +1274,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1212,8 +1290,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1384,8 +1464,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1401,8 +1482,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1413,4 +1495,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/PhpBrowser.md b/docs/modules/PhpBrowser.md
index 37a5317e9a..fad0a6a363 100644
--- a/docs/modules/PhpBrowser.md
+++ b/docs/modules/PhpBrowser.md
@@ -1,5 +1,6 @@
# PhpBrowser
+
Uses [Guzzle](http://guzzlephp.org/) to interact with your application over CURL.
Module works over CURL and requires **PHP CURL extension** to be enabled.
@@ -13,6 +14,7 @@ If test fails stores last shown page in 'output' dir.
* Stability: **stable**
* Contact: codeception@codeception.com
+
## Configuration
* url *required* - start url of your app
@@ -25,6 +27,7 @@ If test fails stores last shown page in 'output' dir.
* verify - ...
* .. those and other [Guzzle Request options](http://docs.guzzlephp.org/en/latest/request-options.html)
+
### Example (`acceptance.suite.yml`)
modules:
@@ -47,6 +50,7 @@ If test fails stores last shown page in 'output' dir.
Secure: true
HttpOnly: false
+
All SSL certification checks are disabled by default.
Use Guzzle request options to configure certifications and others.
@@ -59,12 +63,13 @@ Properties:
* `guzzle` - contains [Guzzle](http://guzzlephp.org/) client instance: `\GuzzleHttp\Client`
* `client` - Symfony BrowserKit instance.
+
## Actions
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -88,10 +93,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -108,10 +114,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -131,10 +138,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -162,10 +170,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -173,15 +182,17 @@ $this->getModule('PhpBrowser')->_savePageSource(codecept_output_dir().'page.html
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -194,8 +205,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnSubdomain
+### amOnSubdomain
+
Changes the subdomain for the 'url' configuration parameter.
Does not open a page; use `amOnPage` for that.
@@ -213,8 +225,10 @@ $I->amOnPage('/');
* `param` $subdomain
-### amOnUrl
+
+### amOnUrl
+
Open web page at the given absolute URL and sets its hostname as the base host.
``` php
@@ -224,8 +238,9 @@ $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart
?>
```
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -238,8 +253,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -250,8 +266,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -282,8 +299,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -300,8 +318,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -330,8 +349,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -343,8 +363,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -352,8 +373,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -366,8 +388,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -379,8 +402,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -396,8 +420,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -408,8 +433,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -427,8 +453,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -469,8 +496,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -481,14 +509,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -502,8 +533,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -515,8 +547,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeResponseCodeIs
+
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -528,8 +562,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### executeInGuzzle
+### executeInGuzzle
+
Low-level API method.
If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly
@@ -548,8 +583,9 @@ If Codeception lacks important Guzzle Client methods, implement them and submit
* `param callable` $function
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -562,8 +598,9 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -576,8 +613,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -585,8 +624,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -599,8 +639,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -624,16 +666,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -648,14 +692,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -697,8 +746,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -729,8 +779,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -743,8 +794,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -757,8 +809,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -771,8 +824,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -784,8 +838,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -805,8 +860,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -820,8 +876,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -839,8 +896,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -901,8 +959,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -913,8 +972,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -925,8 +985,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -940,8 +1002,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -953,8 +1016,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -966,12 +1030,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -984,8 +1051,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1016,8 +1084,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1026,8 +1095,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1047,8 +1117,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1066,8 +1137,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1081,15 +1153,18 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### setHeader
+
+### setHeader
+
Alias to `haveHttpHeader`
* `param` $name
* `param` $value
-### submitForm
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1260,8 +1335,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1277,8 +1353,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1289,4 +1366,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/Queue.md b/docs/modules/Queue.md
index 391a5bce87..3a97a89fdc 100644
--- a/docs/modules/Queue.md
+++ b/docs/modules/Queue.md
@@ -1,5 +1,7 @@
# Queue
+
+
Works with Queue servers.
Testing with a selection of remote/local queueing services, including Amazon's SQS service
@@ -113,10 +115,11 @@ service.
'type': 'aws',
'region': 'us-west-2'
+
## Actions
### addMessageToQueue
-
+
Add a message to a queue/tube
```php
@@ -128,8 +131,9 @@ $I->addMessageToQueue('this is a messages', 'default');
* `param string` $message Message Body
* `param string` $queue Queue Name
-### clearQueue
+### clearQueue
+
Clear all messages of the queue/tube
```php
@@ -140,8 +144,9 @@ $I->clearQueue('default');
* `param string` $queue Queue Name
-### dontSeeEmptyQueue
+### dontSeeEmptyQueue
+
Check if a queue/tube is NOT empty of all messages
```php
@@ -152,8 +157,9 @@ $I->dontSeeEmptyQueue('default');
* `param string` $queue Queue Name
-### dontSeeQueueExists
+### dontSeeQueueExists
+
Check if a queue/tube does NOT exist on the queueing server.
```php
@@ -164,8 +170,9 @@ $I->dontSeeQueueExists('default');
* `param string` $queue Queue Name
-### dontSeeQueueHasCurrentCount
+### dontSeeQueueHasCurrentCount
+
Check if a queue/tube does NOT have a given current number of messages
```php
@@ -177,8 +184,9 @@ $I->dontSeeQueueHasCurrentCount('default', 10);
* `param string` $queue Queue Name
* `param int` $expected Number of messages expected
-### dontSeeQueueHasTotalCount
+### dontSeeQueueHasTotalCount
+
Check if a queue/tube does NOT have a given total number of messages
```php
@@ -190,8 +198,9 @@ $I->dontSeeQueueHasTotalCount('default', 10);
* `param string` $queue Queue Name
* `param int` $expected Number of messages expected
-### grabQueueCurrentCount
+### grabQueueCurrentCount
+
Grabber method to get the current number of messages on the queue/tube (pending/ready)
```php
@@ -203,8 +212,9 @@ Grabber method to get the current number of messages on the queue/tube (pending/
* `return` int Count
-### grabQueueTotalCount
+### grabQueueTotalCount
+
Grabber method to get the total number of messages on the queue/tube
```php
@@ -217,8 +227,9 @@ Grabber method to get the total number of messages on the queue/tube
* `return` int Count
-### grabQueues
+### grabQueues
+
Grabber method to get the list of queues/tubes on the server
```php
@@ -229,8 +240,9 @@ $queues = $I->grabQueues();
* `return` array List of Queues/Tubes
-### seeEmptyQueue
+### seeEmptyQueue
+
Check if a queue/tube is empty of all messages
```php
@@ -241,8 +253,9 @@ $I->seeEmptyQueue('default');
* `param string` $queue Queue Name
-### seeQueueExists
+### seeQueueExists
+
Check if a queue/tube exists on the queueing server.
```php
@@ -253,8 +266,9 @@ $I->seeQueueExists('default');
* `param string` $queue Queue Name
-### seeQueueHasCurrentCount
+### seeQueueHasCurrentCount
+
Check if a queue/tube has a given current number of messages
```php
@@ -266,8 +280,9 @@ $I->seeQueueHasCurrentCount('default', 10);
* `param string` $queue Queue Name
* `param int` $expected Number of messages expected
-### seeQueueHasTotalCount
+### seeQueueHasTotalCount
+
Check if a queue/tube has a given total number of messages
```php
@@ -279,4 +294,4 @@ $I->seeQueueHasTotalCount('default', 10);
* `param string` $queue Queue Name
* `param int` $expected Number of messages expected
-
diff --git a/docs/modules/REST.md b/docs/modules/REST.md
index a3468404bc..6798cf5831 100644
--- a/docs/modules/REST.md
+++ b/docs/modules/REST.md
@@ -1,5 +1,6 @@
# REST
+
Module for testing REST WebService.
This module can be used either with frameworks or PHPBrowser.
@@ -35,10 +36,11 @@ This module requires PHPBrowser or any of Framework modules enabled.
Conflicts with SOAP module
+
## Actions
### amAWSAuthenticated
-
+
Allows to send REST request using AWS Authorization
Only works with PhpBrowser
Example
@@ -61,16 +63,18 @@ $I->amAWSAuthenticated();
* `param array` $additionalAWSConfig
@throws ModuleException
-### amBearerAuthenticated
+### amBearerAuthenticated
+
Adds Bearer authentication via access token.
* `param` $accessToken
* `[Part]` json
* `[Part]` xml
-### amDigestAuthenticated
+### amDigestAuthenticated
+
Adds Digest authentication via username/password.
* `param` $username
@@ -78,8 +82,9 @@ Adds Digest authentication via username/password.
* `[Part]` json
* `[Part]` xml
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Adds HTTP authentication via username/password.
* `param` $username
@@ -87,8 +92,9 @@ Adds HTTP authentication via username/password.
* `[Part]` json
* `[Part]` xml
-### amNTLMAuthenticated
+### amNTLMAuthenticated
+
Adds NTLM authentication via username/password.
Requires client to be Guzzle >=6.3.0
Out of scope for functional modules.
@@ -106,8 +112,9 @@ $I->amNTLMAuthenticated('jon_snow', 'targaryen');
* `[Part]` json
* `[Part]` xml
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -126,8 +133,9 @@ $I->sendPOST('some-other-page.php');
* `[Part]` json
* `[Part]` xml
-### dontSeeBinaryResponseEquals
+### dontSeeBinaryResponseEquals
+
Checks if the hash of a binary response is not the same as provided.
```php
@@ -142,8 +150,9 @@ Opposite to `seeBinaryResponseEquals`
* `[Part]` json
* `[Part]` xml
-### dontSeeHttpHeader
+### dontSeeHttpHeader
+
Checks over the given HTTP header and (optionally)
its value, asserting that are not there
@@ -152,8 +161,9 @@ its value, asserting that are not there
* `[Part]` json
* `[Part]` xml
-### dontSeeResponseCodeIs
+### dontSeeResponseCodeIs
+
Checks that response code is not equal to provided value.
```php
@@ -168,37 +178,42 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `[Part]` xml
* `param` $code
-### dontSeeResponseContains
+### dontSeeResponseContains
+
Checks whether last response do not contain text.
* `param` $text
* `[Part]` json
* `[Part]` xml
-### dontSeeResponseContainsJson
+### dontSeeResponseContainsJson
+
Opposite to seeResponseContainsJson
* `[Part]` json
* `param array` $json
-### dontSeeResponseJsonMatchesJsonPath
+### dontSeeResponseJsonMatchesJsonPath
+
Opposite to seeResponseJsonMatchesJsonPath
* `param string` $jsonPath
* `[Part]` json
-### dontSeeResponseJsonMatchesXpath
+### dontSeeResponseJsonMatchesXpath
+
Opposite to seeResponseJsonMatchesXpath
* `param string` $xpath
* `[Part]` json
-### dontSeeResponseMatchesJsonType
+### dontSeeResponseMatchesJsonType
+
Opposite to `seeResponseMatchesJsonType`.
* `[Part]` json
@@ -207,8 +222,9 @@ Opposite to `seeResponseMatchesJsonType`.
* `param null` $jsonPath optionally set specific path to structure with JsonPath
* `Available since` 2.1.3
-### dontSeeXmlResponseEquals
+### dontSeeXmlResponseEquals
+
Checks XML response does not equal to provided XML.
Comparison is done by canonicalizing both xml`s.
@@ -217,8 +233,9 @@ Parameter can be passed either as XmlBuilder, DOMDocument, DOMNode, XML string,
* `param` $xml
* `[Part]` xml
-### dontSeeXmlResponseIncludes
+### dontSeeXmlResponseIncludes
+
Checks XML response does not include provided XML.
Comparison is done by canonicalizing both xml`s.
Parameter can be passed either as XmlBuilder, DOMDocument, DOMNode, XML string, or array (if no attributes).
@@ -226,8 +243,9 @@ Parameter can be passed either as XmlBuilder, DOMDocument, DOMNode, XML string,
* `param` $xml
* `[Part]` xml
-### dontSeeXmlResponseMatchesXpath
+### dontSeeXmlResponseMatchesXpath
+
Checks whether XML response does not match XPath
```php
@@ -237,8 +255,9 @@ $I->dontSeeXmlResponseMatchesXpath('//root/user[@id=1]');
* `[Part]` xml
* `param` $xpath
-### grabAttributeFromXmlElement
+### grabAttributeFromXmlElement
+
Finds and returns attribute of element.
Element is matched by either CSS or XPath
@@ -247,16 +266,18 @@ Element is matched by either CSS or XPath
* `return` string
* `[Part]` xml
-### grabDataFromJsonResponse
+### grabDataFromJsonResponse
+
Deprecated since 2.0.9 and removed since 2.1.0
* `param` $path
@throws ModuleException
@deprecated
-### grabDataFromResponseByJsonPath
+### grabDataFromResponseByJsonPath
+
Returns data from the current JSON response using [JSONPath](http://goessner.net/articles/JsonPath/) as selector.
JsonPath is XPath equivalent for querying Json structures.
Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/).
@@ -280,8 +301,9 @@ $I->sendPUT('/user', array('id' => $firstUserId[0], 'name' => 'davert'));
@throws \Exception
* `[Part]` json
-### grabHttpHeader
+### grabHttpHeader
+
Returns the value of the specified header name
* `param` $name
@@ -291,8 +313,9 @@ Returns the value of the specified header name
* `[Part]` json
* `[Part]` xml
-### grabResponse
+### grabResponse
+
Returns current response so that it can be used in next scenario steps.
Example:
@@ -309,8 +332,9 @@ $I->sendPUT('/user', array('id' => $user_id, 'name' => 'davert'));
* `[Part]` json
* `[Part]` xml
-### grabTextContentFromXmlElement
+### grabTextContentFromXmlElement
+
Finds and returns text contents of element.
Element is matched by either CSS or XPath
@@ -318,8 +342,9 @@ Element is matched by either CSS or XPath
* `return` string
* `[Part]` xml
-### haveHttpHeader
+### haveHttpHeader
+
Sets HTTP header valid for all next requests. Use `deleteHeader` to unset it
```php
@@ -334,8 +359,9 @@ $I->haveHttpHeader('Content-Type', 'application/json');
* `[Part]` json
* `[Part]` xml
-### seeBinaryResponseEquals
+### seeBinaryResponseEquals
+
Checks if the hash of a binary response is exactly the same as provided.
Parameter can be passed as any hash string supported by hash(), with an
optional second parameter to specify the hash type, which defaults to md5.
@@ -370,8 +396,9 @@ $I->seeBinaryResponseEquals(hash("sha256", base64_decode($fileData)), 'sha256');
* `[Part]` json
* `[Part]` xml
-### seeHttpHeader
+### seeHttpHeader
+
Checks over the given HTTP header and (optionally)
its value, asserting that are there
@@ -380,8 +407,9 @@ its value, asserting that are there
* `[Part]` json
* `[Part]` xml
-### seeHttpHeaderOnce
+### seeHttpHeaderOnce
+
Checks that http response header is received only once.
HTTP RFC2616 allows multiple response headers with the same name.
You can check that you didn't accidentally sent the same header twice.
@@ -396,8 +424,9 @@ $I->seeHttpHeaderOnce('Cache-Control');
* `[Part]` json
* `[Part]` xml
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks response code equals to provided value.
```php
@@ -412,16 +441,18 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `[Part]` xml
* `param` $code
-### seeResponseContains
+### seeResponseContains
+
Checks whether the last response contains text.
* `param` $text
* `[Part]` json
* `[Part]` xml
-### seeResponseContainsJson
+### seeResponseContainsJson
+
Checks whether the last JSON response contains provided array.
The response is converted to array with json_decode($response, true)
Thus, JSON is represented by associative array.
@@ -445,30 +476,34 @@ This method recursively checks if one array can be found inside of another.
* `param array` $json
* `[Part]` json
-### seeResponseEquals
+### seeResponseEquals
+
Checks if response is exactly the same as provided.
* `[Part]` json
* `[Part]` xml
* `param` $response
-### seeResponseIsJson
+### seeResponseIsJson
+
Checks whether last response was valid JSON.
This is done with json_last_error function.
* `[Part]` json
-### seeResponseIsXml
+### seeResponseIsXml
+
Checks whether last response was valid XML.
This is done with libxml_get_last_error function.
* `[Part]` xml
-### seeResponseJsonMatchesJsonPath
+### seeResponseJsonMatchesJsonPath
+
Checks if json structure in response matches [JsonPath](http://goessner.net/articles/JsonPath/).
JsonPath is XPath equivalent for querying Json structures.
Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/).
@@ -513,8 +548,9 @@ $I->seeResponseJsonMatchesJsonPath('$.store..price');
* `[Part]` json
* `Available since` 2.0.9
-### seeResponseJsonMatchesXpath
+### seeResponseJsonMatchesXpath
+
Checks if json structure in response matches the xpath provided.
JSON is not supposed to be checked against XPath, yet it can be converted to xml and used with XPath.
This assertion allows you to check the structure of response json.
@@ -555,8 +591,9 @@ $I->seeResponseJsonMatchesXpath('/store//price');
* `[Part]` json
* `Available since` 2.0.9
-### seeResponseMatchesJsonType
+### seeResponseMatchesJsonType
+
Checks that Json matches provided types.
In case you don't know the actual values of JSON data returned you can match them by type.
Starts check with a root element. If JSON data is array it will check the first element of an array.
@@ -636,8 +673,9 @@ See [JsonType reference](http://codeception.com/docs/reference/JsonType).
* `param array` $jsonType
* `param string` $jsonPath
-### seeXmlResponseEquals
+### seeXmlResponseEquals
+
Checks XML response equals provided XML.
Comparison is done by canonicalizing both xml`s.
@@ -646,8 +684,9 @@ Parameters can be passed either as DOMDocument, DOMNode, XML string, or array (i
* `param` $xml
* `[Part]` xml
-### seeXmlResponseIncludes
+### seeXmlResponseIncludes
+
Checks XML response includes provided XML.
Comparison is done by canonicalizing both xml`s.
Parameter can be passed either as XmlBuilder, DOMDocument, DOMNode, XML string, or array (if no attributes).
@@ -663,8 +702,9 @@ $I->seeXmlResponseIncludes("1");
* `param` $xml
* `[Part]` xml
-### seeXmlResponseMatchesXpath
+### seeXmlResponseMatchesXpath
+
Checks whether XML response matches XPath
```php
@@ -674,8 +714,9 @@ $I->seeXmlResponseMatchesXpath('//root/user[@id=1]');
* `[Part]` xml
* `param` $xpath
-### sendDELETE
+### sendDELETE
+
Sends DELETE request to given uri.
* `param` $url
@@ -684,8 +725,9 @@ Sends DELETE request to given uri.
* `[Part]` json
* `[Part]` xml
-### sendGET
+### sendGET
+
Sends a GET request to given uri.
* `param` $url
@@ -693,8 +735,9 @@ Sends a GET request to given uri.
* `[Part]` json
* `[Part]` xml
-### sendHEAD
+### sendHEAD
+
Sends a HEAD request to given uri.
* `param` $url
@@ -702,8 +745,9 @@ Sends a HEAD request to given uri.
* `[Part]` json
* `[Part]` xml
-### sendLINK
+### sendLINK
+
Sends LINK request to given uri.
* `param` $url
@@ -715,8 +759,9 @@ Sends LINK request to given uri.
* `[Part]` json
* `[Part]` xml
-### sendOPTIONS
+### sendOPTIONS
+
Sends an OPTIONS request to given uri.
* `param` $url
@@ -724,8 +769,9 @@ Sends an OPTIONS request to given uri.
* `[Part]` json
* `[Part]` xml
-### sendPATCH
+### sendPATCH
+
Sends PATCH request to given uri.
* `param` $url
@@ -734,8 +780,9 @@ Sends PATCH request to given uri.
* `[Part]` json
* `[Part]` xml
-### sendPOST
+### sendPOST
+
Sends a POST request to given uri. Parameters and files can be provided separately.
Example:
@@ -768,8 +815,9 @@ $I->sendPOST('/message/24', ['inline' => 0], [
* `[Part]` json
* `[Part]` xml
-### sendPUT
+### sendPUT
+
Sends PUT request to given uri.
* `param` $url
@@ -778,8 +826,9 @@ Sends PUT request to given uri.
* `[Part]` json
* `[Part]` xml
-### sendUNLINK
+### sendUNLINK
+
Sends UNLINK request to given uri.
* `param` $url
@@ -789,8 +838,9 @@ Sends UNLINK request to given uri.
* `[Part]` json
* `[Part]` xml
-### startFollowingRedirects
+### startFollowingRedirects
+
Enables automatic redirects to be followed by the client
```php
@@ -801,8 +851,9 @@ $I->startFollowingRedirects();
* `[Part]` xml
* `[Part]` json
-### stopFollowingRedirects
+### stopFollowingRedirects
+
Prevents automatic redirects to be followed by the client
```php
@@ -813,4 +864,4 @@ $I->stopFollowingRedirects();
* `[Part]` xml
* `[Part]` json
-
diff --git a/docs/modules/Redis.md b/docs/modules/Redis.md
index 0495236030..459145e7cb 100644
--- a/docs/modules/Redis.md
+++ b/docs/modules/Redis.md
@@ -1,5 +1,6 @@
# Redis
+
This module uses the [Predis](https://github.com/nrk/predis) library
to interact with a Redis server.
@@ -37,13 +38,14 @@ to interact with a Redis server.
## Actions
### cleanup
-
+
Delete all the keys in the Redis database
@throws ModuleException
-### dontSeeInRedis
+### dontSeeInRedis
+
Asserts that a key does not exist or, optionally, that it doesn't have the
provided $value
@@ -74,8 +76,9 @@ $I->dontSeeInRedis('example:hash', ['riri' => true, 'fifi' => 'Dewey', 'loulou'
* `param mixed` $value Optional. If specified, also checks the key has this
value. Booleans will be converted to 1 and 0 (even inside arrays)
-### dontSeeRedisKeyContains
+### dontSeeRedisKeyContains
+
Asserts that a given key does not contain a given item
Examples:
@@ -111,8 +114,9 @@ specified, the method will also check that the $item has this value/score
* `return` bool
-### grabFromRedis
+### grabFromRedis
+
Returns the value of a given key
Examples:
@@ -151,8 +155,9 @@ $I->grabFromRedis('example:hash', 'foo');
@throws ModuleException if the key does not exist
-### haveInRedis
+### haveInRedis
+
Creates or modifies keys
If $key already exists:
@@ -186,8 +191,9 @@ $I->haveInRedis('hash', ['obladi' => 'oblada']);
@throws ModuleException
-### seeInRedis
+### seeInRedis
+
Asserts that a key exists, and optionally that it has the provided $value
Examples:
@@ -217,8 +223,9 @@ $I->seeInRedis('example:hash', ['riri' => true, 'fifi' => 'Dewey', 'loulou' => 2
* `param mixed` $value Optional. If specified, also checks the key has this
value. Booleans will be converted to 1 and 0 (even inside arrays)
-### seeRedisKeyContains
+### seeRedisKeyContains
+
Asserts that a given key contains a given item
Examples:
@@ -254,8 +261,9 @@ specified, the method will also check that the $item has this value/score
* `return` bool
-### sendCommandToRedis
+### sendCommandToRedis
+
Sends a command directly to the Redis driver. See documentation at
https://github.com/nrk/predis
Every argument that follows the $command name will be passed to it.
@@ -273,4 +281,5 @@ $I->sendCommandToRedis('flushdb');
* `param string` $command The command name
-
diff --git a/docs/modules/SOAP.md b/docs/modules/SOAP.md
index 126e68a961..806fecb366 100644
--- a/docs/modules/SOAP.md
+++ b/docs/modules/SOAP.md
@@ -1,5 +1,6 @@
# SOAP
+
Module for testing SOAP WSDL web services.
Send requests and check if response matches the pattern.
@@ -29,15 +30,17 @@ If you use PHP SoapServer with framework, try to block call to this method in te
* xmlRequest - last SOAP request (DOMDocument)
* xmlResponse - last SOAP response (DOMDocument)
+
## Actions
### dontSeeSoapResponseContainsStructure
-
+
Opposite to `seeSoapResponseContainsStructure`
* `param` $xml
-### dontSeeSoapResponseContainsXPath
+### dontSeeSoapResponseContainsXPath
+
Checks XML response doesn't contain XPath locator
``` php
@@ -48,8 +51,9 @@ $I->dontSeeSoapResponseContainsXPath('//root/user[@id=1]');
* `param` $xpath
-### dontSeeSoapResponseEquals
+### dontSeeSoapResponseEquals
+
Checks XML response equals provided XML.
Comparison is done by canonicalizing both xml`s.
@@ -57,16 +61,18 @@ Parameter can be passed either as XmlBuilder, DOMDocument, DOMNode, XML string,
* `param` $xml
-### dontSeeSoapResponseIncludes
+### dontSeeSoapResponseIncludes
+
Checks XML response does not include provided XML.
Comparison is done by canonicalizing both xml`s.
Parameter can be passed either as XmlBuilder, DOMDocument, DOMNode, XML string, or array (if no attributes).
* `param` $xml
-### grabAttributeFrom
+### grabAttributeFrom
+
Finds and returns attribute of element.
Element is matched by either CSS or XPath
@@ -75,8 +81,9 @@ Element is matched by either CSS or XPath
* `param` $attribute
* `return` string
-### grabTextContentFrom
+### grabTextContentFrom
+
Finds and returns text contents of element.
Element is matched by either CSS or XPath
@@ -84,8 +91,9 @@ Element is matched by either CSS or XPath
* `param` $cssOrXPath
* `return` string
-### haveSoapHeader
+### haveSoapHeader
+
Prepare SOAP header.
Receives header name and parameters as array.
@@ -111,18 +119,21 @@ Will produce header:
* `param` $header
* `param array` $params
-### seeResponseCodeIs
+### seeResponseCodeIs
+
@deprecated use seeSoapResponseCodeIs instead
-### seeSoapResponseCodeIs
+### seeSoapResponseCodeIs
+
Checks response code from server.
* `param` $code
-### seeSoapResponseContainsStructure
+### seeSoapResponseContainsStructure
+
Checks XML response contains provided structure.
Response elements will be compared with XML provided.
Only nodeNames are checked to see elements match.
@@ -142,8 +153,9 @@ This method does not require path from root to match the structure.
* `param` $xml
-### seeSoapResponseContainsXPath
+### seeSoapResponseContainsXPath
+
Checks XML response with XPath locator
``` php
@@ -154,8 +166,9 @@ $I->seeSoapResponseContainsXPath('//root/user[@id=1]');
* `param` $xpath
-### seeSoapResponseEquals
+### seeSoapResponseEquals
+
Checks XML response equals provided XML.
Comparison is done by canonicalizing both xml`s.
@@ -175,8 +188,9 @@ $I->seeSoapRequestIncludes($dom);
* `param` $xml
-### seeSoapResponseIncludes
+### seeSoapResponseIncludes
+
Checks XML response includes provided XML.
Comparison is done by canonicalizing both xml`s.
Parameter can be passed either as XmlBuilder, DOMDocument, DOMNode, XML string, or array (if no attributes).
@@ -196,8 +210,9 @@ $I->seeSoapRequestIncludes($dom);
* `param` $xml
-### sendSoapRequest
+### sendSoapRequest
+
Submits request to endpoint.
Requires of api function name and parameters.
@@ -217,4 +232,4 @@ $I->sendSoapRequest('UpdateUser', \Codeception\Utils\Soap::request()->user
* `param` $request
* `param` $body
-
diff --git a/docs/modules/Sequence.md b/docs/modules/Sequence.md
index 38d1249d93..0e7b08dd19 100644
--- a/docs/modules/Sequence.md
+++ b/docs/modules/Sequence.md
@@ -1,5 +1,6 @@
# Sequence
+
Sequence solves data cleanup issue in alternative way.
Instead cleaning up the database between tests,
you can use generated unique names, that should not conflict.
@@ -93,4 +94,4 @@ Sequence:
## Actions
-
diff --git a/docs/modules/Silex.md b/docs/modules/Silex.md
index 9978810734..55684b8796 100644
--- a/docs/modules/Silex.md
+++ b/docs/modules/Silex.md
@@ -1,5 +1,6 @@
# Silex
+
Module for testing Silex applications like you would regularly do with Silex\WebTestCase.
This module uses Symfony2 Crawler and HttpKernel to emulate requests and get response.
@@ -49,7 +50,7 @@ Class Silex
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -73,10 +74,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -93,10 +95,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -116,10 +119,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -147,10 +151,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -158,15 +163,17 @@ $this->getModule('Silex')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -179,8 +186,9 @@ $I->amOnPage('/register');
* `param string` $page
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -193,8 +201,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -205,8 +214,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -237,8 +247,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -255,8 +266,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -285,8 +297,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -298,8 +311,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -307,8 +321,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -321,8 +336,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -334,8 +350,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -351,8 +368,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -363,8 +381,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -382,8 +401,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -424,8 +444,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -436,14 +457,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -457,8 +481,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -470,8 +495,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeResponseCodeIs
+
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -483,8 +510,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -497,14 +525,16 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### getInternalDomains
+### getInternalDomains
+
Returns a list of recognized domain names
* `return` array
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -517,8 +547,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -526,8 +558,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -540,8 +573,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -565,16 +600,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabService
+### grabService
+
Return an instance of a class from the Container.
Example
@@ -586,8 +623,9 @@ $I->grabService('session');
* `param` string $service
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -602,14 +640,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -651,8 +694,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -683,8 +727,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -697,8 +742,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -711,8 +757,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -725,8 +772,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -738,8 +786,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -759,8 +808,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -774,8 +824,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -793,8 +844,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -855,8 +907,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -867,8 +920,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -879,8 +933,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -894,8 +950,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -907,8 +964,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -920,12 +978,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -938,8 +999,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -970,8 +1032,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -980,8 +1043,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1001,8 +1065,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1020,8 +1085,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1035,8 +1101,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1207,8 +1275,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1224,8 +1293,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1236,4 +1306,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/Symfony.md b/docs/modules/Symfony.md
index cee9cf5998..607fe2677b 100644
--- a/docs/modules/Symfony.md
+++ b/docs/modules/Symfony.md
@@ -1,5 +1,6 @@
# Symfony
+
This module uses Symfony Crawler and HttpKernel to emulate requests and test response.
## Demo Project
@@ -25,6 +26,7 @@ This module uses Symfony Crawler and HttpKernel to emulate requests and test res
app_path: 'src'
environment: 'test'
+
### Symfony 3.x
* app_path: 'app' - specify custom path to your app dir, where the kernel interface is located.
@@ -44,6 +46,7 @@ This module uses Symfony Crawler and HttpKernel to emulate requests and test res
var_path: 'var'
environment: 'local_test'
+
### Symfony 2.x
* app_path: 'app' - specify custom path to your app dir, where bootstrap cache and kernel interface is located.
@@ -86,12 +89,13 @@ modules:
browser: phantomjs
```
+
## Actions
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -115,10 +119,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -135,10 +140,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -158,10 +164,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -189,10 +196,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -200,15 +208,17 @@ $this->getModule('Symfony')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -221,8 +231,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnRoute
+### amOnRoute
+
Opens web page using route name and parameters.
``` php
@@ -235,8 +246,9 @@ $I->amOnRoute('posts.show', array('id' => 34));
* `param` $routeName
* `param array` $params
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -249,8 +261,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -261,8 +274,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -293,8 +307,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -311,8 +326,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -341,8 +357,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -354,8 +371,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -363,8 +381,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -377,8 +396,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -390,8 +410,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -407,8 +428,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -419,8 +441,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -438,8 +461,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -480,8 +504,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -492,14 +517,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -513,8 +541,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -526,8 +555,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeResponseCodeIs
+
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -539,8 +570,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -553,8 +585,9 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -567,8 +600,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -576,8 +611,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -590,8 +626,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -615,16 +653,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabService
+### grabService
+
Grabs a service from Symfony DIC container.
Recommended to use for unit testing.
@@ -637,8 +677,9 @@ $em = $I->grabService('doctrine');
* `param` $service
* `[Part]` services
-### grabServiceFromContainer
+### grabServiceFromContainer
+
Grabs a service from Symfony DIC container.
Recommended to use for unit testing.
@@ -652,8 +693,9 @@ $em = $I->grabServiceFromContainer('doctrine');
* `[Part]` services
@deprecated Use grabService instead
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -668,14 +710,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### invalidateCachedRouter
+### invalidateCachedRouter
+
Invalidate previously cached routes.
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### persistService
+### persistService
+
Get service $serviceName and add it to the lists of persistent services.
If $isPermanent then service becomes persistent between tests
* `param string` $serviceName
* `param boolean` $isPermanent
-### rebootClientKernel
+### rebootClientKernel
+
Reboot client's kernel.
Can be used to manually reboot kernel when 'rebootable_client' => false
@@ -738,8 +787,10 @@ perform other requests
?>
```
-### resetCookie
+
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -747,8 +798,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -779,8 +831,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -793,8 +846,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -807,8 +861,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentRouteIs
+### seeCurrentRouteIs
+
Checks that current url matches route.
``` php
@@ -821,8 +876,9 @@ $I->seeCurrentRouteIs('posts.show', array('id' => 8));
* `param` $routeName
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -835,8 +891,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -848,8 +905,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -869,14 +927,16 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeEmailIsSent
+### seeEmailIsSent
+
Checks if any email were sent by last request
@throws \LogicException
-### seeInCurrentRoute
+### seeInCurrentRoute
+
Checks that current url matches route.
Unlike seeCurrentRouteIs, this can matches without exact route parameters
@@ -888,8 +948,9 @@ $I->seeCurrentRouteMatches('my_blog_pages');
* `param` $routeName
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -903,8 +964,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -922,8 +984,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -984,8 +1047,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -996,8 +1060,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -1008,8 +1073,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -1023,8 +1090,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -1036,8 +1104,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -1049,12 +1118,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -1067,8 +1139,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1099,8 +1172,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1109,8 +1183,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1130,8 +1205,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1149,8 +1225,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1164,8 +1241,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1336,8 +1415,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1353,8 +1433,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1365,10 +1446,11 @@ $I->uncheckOption('#notify');
* `param` $option
-### unpersistService
+### unpersistService
+
Remove service $serviceName from the lists of persistent services.
* `param string` $serviceName
-
diff --git a/docs/modules/WebDriver.md b/docs/modules/WebDriver.md
index 1bb791cb27..7faf738973 100644
--- a/docs/modules/WebDriver.md
+++ b/docs/modules/WebDriver.md
@@ -1,5 +1,6 @@
# WebDriver
+
New generation Selenium WebDriver module.
## Local Testing
@@ -49,6 +50,7 @@ To run tests in Chrome browser you may connect to ChromeDriver directly, without
Additional [Chrome options](https://sites.google.com/a/chromium.org/chromedriver/capabilities) can be set in `chromeOptions` capabilities.
+
### PhantomJS
PhantomJS is a [headless browser](https://en.wikipedia.org/wiki/Headless_browser) alternative to Selenium Server that implements
@@ -227,20 +229,22 @@ If speed is a concern, it's recommended you stick with explicitly specifying the
$this->getModule('WebDriver')->webDriver->getKeyboard()->sendKeys('hello, webdriver');
```
+
## Actions
### _backupSession
*hidden API method, expected to be used from Helper classes*
-
+
Returns current WebDriver session for saving
* `return` RemoteWebDriver
+
### _capabilities
*hidden API method, expected to be used from Helper classes*
-
+
Change capabilities of WebDriver. Should be executed before starting a new browser session.
This method expects a function to be passed which returns array or [WebDriver Desired Capabilities](https://github.com/facebook/php-webdriver/blob/community/lib/Remote/DesiredCapabilities.php) object.
Additional [Chrome options](https://github.com/facebook/php-webdriver/wiki/ChromeOptions) (like adding extensions) can be passed as well.
@@ -283,10 +287,11 @@ In this case, please ensure that `\Helper\Acceptance` is loaded before WebDriver
* `param \Closure` $capabilityFunction
+
### _closeSession
*hidden API method, expected to be used from Helper classes*
-
+
Manually closes current WebDriver session.
```php
@@ -300,10 +305,11 @@ $this->getModule('WebDriver')->_closeSession($webDriver);
* `param` $webDriver (optional) a specific webdriver session instance
+
### _findClickable
*hidden API method, expected to be used from Helper classes*
-
+
Locates a clickable element.
Use it in Helpers or GroupObject or Extension classes:
@@ -325,10 +331,11 @@ $el = $module->_findClickable($topBar, 'Click Me');
* `param` $link a link text or locator to click
* `return` WebDriverElement
+
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -352,26 +359,29 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getCurrentUri
*hidden API method, expected to be used from Helper classes*
-
+
Uri of currently opened page.
* `return` string
@throws ModuleException
+
### _getUrl
*hidden API method, expected to be used from Helper classes*
-
+
Returns URL of a host.
@throws ModuleConfigException
+
### _initializeSession
*hidden API method, expected to be used from Helper classes*
-
+
Manually starts a new browser session.
```php
@@ -379,18 +389,21 @@ Manually starts a new browser session.
$this->getModule('WebDriver')->_initializeSession();
```
+
+
### _loadSession
*hidden API method, expected to be used from Helper classes*
-
+
Loads current RemoteWebDriver instance as a session
* `param RemoteWebDriver` $session
+
### _restart
*hidden API method, expected to be used from Helper classes*
-
+
Restarts a web browser.
Can be used with `_reconfigure` to open browser with different configuration
@@ -403,17 +416,19 @@ $this->getModule('WebDriver')->_restart(['browser' => $browser]); // reconfigure
* `param array` $config
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves HTML source of a page to a file
* `param` $filename
+
### _saveScreenshot
*hidden API method, expected to be used from Helper classes*
-
+
Saves screenshot of current page to a file
```php
@@ -421,14 +436,16 @@ $this->getModule('WebDriver')->_saveScreenshot(codecept_output_dir().'screenshot
```
* `param` $filename
-### acceptPopup
+### acceptPopup
+
Accepts the active JavaScript native popup window, as created by `window.alert`|`window.confirm`|`window.prompt`.
Don't confuse popups with modal windows,
as created by [various libraries](http://jster.net/category/windows-modals-popups).
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -441,8 +458,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnSubdomain
+### amOnSubdomain
+
Changes the subdomain for the 'url' configuration parameter.
Does not open a page; use `amOnPage` for that.
@@ -460,8 +478,10 @@ $I->amOnPage('/');
* `param` $subdomain
-### amOnUrl
+
+### amOnUrl
+
Open web page at the given absolute URL and sets its hostname as the base host.
``` php
@@ -471,8 +491,9 @@ $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart
?>
```
-### appendField
+### appendField
+
Append the given text to the given element.
Can also add a selection to a select box.
@@ -487,8 +508,9 @@ $I->appendField('#myTextField', 'appended');
* `param string` $value
@throws \Codeception\Exception\ElementNotFound
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -501,12 +523,14 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### cancelPopup
+### cancelPopup
+
Dismisses the active JavaScript popup, as created by `window.alert`, `window.confirm`, or `window.prompt`.
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -517,8 +541,21 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### clearField
+
+Clears given field which isn't empty.
+
+``` php
+clearField('#username');
+```
+
+ * `param` $field
+
+
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -549,8 +586,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### clickWithLeftButton
+### clickWithLeftButton
+
Performs click with the left mouse button on an element.
If the first parameter `null` then the offset is relative to the actual mouse position.
If the second and third parameters are given,
@@ -571,8 +609,9 @@ $I->clickWithLeftButton(['css' => '.checkout'], 20, 50);
@throws \Codeception\Exception\ElementNotFound
-### clickWithRightButton
+### clickWithRightButton
+
Performs contextual click with the right mouse button on an element.
If the first parameter `null` then the offset is relative to the actual mouse position.
If the second and third parameters are given,
@@ -588,13 +627,14 @@ $I->clickWithRightButton(['css' => '.checkout'], 20, 50);
```
* `param string` $cssOrXPath css or xpath of the web element (body by default).
- * `param int` $offsetX
- * `param int` $offsetY
+ * `param int` $offsetX
+ * `param int` $offsetY
@throws \Codeception\Exception\ElementNotFound
-### closeTab
+### closeTab
+
Closes current browser tab and switches to previous active tab.
```php
@@ -604,14 +644,16 @@ $I->closeTab();
Can't be used with PhantomJS
-### debugWebDriverLogs
+### debugWebDriverLogs
+
Print out latest Selenium Logs in debug mode
* `param TestInterface` $test
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -640,8 +682,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -653,8 +696,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -662,8 +706,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -676,8 +721,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -689,8 +735,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -706,15 +753,17 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeElementInDOM
+### dontSeeElementInDOM
+
Opposite of `seeElementInDOM`.
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -725,8 +774,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -744,8 +794,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -786,14 +837,16 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInPageSource
+### dontSeeInPageSource
+
Checks that the page source doesn't contain the given string.
* `param` $text
-### dontSeeInPopup
+### dontSeeInPopup
+
Checks that the active JavaScript popup,
as created by `window.alert`|`window.confirm`|`window.prompt`, does NOT contain the given string.
@@ -801,8 +854,9 @@ as created by `window.alert`|`window.confirm`|`window.prompt`, does NOT contain
@throws \Codeception\Exception\ModuleException
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -813,14 +867,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -834,8 +891,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -847,15 +905,18 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### doubleClick
+
+### doubleClick
+
Performs a double-click on an element matched by CSS or XPath.
* `param` $cssOrXPath
@throws \Codeception\Exception\ElementNotFound
-### dragAndDrop
+### dragAndDrop
+
Performs a simple mouse drag-and-drop operation.
``` php
@@ -867,8 +928,28 @@ $I->dragAndDrop('#drag', '#drop');
* `param string` $source (CSS ID or XPath)
* `param string` $target (CSS ID or XPath)
-### executeInSelenium
+### executeAsyncJS
+
+Executes asynchronous JavaScript.
+A callback should be executed by JavaScript to exit from a script.
+Callback is passed as a last element in `arguments` array.
+Additional arguments can be passed as array in second parameter.
+
+```js
+// wait for 1200 milliseconds my running `setTimeout`
+* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
+
+$seconds = 1200; // or seconds are passed as argument
+$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
+```
+
+ * `param` $script
+ * `param array` $arguments
+
+
+### executeInSelenium
+
Low-level API method.
If Codeception commands are not enough, this allows you to use Selenium WebDriver methods directly:
@@ -885,8 +966,9 @@ If Codeception lacks a feature you need, please implement it and submit a patch.
* `param callable` $function
-### executeJS
+### executeJS
+
Executes custom JavaScript.
This example uses jQuery to get a value and assigns that value to a PHP variable:
@@ -894,13 +976,18 @@ This example uses jQuery to get a value and assigns that value to a PHP variable
```php
executeJS('return $("#myField").val()');
-?>
+
+// additional arguments can be passed as array
+// Example shows `Hello World` alert:
+$I->executeJS("window.alert(arguments[0])", ['Hello world']);
```
* `param` $script
+ * `param array` $arguments
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -913,8 +1000,9 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -927,8 +1015,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -936,8 +1026,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -950,8 +1041,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -975,16 +1068,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -999,8 +1094,10 @@ $value = $I->grabTextFrom('~grabValueFrom(['name' => 'username']);
* `param` $field
-### loadSessionSnapshot
+
+### loadSessionSnapshot
+
* `param string` $name
* `return` bool
-### makeScreenshot
+### makeScreenshot
+
Takes a screenshot of the current window and saves it to `tests/_output/debug`.
``` php
@@ -1035,20 +1135,24 @@ $I->makeScreenshot();
* `param` $name
-### maximizeWindow
+### maximizeWindow
+
Maximizes the current window.
-### moveBack
+### moveBack
+
Moves back in history.
-### moveForward
+### moveForward
+
Moves forward in history.
-### moveMouseOver
+### moveMouseOver
+
Move mouse over the first element matched by the given locator.
If the first parameter null then the page is used.
If the second and third parameters are given,
@@ -1069,8 +1173,9 @@ $I->moveMouseOver(['css' => '.checkout'], 20, 50);
@throws \Codeception\Exception\ElementNotFound
-### openNewTab
+### openNewTab
+
Opens a new browser tab (wherever it is possible) and switches to it.
```php
@@ -1082,16 +1187,19 @@ Please note, that adblock can restrict creating such tabs.
Can't be used with PhantomJS
-### pauseExecution
+
+### pauseExecution
+
Pauses test execution in debug mode.
To proceed test press "ENTER" in console.
This method is useful while writing tests,
since it allows you to inspect the current page in the middle of a test case.
-### performOn
+### performOn
+
Waits for element and runs a sequence of actions inside its context.
Actions can be defined with array, callback, or `Codeception\Util\ActionSequence` instance.
@@ -1134,8 +1242,9 @@ In 3rd argument you can set number a seconds to wait for element to appear
* `param` $actions
* `param int` $timeout
-### pressKey
+### pressKey
+
Presses the given key on the given element.
To specify a character and modifier (e.g. ctrl, alt, shift, meta), pass an array for $char with
the modifier as the first element and the character as the second.
@@ -1156,12 +1265,14 @@ $I->pressKey('#name', array('ctrl', 'a'), \Facebook\WebDriver\WebDriverKeys::DEL
* `param` $char string|array Can be char or array with modifier. You can provide several chars.
@throws \Codeception\Exception\ElementNotFound
-### reloadPage
+### reloadPage
+
Reloads the current page.
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -1169,8 +1280,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### resizeWindow
+### resizeWindow
+
Resize the current window.
``` php
@@ -1182,12 +1294,14 @@ $I->resizeWindow(800, 600);
* `param int` $width
* `param int` $height
-### saveSessionSnapshot
+### saveSessionSnapshot
+
* `param string` $name
-### scrollTo
+### scrollTo
+
Move to the middle of the given element matched by the given locator.
Extra shift, calculated from the top-left corner of the element,
can be set by passing $offsetX and $offsetY parameters.
@@ -1202,8 +1316,9 @@ $I->scrollTo(['css' => '.checkout'], 20, 50);
* `param int` $offsetX
* `param int` $offsetY
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -1234,8 +1349,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -1248,8 +1364,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -1262,8 +1379,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -1276,8 +1394,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -1289,8 +1408,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -1310,8 +1430,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeElementInDOM
+### seeElementInDOM
+
Checks that the given element exists on the page, even it is invisible.
``` php
@@ -1323,8 +1444,9 @@ $I->seeElementInDOM('//form/input[type=hidden]');
* `param` $selector
* `param array` $attributes
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -1338,8 +1460,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -1357,8 +1480,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -1419,8 +1543,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInPageSource
+### seeInPageSource
+
Checks that the page source contains the given string.
```php
@@ -1430,8 +1555,9 @@ $I->seeInPageSource('seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -1463,8 +1591,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -1478,8 +1608,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -1491,11 +1622,13 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
+
### seeNumberOfElementsInDOM
__not documented__
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -1507,8 +1640,10 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### selectOption
+
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1539,8 +1674,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1554,8 +1690,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, optionally with the given form
values. Give the form fields values as an array. Note that hidden fields
can't be accessed.
@@ -1714,8 +1852,9 @@ For example, given the following HTML:
* `param` $params
* `param` $button
-### switchToIFrame
+### switchToIFrame
+
Switch to another frame on the page.
Example:
@@ -1735,8 +1874,9 @@ $I->switchToIFrame();
* `param string|null` $name
-### switchToNextTab
+### switchToNextTab
+
Switches to next browser tab.
An offset can be specified.
@@ -1752,8 +1892,9 @@ Can't be used with PhantomJS
* `param int` $offset 1
-### switchToPreviousTab
+### switchToPreviousTab
+
Switches to previous browser tab.
An offset can be specified.
@@ -1769,8 +1910,9 @@ Can't be used with PhantomJS
* `param int` $offset 1
-### switchToWindow
+### switchToWindow
+
Switch to another window identified by name.
The window can only be identified by name. If the $name parameter is blank, the parent window will be used.
@@ -1806,16 +1948,18 @@ $I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webd
* `param string|null` $name
-### typeInPopup
+### typeInPopup
+
Enters text into a native JavaScript prompt popup, as created by `window.prompt`.
* `param` $keys
@throws \Codeception\Exception\ModuleException
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1826,22 +1970,25 @@ $I->uncheckOption('#notify');
* `param` $option
-### unselectOption
+### unselectOption
+
Unselect an option in the given select box.
* `param` $select
* `param` $option
-### wait
+### wait
+
Wait for $timeout seconds.
* `param int|float` $timeout secs
@throws \Codeception\Exception\TestRuntimeException
-### waitForElement
+### waitForElement
+
Waits up to $timeout seconds for an element to appear on the page.
If the element doesn't appear, a timeout exception is thrown.
@@ -1856,8 +2003,9 @@ $I->click('#agree_button');
* `param int` $timeout seconds
@throws \Exception
-### waitForElementChange
+### waitForElementChange
+
Waits up to $timeout seconds for the given element to change.
Element "change" is determined by a callback function which is called repeatedly
until the return value evaluates to true.
@@ -1876,8 +2024,9 @@ $I->waitForElementChange('#menu', function(WebDriverElement $el) {
* `param int` $timeout seconds
@throws \Codeception\Exception\ElementNotFound
-### waitForElementNotVisible
+### waitForElementNotVisible
+
Waits up to $timeout seconds for the given element to become invisible.
If element stays visible, a timeout exception is thrown.
@@ -1891,8 +2040,9 @@ $I->waitForElementNotVisible('#agree_button', 30); // secs
* `param int` $timeout seconds
@throws \Exception
-### waitForElementVisible
+### waitForElementVisible
+
Waits up to $timeout seconds for the given element to be visible on the page.
If element doesn't appear, a timeout exception is thrown.
@@ -1907,8 +2057,9 @@ $I->click('#agree_button');
* `param int` $timeout seconds
@throws \Exception
-### waitForJS
+### waitForJS
+
Executes JavaScript and waits up to $timeout seconds for it to return true.
In this example we will wait up to 60 seconds for all jQuery AJAX requests to finish.
@@ -1922,8 +2073,9 @@ $I->waitForJS("return $.active == 0;", 60);
* `param string` $script
* `param int` $timeout seconds
-### waitForText
+### waitForText
+
Waits up to $timeout seconds for the given string to appear on the page.
Can also be passed a selector to search in, be as specific as possible when using selectors.
@@ -1942,4 +2094,4 @@ $I->waitForText('foo', 30, '.title'); // secs
* `param string` $selector optional
@throws \Exception
-
diff --git a/docs/modules/Yii1.md b/docs/modules/Yii1.md
index 74eee61ade..dae9e37d11 100644
--- a/docs/modules/Yii1.md
+++ b/docs/modules/Yii1.md
@@ -1,5 +1,6 @@
# Yii1
+
This module provides integration with [Yii Framework 1.1](http://www.yiiframework.com/doc/guide/).
The following configurations are available for this module:
@@ -111,7 +112,7 @@ modules:
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -135,10 +136,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -155,10 +157,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -178,10 +181,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -209,10 +213,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -220,15 +225,17 @@ $this->getModule('Yii1')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -241,8 +248,9 @@ $I->amOnPage('/register');
* `param string` $page
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -255,8 +263,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -267,8 +276,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -299,8 +309,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -317,8 +328,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -347,8 +359,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -360,8 +373,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -369,8 +383,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -383,8 +398,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -396,8 +412,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -413,8 +430,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -425,8 +443,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -444,8 +463,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -486,8 +506,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -498,14 +519,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -519,8 +543,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -532,8 +557,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeResponseCodeIs
+
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -545,8 +572,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -559,14 +587,16 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### getInternalDomains
+### getInternalDomains
+
Returns a list of regex patterns for recognized domain names
* `return` array
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -579,8 +609,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -588,8 +620,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -602,8 +635,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -627,16 +662,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -651,14 +688,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -700,8 +742,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -732,8 +775,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -746,8 +790,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -760,8 +805,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -774,8 +820,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -787,8 +834,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -808,8 +856,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -823,8 +872,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -842,8 +892,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -904,8 +955,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -916,8 +968,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -928,8 +981,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -943,8 +998,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -956,8 +1012,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -969,12 +1026,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -987,8 +1047,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1019,8 +1080,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1029,8 +1091,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1050,8 +1113,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1069,8 +1133,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1084,8 +1149,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1256,8 +1323,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1273,8 +1341,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1285,4 +1354,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/Yii2.md b/docs/modules/Yii2.md
index 52a28cb26e..ed6bb2c955 100644
--- a/docs/modules/Yii2.md
+++ b/docs/modules/Yii2.md
@@ -1,5 +1,6 @@
# Yii2
+
This module provides integration with [Yii framework](http://www.yiiframework.com/) (2.0).
It initializes Yii framework in test environment and provides actions for functional testing.
@@ -108,12 +109,13 @@ $I->sendAjaxPostRequest(['/user/update', 'id' => 1], ['UserForm[name]' => 'G.Hop
Maintainer: **samdark**
Stability: **stable**
+
## Actions
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -137,10 +139,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -157,10 +160,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -180,10 +184,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -211,10 +216,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -222,15 +228,17 @@ $this->getModule('Yii2')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amLoggedInAs
+### amLoggedInAs
+
Authorizes user on a site without submitting login form.
Use it for fast pragmatic authorization in functional tests.
@@ -248,8 +256,9 @@ Requires `user` component to be enabled and configured.
* `param` $user
@throws ModuleException
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -262,16 +271,19 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnRoute
+### amOnRoute
+
Similar to amOnPage but accepts route as first argument and params as second
```
$I->amOnRoute('site/view', ['page' => 'about']);
```
-### attachFile
+
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -284,8 +296,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -296,8 +309,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -328,8 +342,16 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### createAndSetCsrfCookie
+
+This function creates the CSRF Cookie.
+ * `param string` $val The value of the CSRF token
+ * `return` string[] Returns an array containing the name of the CSRF param and the masked CSRF token.
+
+
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -346,8 +368,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -376,8 +399,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -389,8 +413,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -398,8 +423,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -412,8 +438,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -425,8 +452,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -442,14 +470,16 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeEmailIsSent
+### dontSeeEmailIsSent
+
Checks that no email was sent
* `[Part]` email
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -460,8 +490,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -479,8 +510,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -521,8 +553,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -533,14 +566,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -554,8 +590,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -567,8 +604,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeRecord
+
+### dontSeeRecord
+
Checks that record does not exist in database.
``` php
@@ -579,8 +618,9 @@ $I->dontSeeRecord('app\models\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### dontSeeResponseCodeIs
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -592,8 +632,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -606,14 +647,16 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### getInternalDomains
+### getInternalDomains
+
Returns a list of regex patterns for recognized domain names
* `return` array
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -626,8 +669,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabComponent
+
+### grabComponent
+
Gets a component from Yii container. Throws exception if component is not available
```php
@@ -638,8 +683,9 @@ $mailer = $I->grabComponent('mailer');
* `param` $component
@throws ModuleException
-### grabCookie
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -647,8 +693,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFixture
+### grabFixture
+
Gets a fixture by name.
Returns a Fixture instance. If a fixture is an instance of `\yii\test\BaseActiveFixture` a second parameter
can be used to return a specific model:
@@ -667,16 +714,18 @@ $user = $I->grabFixture('users', 'user1');
@throws ModuleException if a fixture is not found
* `[Part]` fixtures
-### grabFixtures
+### grabFixtures
+
Returns all loaded fixtures.
Array of fixture instances
* `[Part]` fixtures
* `return` array
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -689,8 +738,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabLastSentEmail
+
+### grabLastSentEmail
+
Returns last sent email:
```php
@@ -701,8 +752,9 @@ $I->assertEquals('admin@site,com', $message->getTo());
```
* `[Part]` email
-### grabMultiple
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -726,16 +778,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabRecord
+### grabRecord
+
Retrieves record from database
``` php
@@ -746,10 +800,11 @@ $category = $I->grabRecord('app\models\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### grabSentEmails
+### grabSentEmails
+
Returns array of all sent email messages.
-Each message implements `yii\mail\Message` interface.
+Each message implements `yii\mail\MessageInterface` interface.
Useful to perform additional checks using `Asserts` module:
```php
@@ -763,8 +818,9 @@ $I->assertEquals('admin@site,com', $messages[0]->getTo());
* `return` array
@throws ModuleException
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -779,14 +835,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### haveRecord
+### haveRecord
+
Inserts record into the database.
``` php
@@ -862,14 +923,16 @@ $user_id = $I->haveRecord('app\models\User', array('name' => 'Davert'));
* `param array` $attributes
* `[Part]` orm
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -877,8 +940,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -909,8 +973,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -923,8 +988,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -937,8 +1003,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -951,8 +1018,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -964,8 +1032,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -985,8 +1054,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeEmailIsSent
+### seeEmailIsSent
+
Checks that email is sent.
```php
@@ -1002,8 +1072,9 @@ $I->seeEmailIsSent(3);
@throws ModuleException
* `[Part]` email
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -1017,8 +1088,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -1036,8 +1108,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -1098,8 +1171,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -1110,8 +1184,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -1122,8 +1197,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -1137,8 +1214,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -1150,8 +1228,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -1163,12 +1242,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeRecord
+### seeRecord
+
Checks that record exists in database.
``` php
@@ -1179,8 +1261,9 @@ $I->seeRecord('app\models\User', array('name' => 'davert'));
* `param array` $attributes
* `[Part]` orm
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -1193,8 +1276,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -1225,8 +1309,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1235,8 +1320,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1256,8 +1342,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1275,23 +1362,17 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
-
-Sets a cookie with the given name and value.
-You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
-``` php
-setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
-?>
-```
+### setCookie
+
+Sets a cookie and, if validation is enabled, signs it.
+ * `param string` $name The name of the cookie
+ * `param string` $value The value of the cookie
+ * `param array` $params Additional cookie params like `domain`, `path`, `expires` and `secure`.
- * `param` $name
- * `param` $val
- * `param array` $params
### submitForm
-
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1462,8 +1543,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1479,8 +1561,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1491,4 +1574,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/ZF1.md b/docs/modules/ZF1.md
index 8a44607c70..6a901dfabd 100644
--- a/docs/modules/ZF1.md
+++ b/docs/modules/ZF1.md
@@ -1,5 +1,6 @@
# ZF1
+
This module allows you to run tests inside Zend Framework.
It acts just like ControllerTestCase, but with usage of Codeception syntax.
@@ -54,12 +55,13 @@ class TestHelper extends \Codeception\Module {
This will make your functional tests run super-fast.
+
## Actions
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -83,10 +85,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -103,10 +106,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -126,10 +130,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -157,10 +162,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -168,15 +174,17 @@ $this->getModule('ZF1')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -189,8 +197,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnRoute
+### amOnRoute
+
Opens web page using route name and parameters.
``` php
@@ -203,8 +212,9 @@ $I->amOnRoute('posts.show', array('id' => 34));
* `param` $routeName
* `param array` $params
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -217,8 +227,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -229,8 +240,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -261,8 +273,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -279,8 +292,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -309,8 +323,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -322,8 +337,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -331,8 +347,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -345,8 +362,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -358,8 +376,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -375,8 +394,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -387,8 +407,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -406,8 +427,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -448,8 +470,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -460,14 +483,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -481,8 +507,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -494,8 +521,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeResponseCodeIs
+
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -507,8 +536,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -521,8 +551,9 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -535,8 +566,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -544,8 +577,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -558,8 +592,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -583,16 +619,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -607,14 +645,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -656,8 +699,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -688,8 +732,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -702,8 +747,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -716,8 +762,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentRouteIs
+### seeCurrentRouteIs
+
Checks that current url matches route.
``` php
@@ -730,8 +777,9 @@ $I->seeCurrentRouteIs('posts.show', ['id' => 8]));
* `param` $routeName
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -744,8 +792,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -757,8 +806,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -778,8 +828,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -793,8 +844,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -812,8 +864,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -874,8 +927,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -886,8 +940,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -898,8 +953,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -913,8 +970,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -926,8 +984,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -939,12 +998,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -957,8 +1019,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -989,8 +1052,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -999,8 +1063,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1020,8 +1085,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1039,8 +1105,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1054,8 +1121,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1226,8 +1295,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1243,8 +1313,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1255,4 +1326,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/ZF2.md b/docs/modules/ZF2.md
index 3018081c34..263c422a75 100644
--- a/docs/modules/ZF2.md
+++ b/docs/modules/ZF2.md
@@ -1,5 +1,6 @@
# ZF2
+
This module allows you to run tests inside Zend Framework 2 and Zend Framework 3.
File `init_autoloader` in project's root is required by Zend Framework 2.
@@ -46,7 +47,7 @@ modules:
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -70,10 +71,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -90,10 +92,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -113,10 +116,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -144,10 +148,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -155,22 +160,25 @@ $this->getModule('ZF2')->_savePageSource(codecept_output_dir().'page.html');
```
* `param` $filename
-### addServiceToContainer
+### addServiceToContainer
+
Adds service to ZF2 container
* `param string` $name
* `param object` $service
* `[Part]` services
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -183,8 +191,9 @@ $I->amOnPage('/register');
* `param string` $page
-### amOnRoute
+### amOnRoute
+
Opens web page using route name and parameters.
``` php
@@ -197,8 +206,9 @@ $I->amOnRoute('posts.show', array('id' => 34));
* `param` $routeName
* `param array` $params
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -211,8 +221,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -223,8 +234,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -255,8 +267,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -273,8 +286,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -303,8 +317,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -316,8 +331,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -325,8 +341,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -339,8 +356,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -352,8 +370,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -369,8 +388,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -381,8 +401,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -400,8 +421,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -442,8 +464,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -454,14 +477,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -475,8 +501,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -488,8 +515,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeResponseCodeIs
+
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -501,8 +530,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -515,8 +545,9 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -529,8 +560,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -538,8 +571,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -552,8 +586,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -577,16 +613,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabServiceFromContainer
+### grabServiceFromContainer
+
Grabs a service from ZF2 container.
Recommended to use for unit testing.
@@ -599,8 +637,9 @@ $em = $I->grabServiceFromContainer('Doctrine\ORM\EntityManager');
* `param` $service
* `[Part]` services
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -615,14 +654,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -664,8 +708,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -696,8 +741,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -710,8 +756,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -724,8 +771,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentRouteIs
+### seeCurrentRouteIs
+
Checks that current url matches route.
``` php
@@ -738,8 +786,9 @@ $I->seeCurrentRouteIs('posts.show', ['id' => 8]));
* `param` $routeName
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -752,8 +801,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -765,8 +815,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -786,8 +837,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -801,8 +853,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -820,8 +873,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -882,8 +936,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -894,8 +949,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -906,8 +962,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -921,8 +979,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -934,8 +993,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -947,12 +1007,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -965,8 +1028,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -997,8 +1061,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -1007,8 +1072,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -1028,8 +1094,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -1047,8 +1114,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -1062,8 +1130,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1234,8 +1304,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1251,8 +1322,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1263,4 +1335,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/modules/ZendExpressive.md b/docs/modules/ZendExpressive.md
index 57a2acfe73..f0e265a9a8 100644
--- a/docs/modules/ZendExpressive.md
+++ b/docs/modules/ZendExpressive.md
@@ -1,5 +1,6 @@
# ZendExpressive
+
This module allows you to run tests inside Zend Expressive.
Uses `config/container.php` file by default.
@@ -19,12 +20,13 @@ Uses `config/container.php` file by default.
* container - instance of `\Interop\Container\ContainerInterface`
* client - BrowserKit client
+
## Actions
### _findElements
*hidden API method, expected to be used from Helper classes*
-
+
Locates element using available Codeception locator types:
* XPath
@@ -48,10 +50,11 @@ PhpBrowser and Framework modules return `Symfony\Component\DomCrawler\Crawler` i
* `param` $locator
* `return` array of interactive elements
+
### _getResponseContent
*hidden API method, expected to be used from Helper classes*
-
+
Returns content of the last response
Use it in Helpers when you want to retrieve response of request performed by another module.
@@ -68,10 +71,11 @@ public function seeResponseContains($text)
* `return` string
@throws ModuleException
+
### _loadPage
*hidden API method, expected to be used from Helper classes*
-
+
Opens a page with arbitrary request parameters.
Useful for testing multi-step forms on a specific step.
@@ -91,10 +95,11 @@ public function openCheckoutFormStep2($orderId) {
* `param array` $server
* `param null` $content
+
### _request
*hidden API method, expected to be used from Helper classes*
-
+
Send custom request to a backend using method, uri, parameters, etc.
Use it in Helpers to create special request actions, like accessing API
Returns a string with response body.
@@ -122,10 +127,11 @@ To load arbitrary page for interaction, use `_loadPage` method.
@throws ExternalUrlException
@see `_loadPage`
+
### _savePageSource
*hidden API method, expected to be used from Helper classes*
-
+
Saves page source of to a file
```php
@@ -133,15 +139,17 @@ $this->getModule('ZendExpressive')->_savePageSource(codecept_output_dir().'page.
```
* `param` $filename
-### amHttpAuthenticated
+### amHttpAuthenticated
+
Authenticates user for HTTP_AUTH
* `param` $username
* `param` $password
-### amOnPage
+### amOnPage
+
Opens the page for the given relative URI.
``` php
@@ -154,8 +162,9 @@ $I->amOnPage('/register');
* `param string` $page
-### attachFile
+### attachFile
+
Attaches a file relative to the Codeception `_data` directory to the given file upload field.
``` php
@@ -168,8 +177,9 @@ $I->attachFile('input[@type="file"]', 'prices.xls');
* `param` $field
* `param` $filename
-### checkOption
+### checkOption
+
Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
``` php
@@ -180,8 +190,9 @@ $I->checkOption('#agree');
* `param` $option
-### click
+### click
+
Perform a click on a link or a button, given by a locator.
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
For buttons, the "value" attribute, "name" attribute, and inner text are searched.
@@ -212,8 +223,9 @@ $I->click(['link' => 'Login']);
* `param` $link
* `param` $context
-### deleteHeader
+### deleteHeader
+
Deletes the header with the passed name. Subsequent requests
will not have the deleted header in its request.
@@ -230,8 +242,9 @@ $I->amOnPage('some-other-page.php');
* `param string` $name the name of the header to delete.
-### dontSee
+### dontSee
+
Checks that the current page doesn't contain the text specified (case insensitive).
Give a locator as the second parameter to match a specific region.
@@ -260,8 +273,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### dontSeeCheckboxIsChecked
+### dontSeeCheckboxIsChecked
+
Check that the specified checkbox is unchecked.
``` php
@@ -273,8 +287,9 @@ $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user
* `param` $checkbox
-### dontSeeCookie
+### dontSeeCookie
+
Checks that there isn't a cookie with the given name.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -282,8 +297,9 @@ You can set additional cookie params like `domain`, `path` as array passed in la
* `param array` $params
-### dontSeeCurrentUrlEquals
+### dontSeeCurrentUrlEquals
+
Checks that the current URL doesn't equal the given string.
Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
@@ -296,8 +312,9 @@ $I->dontSeeCurrentUrlEquals('/');
* `param string` $uri
-### dontSeeCurrentUrlMatches
+### dontSeeCurrentUrlMatches
+
Checks that current url doesn't match the given regular expression.
``` php
@@ -309,8 +326,9 @@ $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### dontSeeElement
+### dontSeeElement
+
Checks that the given element is invisible or not present on the page.
You can also specify expected attributes of this element.
@@ -326,8 +344,9 @@ $I->dontSeeElement('input', ['value' => '123456']);
* `param` $selector
* `param array` $attributes
-### dontSeeInCurrentUrl
+### dontSeeInCurrentUrl
+
Checks that the current URI doesn't contain the given string.
``` php
@@ -338,8 +357,9 @@ $I->dontSeeInCurrentUrl('/users/');
* `param string` $uri
-### dontSeeInField
+### dontSeeInField
+
Checks that an input field or textarea doesn't contain the given value.
For fuzzy locators, the field is matched by label text, CSS and XPath.
@@ -357,8 +377,9 @@ $I->dontSeeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### dontSeeInFormFields
+### dontSeeInFormFields
+
Checks if the array of form parameters (name => value) are not set on the form matched with
the passed selector.
@@ -399,8 +420,9 @@ $I->dontSeeInFormFields('#form-id', [
* `param` $formSelector
* `param` $params
-### dontSeeInSource
+### dontSeeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -411,14 +433,17 @@ $I->dontSeeInSource('
Green eggs & ham
');
* `param` $raw
-### dontSeeInTitle
+### dontSeeInTitle
+
Checks that the page title does not contain the given string.
* `param` $title
-### dontSeeLink
+
+### dontSeeLink
+
Checks that the page doesn't contain a link with the given string.
If the second parameter is given, only links with a matching "href" attribute will be checked.
@@ -432,8 +457,9 @@ $I->dontSeeLink('Checkout now', '/store/cart.php');
* `param string` $text
* `param string` $url optional
-### dontSeeOptionIsSelected
+### dontSeeOptionIsSelected
+
Checks that the given option is not selected.
``` php
@@ -445,8 +471,10 @@ $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### dontSeeResponseCodeIs
+
+### dontSeeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -458,8 +486,9 @@ $I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
```
* `param` $code
-### fillField
+### fillField
+
Fills a text field or textarea with the given string.
``` php
@@ -472,8 +501,9 @@ $I->fillField(['name' => 'email'], 'jon@mail.com');
* `param` $field
* `param` $value
-### grabAttributeFrom
+### grabAttributeFrom
+
Grabs the value of the given attribute value from the given element.
Fails if element is not found.
@@ -486,8 +516,10 @@ $I->grabAttributeFrom('#tooltip', 'title');
* `param` $cssOrXpath
* `param` $attribute
-### grabCookie
+
+### grabCookie
+
Grabs a cookie value.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -495,8 +527,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### grabFromCurrentUrl
+### grabFromCurrentUrl
+
Executes the given regular expression against the current URI and returns the first capturing group.
If no parameters are provided, the full URI is returned.
@@ -509,8 +542,10 @@ $uri = $I->grabFromCurrentUrl();
* `param string` $uri optional
-### grabMultiple
+
+### grabMultiple
+
Grabs either the text content, or attribute values, of nodes
matched by $cssOrXpath and returns them as an array.
@@ -534,16 +569,18 @@ $aLinks = $I->grabMultiple('a', 'href');
* `param` $attribute
* `return` string[]
-### grabPageSource
+### grabPageSource
+
Grabs current page source code.
@throws ModuleException if no page was opened.
* `return` string Current page source code.
-### grabTextFrom
+### grabTextFrom
+
Finds and returns the text contents of the given element.
If a fuzzy locator is used, the element is found using CSS, XPath,
and by matching the full page source by regular expression.
@@ -558,14 +595,17 @@ $value = $I->grabTextFrom('~haveHttpHeader('Client_Id', 'Codeception');
* `param string` $value the value to set it to for subsequent
requests
-### moveBack
+### moveBack
+
Moves back in history.
* `param int` $numberOfSteps (default value 1)
-### resetCookie
+### resetCookie
+
Unsets cookie with the given name.
You can set additional cookie params like `domain`, `path` in array passed as last argument.
@@ -607,8 +649,9 @@ You can set additional cookie params like `domain`, `path` in array passed as la
* `param array` $params
-### see
+### see
+
Checks that the current page contains the given string (case insensitive).
You can specify a specific HTML element (via CSS or XPath) as the second
@@ -639,8 +682,9 @@ For checking the raw source code, use `seeInSource()`.
* `param string` $text
* `param string` $selector optional
-### seeCheckboxIsChecked
+### seeCheckboxIsChecked
+
Checks that the specified checkbox is checked.
``` php
@@ -653,8 +697,9 @@ $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
* `param` $checkbox
-### seeCookie
+### seeCookie
+
Checks that a cookie with the given name is set.
You can set additional cookie params like `domain`, `path` as array passed in last argument.
@@ -667,8 +712,9 @@ $I->seeCookie('PHPSESSID');
* `param` $cookie
* `param array` $params
-### seeCurrentUrlEquals
+### seeCurrentUrlEquals
+
Checks that the current URL is equal to the given string.
Unlike `seeInCurrentUrl`, this only matches the full URL.
@@ -681,8 +727,9 @@ $I->seeCurrentUrlEquals('/');
* `param string` $uri
-### seeCurrentUrlMatches
+### seeCurrentUrlMatches
+
Checks that the current URL matches the given regular expression.
``` php
@@ -694,8 +741,9 @@ $I->seeCurrentUrlMatches('~$/users/(\d+)~');
* `param string` $uri
-### seeElement
+### seeElement
+
Checks that the given element exists on the page and is visible.
You can also specify expected attributes of this element.
@@ -715,8 +763,9 @@ $I->seeElement(['css' => 'form input'], ['name' => 'login']);
* `param array` $attributes
@return
-### seeInCurrentUrl
+### seeInCurrentUrl
+
Checks that current URI contains the given string.
``` php
@@ -730,8 +779,9 @@ $I->seeInCurrentUrl('/users/');
* `param string` $uri
-### seeInField
+### seeInField
+
Checks that the given input field or textarea *equals* (i.e. not just contains) the given value.
Fields are matched by label text, the "name" attribute, CSS, or XPath.
@@ -749,8 +799,9 @@ $I->seeInField(['name' => 'search'], 'Search');
* `param` $field
* `param` $value
-### seeInFormFields
+### seeInFormFields
+
Checks if the array of form parameters (name => value) are set on the form matched with the
passed selector.
@@ -811,8 +862,9 @@ $I->seeInFormFields('//form[@id=my-form]', $form);
* `param` $formSelector
* `param` $params
-### seeInSource
+### seeInSource
+
Checks that the current page contains the given string in its
raw source code.
@@ -823,8 +875,9 @@ $I->seeInSource('
Green eggs & ham
');
* `param` $raw
-### seeInTitle
+### seeInTitle
+
Checks that the page title contains the given string.
``` php
@@ -835,8 +888,10 @@ $I->seeInTitle('Blog - Post #1');
* `param` $title
-### seeLink
+
+### seeLink
+
Checks that there's a link with the specified text.
Give a full URL as the second parameter to match links with that exact URL.
@@ -850,8 +905,9 @@ $I->seeLink('Logout','/logout'); // matches Logout
* `param string` $text
* `param string` $url optional
-### seeNumberOfElements
+### seeNumberOfElements
+
Checks that there are a certain number of elements matched by the given locator on the page.
``` php
@@ -863,8 +919,9 @@ $I->seeNumberOfElements('tr', [0,10]); // between 0 and 10 elements
* `param` $selector
* `param mixed` $expected int or int[]
-### seeOptionIsSelected
+### seeOptionIsSelected
+
Checks that the given option is selected.
``` php
@@ -876,12 +933,15 @@ $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
* `param` $selector
* `param` $optionText
-### seePageNotFound
+
+### seePageNotFound
+
Asserts that current page has 404 response status code.
-### seeResponseCodeIs
+### seeResponseCodeIs
+
Checks that response code is equal to value provided.
```php
@@ -894,8 +954,9 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
-### selectOption
+### selectOption
+
Selects an option in a select tag or in radio button group.
``` php
@@ -926,8 +987,9 @@ $I->selectOption('Which OS do you use?', array('value' => 'windows')); // Only s
* `param` $select
* `param` $option
-### sendAjaxGetRequest
+### sendAjaxGetRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a GET ajax request with specified params.
@@ -936,8 +998,9 @@ See ->sendAjaxPostRequest for examples.
* `param` $uri
* `param` $params
-### sendAjaxPostRequest
+### sendAjaxPostRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends a POST ajax request with specified params.
Additional params can be passed as array.
@@ -957,8 +1020,9 @@ $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GE
* `param` $uri
* `param` $params
-### sendAjaxRequest
+### sendAjaxRequest
+
If your page triggers an ajax request, you can perform it manually.
This action sends an ajax request with specified method and params.
@@ -976,8 +1040,9 @@ $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
* `param` $uri
* `param` $params
-### setCookie
+### setCookie
+
Sets a cookie with the given name and value.
You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument.
@@ -991,8 +1056,10 @@ $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
* `param` $val
* `param array` $params
-### submitForm
+
+### submitForm
+
Submits the given form on the page, with the given form
values. Pass the form field's values as an array in the second
parameter.
@@ -1163,8 +1230,9 @@ $I->submitForm('#my-form', [
* `param` $params
* `param` $button
-### switchToIframe
+### switchToIframe
+
Switch to iframe or frame on the page.
Example:
@@ -1180,8 +1248,9 @@ $I->switchToIframe("another_frame");
* `param string` $name
-### uncheckOption
+### uncheckOption
+
Unticks a checkbox.
``` php
@@ -1192,4 +1261,4 @@ $I->uncheckOption('#notify');
* `param` $option
-
diff --git a/docs/reference/XmlBuilder.md b/docs/reference/XmlBuilder.md
index a92855156a..05191c2590 100644
--- a/docs/reference/XmlBuilder.md
+++ b/docs/reference/XmlBuilder.md
@@ -1,10 +1,13 @@
## Codeception\Util\XmlBuilder
+
+
That's a pretty simple yet powerful class to build XML structures in jQuery-like style.
With no XML line actually written!
Uses DOM extension to manipulate XML data.
+
```php
diff --git a/ext/README.md b/ext/README.md
index fde3094b17..a6748b32ff 100644
--- a/ext/README.md
+++ b/ext/README.md
@@ -2,7 +2,7 @@
## DotReporter
-[See Source](https://github.com/Codeception/Codeception/blob/2.3/ext/DotReporter.php)
+[See Source](https://github.com/Codeception/Codeception/blob/2.4/ext/DotReporter.php)
DotReporter provides less verbose output for test execution.
Like PHPUnit printer it prints dots "." for successful testes and "F" for failures.
@@ -24,6 +24,7 @@ Time: 2.07 seconds, Memory: 20.00MB
OK (80 tests, 124 assertions)
```
+
Enable this reporter with `--ext option`
```
@@ -33,9 +34,11 @@ codecept run --ext DotReporter
Failures and Errors are printed by a standard Codeception reporter.
Use this extension as an example for building custom reporters.
+
+
## Logger
-[See Source](https://github.com/Codeception/Codeception/blob/2.3/ext/Logger.php)
+[See Source](https://github.com/Codeception/Codeception/blob/2.4/ext/Logger.php)
Log suites/tests/steps using Monolog library.
Monolog should be installed additionally by Composer.
@@ -57,9 +60,12 @@ extensions:
* `max_files` (default: 3) - how many log files to keep
+
+
+
## Recorder
-[See Source](https://github.com/Codeception/Codeception/blob/2.3/ext/Recorder.php)
+[See Source](https://github.com/Codeception/Codeception/blob/2.4/ext/Recorder.php)
Saves a screenshot of each step in acceptance tests and shows them as a slideshow on one HTML page (here's an [example](http://codeception.com/images/recorder.gif))
Activated only for suites with WebDriver module enabled.
@@ -81,6 +87,7 @@ extensions:
* `delete_successful` (default: true) - delete screenshots for successfully passed tests (i.e. log only failed and errored tests).
* `module` (default: WebDriver) - which module for screenshots to use. Set `AngularJS` if you want to use it with AngularJS module. Generally, the module should implement `Codeception\Lib\Interfaces\ScreenshotSaver` interface.
+
#### Examples:
``` yaml
@@ -91,9 +98,12 @@ extensions:
delete_successful: false # keep screenshots of successful tests
```
+
+
+
## RunFailed
-[See Source](https://github.com/Codeception/Codeception/blob/2.3/ext/RunFailed.php)
+[See Source](https://github.com/Codeception/Codeception/blob/2.4/ext/RunFailed.php)
Saves failed tests into tests/log/failed in order to rerun failed tests.
@@ -118,9 +128,11 @@ extensions:
On each execution failed tests are logged and saved into `tests/_output/failed` file.
+
+
## RunProcess
-[See Source](https://github.com/Codeception/Codeception/blob/2.3/ext/RunProcess.php)
+[See Source](https://github.com/Codeception/Codeception/blob/2.4/ext/RunProcess.php)
Extension to start and stop processes per suite.
Can be used to start/stop selenium server, chromedriver, phantomjs, mailcatcher, etc.
@@ -163,10 +175,14 @@ extensions:
HINT: you can use different configurations per environment.
+
+
## SimpleReporter
-[See Source](https://github.com/Codeception/Codeception/blob/2.3/ext/SimpleReporter.php)
+[See Source](https://github.com/Codeception/Codeception/blob/2.4/ext/SimpleReporter.php)
This extension demonstrates how you can implement console output of your own.
Recommended to be used for development purposes only.
+
+
diff --git a/readme.md b/readme.md
index 49633e4a37..12451b2293 100644
--- a/readme.md
+++ b/readme.md
@@ -5,7 +5,7 @@
[](https://packagist.org/packages/codeception/codeception)
[](https://gitter.im/Codeception/Codeception?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://travis-ci.org/Codeception/Codeception)
-[](https://scrutinizer-ci.com/g/Codeception/Codeception/?branch=2.3)
+[](https://scrutinizer-ci.com/g/Codeception/Codeception/?branch=2.4)
**Modern PHP Testing for everyone**
@@ -15,11 +15,11 @@ Powered by PHPUnit.
| General | Windows | Webdriver | HHVM |
| ------- | -------- | -------- | -------- |
-| [](http://travis-ci.org/Codeception/Codeception) | [](https://ci.appveyor.com/project/DavertMik/codeception/branch/2.3) | [](https://semaphoreci.com/codeception/codeception) | [](https://app.wercker.com/project/byKey/b4eecd0596bedb65333ff7ab7836bc7f) |
+| [](http://travis-ci.org/Codeception/Codeception) | [](https://ci.appveyor.com/project/DavertMik/codeception/branch/2.4) | [](https://semaphoreci.com/codeception/codeception) | [](https://app.wercker.com/project/byKey/b4eecd0596bedb65333ff7ab7836bc7f) |
#### Contributions
-At Codeception we are glad to receive contributions from the community. If you want to send additions or fixes to the code or the documentation please check the [Contributing guide](https://github.com/Codeception/Codeception/blob/2.3/CONTRIBUTING.md).
+At Codeception we are glad to receive contributions from the community. If you want to send additions or fixes to the code or the documentation please check the [Contributing guide](https://github.com/Codeception/Codeception/blob/2.4/CONTRIBUTING.md).
### At a Glance
diff --git a/src/Codeception/Codecept.php b/src/Codeception/Codecept.php
index 95b0235b6c..8e1626d6bf 100644
--- a/src/Codeception/Codecept.php
+++ b/src/Codeception/Codecept.php
@@ -7,7 +7,7 @@
class Codecept
{
- const VERSION = "2.4.0";
+ const VERSION = "2.4.1";
/**
* @var \Codeception\PHPUnit\Runner
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index a5fec31f9a..942eaae15d 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -1,4 +1,5 @@
config['browser'];
$capabilities = $this->config['capabilities'];
}
- $test->getMetadata()->setCurrent([
- 'browser' => $browser,
- 'capabilities' => $capabilities,
- ]);
+ $test->getMetadata()->setCurrent(
+ [
+ 'browser' => $browser,
+ 'capabilities' => $capabilities,
+ ]
+ );
}
/**
@@ -600,11 +603,11 @@ protected function logJSErrors(ScenarioDriven $test, array $browserLogEntries)
protected function isJSError($logEntryLevel, $message)
{
return
- (
- ($this->isPhantom() && $logEntryLevel != 'INFO') // phantomjs logs errors as "WARNING"
- || $logEntryLevel === 'SEVERE' // other browsers log errors as "SEVERE"
- )
- && strpos($message, 'ERR_PROXY_CONNECTION_FAILED') === false; // ignore blackhole proxy
+ (
+ ($this->isPhantom() && $logEntryLevel != 'INFO') // phantomjs logs errors as "WARNING"
+ || $logEntryLevel === 'SEVERE' // other browsers log errors as "SEVERE"
+ )
+ && strpos($message, 'ERR_PROXY_CONNECTION_FAILED') === false; // ignore blackhole proxy
}
public function _afterSuite()
@@ -1044,10 +1047,10 @@ protected function findFields($selector)
$locator = Crawler::xpathLiteral(trim($selector));
// by text or label
$xpath = Locator::combine(
- // @codingStandardsIgnoreStart
+ // @codingStandardsIgnoreStart
".//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')][(((./@name = $locator) or ./@id = //label[contains(normalize-space(string(.)), $locator)]/@for) or ./@placeholder = $locator)]",
".//label[contains(normalize-space(string(.)), $locator)]//.//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]"
- // @codingStandardsIgnoreEnd
+ // @codingStandardsIgnoreEnd
);
$fields = $this->webDriver->findElements(WebDriverBy::xpath($xpath));
if (!empty($fields)) {
@@ -1550,7 +1553,7 @@ protected function findCheckable($context, $radioOrCheckbox, $byValue = false)
$typeLiteral = Crawler::xPathLiteral($contextType);
$inputLocatorFragment = "input[@type = $typeLiteral][@name = $nameLiteral]";
$xpath = Locator::combine(
- // @codingStandardsIgnoreStart
+ // @codingStandardsIgnoreStart
"ancestor::form//{$inputLocatorFragment}[(@id = ancestor::form//label[contains(normalize-space(string(.)), $locator)]/@for) or @placeholder = $locator]",
// @codingStandardsIgnoreEnd
"ancestor::form//label[contains(normalize-space(string(.)), $locator)]//{$inputLocatorFragment}"
@@ -1560,7 +1563,7 @@ protected function findCheckable($context, $radioOrCheckbox, $byValue = false)
}
} else {
$xpath = Locator::combine(
- // @codingStandardsIgnoreStart
+ // @codingStandardsIgnoreStart
"//input[@type = 'checkbox' or @type = 'radio'][(@id = //label[contains(normalize-space(string(.)), $locator)]/@for) or @placeholder = $locator or @name = $locator]",
// @codingStandardsIgnoreEnd
"//label[contains(normalize-space(string(.)), $locator)]//input[@type = 'radio' or @type = 'checkbox']"
@@ -1621,26 +1624,25 @@ public function fillField($field, $value)
{
$el = $this->findField($field);
$el->clear();
- $el->sendKeys((string) $value);
+ $el->sendKeys((string)$value);
}
/**
- * Clears given field which isn't empty.
- *
- * ``` php
- * clearField('#username');
- * ?>
- * ```
- *
- * @param $field
- */
+ * Clears given field which isn't empty.
+ *
+ * ``` php
+ * clearField('#username');
+ * ```
+ *
+ * @param $field
+ */
public function clearField($field)
{
$el = $this->findField($field);
$el->clear();
}
-
+
public function attachFile($field, $filename)
{
$el = $this->findField($field);
@@ -2645,8 +2647,8 @@ public function clickWithLeftButton($cssOrXPath = null, $offsetX = null, $offset
* ```
*
* @param string $cssOrXPath css or xpath of the web element (body by default).
- * @param int $offsetX
- * @param int $offsetY
+ * @param int $offsetX
+ * @param int $offsetY
*
* @throws \Codeception\Exception\ElementNotFound
*/
@@ -2697,7 +2699,7 @@ protected function match($page, $selector, $throwMalformed = true)
if ($this->isPhantom() and $e->getResults()['status'] == 12) {
throw new MalformedLocatorException(
key($selector) . ' => ' . reset($selector),
- "Strict locator ".$e->getCode()
+ "Strict locator " . $e->getCode()
);
}
}
From 7b3ac33e0b05a64c4ac1c8524b8ca9e4fcde8425 Mon Sep 17 00:00:00 2001
From: MilesChou
Date: Wed, 28 Feb 2018 22:22:01 +0800
Subject: [PATCH 009/395] Fix clean command bug when output dir is not exist
(#4834)
Fix the bug when output dir is not exist and run Clean command.
---
src/Codeception/Command/Clean.php | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/Codeception/Command/Clean.php b/src/Codeception/Command/Clean.php
index cf4d5bf05b..05704613fc 100644
--- a/src/Codeception/Command/Clean.php
+++ b/src/Codeception/Command/Clean.php
@@ -31,12 +31,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
private function cleanProjectsRecursively(OutputInterface $output, $projectDir)
{
- $config = Configuration::config($projectDir);
-
- $logDir = $projectDir . DIRECTORY_SEPARATOR . $config['paths']['output'];
+ $logDir = Configuration::logDir();
$output->writeln("Cleaning up output " . $logDir . "...");
FileSystem::doEmptyDir($logDir);
+ $config = Configuration::config($projectDir);
$subProjects = $config['include'];
foreach ($subProjects as $subProject) {
$subProjectDir = $projectDir . $subProject;
From f719c7bb987ca75a937e663816f14b9a03669c4a Mon Sep 17 00:00:00 2001
From: Davert
Date: Wed, 28 Feb 2018 16:23:04 +0200
Subject: [PATCH 010/395] updated release notes
---
CHANGELOG-2.4.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index f925fc89bf..2cc68994fa 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -5,8 +5,13 @@
* Internal API refactored:
* Modern PHP class names used internally
* Moved PHPUnit related classes to [codeception/phpunit-wrapper](https://github.com/Codeception/phpunit-wrapper) package.
+ * Removed `shims` for underscore PHPUnit classes > namespaced PHP classes
* Cest hooks behavior changed (by @fffilimonov):
* `_failed` called when test fails
* `_passed` called when tests is successful
* `_after` is called for failing and successful tests
+**Upgrade Notice**: If you face issues with underscore PHPUnit class names (like PHPUnit_Framework_Assert) you have two options:
+
+* Lock version for PHPUnit in composer.json: "phpunit/phpunit":"^5.0.0"
+* Update your codebase and replace underscore PHPUnit class names to namespaced (PHPUnit 6+ API)
\ No newline at end of file
From ef419075e8c669564deb5f4051803e0dd517130c Mon Sep 17 00:00:00 2001
From: Michael Bodnarchuk
Date: Tue, 6 Mar 2018 23:50:06 +0200
Subject: [PATCH 011/395] Fixed RunCest to be compatible with all PHPUnits
---
tests/cli/RunCest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/cli/RunCest.php b/tests/cli/RunCest.php
index 2115a1ebdb..6aee7c5fde 100644
--- a/tests/cli/RunCest.php
+++ b/tests/cli/RunCest.php
@@ -228,7 +228,7 @@ public function runErrorTest(\CliGuy $I)
$I->executeCommand('run unit ErrorTest --no-exit');
$I->seeInShellOutput('There was 1 error');
$I->seeInShellOutput('Array to string conversion');
- $I->seeInShellOutput('ErrorTest.php:9');
+ $I->seeInShellOutput('ErrorTest.php');
}
public function runTestWithException(\CliGuy $I)
From e76fb09644bcada40d79bee162de46422b198930 Mon Sep 17 00:00:00 2001
From: Vadim
Date: Wed, 7 Mar 2018 01:44:00 +0200
Subject: [PATCH 012/395] Running tests with particular data set index (#4835)
* Make working running test with particular data set by index
Example: codecept run tests/acceptance/FirstCest.php:frontpageWorks#0
* return null if not descriptive
---
src/Codeception/Test/Descriptor.php | 14 ++++++++++++++
src/Codeception/Test/Loader/Cest.php | 3 +++
src/Codeception/Test/Metadata.php | 17 +++++++++++++++++
3 files changed, 34 insertions(+)
diff --git a/src/Codeception/Test/Descriptor.php b/src/Codeception/Test/Descriptor.php
index c68a6e0ef3..7e42dfc7b5 100644
--- a/src/Codeception/Test/Descriptor.php
+++ b/src/Codeception/Test/Descriptor.php
@@ -90,4 +90,18 @@ public static function getTestFullName(\PHPUnit\Framework\SelfDescribing $testCa
}
return self::getTestFileName($testCase) . ':' . $testCase->toString();
}
+
+ /**
+ * Provides a test data set index
+ *
+ * @param \PHPUnit\Framework\SelfDescribing $testCase
+ * @return int|null
+ */
+ public static function getTestDataSetIndex(\PHPUnit\Framework\SelfDescribing $testCase)
+ {
+ if ($testCase instanceof Descriptive) {
+ return $testCase->getMetadata()->getIndex();
+ }
+ return null;
+ }
}
diff --git a/src/Codeception/Test/Loader/Cest.php b/src/Codeception/Test/Loader/Cest.php
index ba69af0d40..a1cbc584fb 100644
--- a/src/Codeception/Test/Loader/Cest.php
+++ b/src/Codeception/Test/Loader/Cest.php
@@ -76,6 +76,7 @@ function ($v) {
if (count($examples)) {
$dataProvider = new \PHPUnit\Framework\DataProviderTestSuite();
+ $index = 0;
foreach ($examples as $k => $example) {
if ($example === null) {
throw new TestParseException(
@@ -87,7 +88,9 @@ function ($v) {
}
$test = new CestFormat($unit, $method, $file);
$test->getMetadata()->setCurrent(['example' => $example]);
+ $test->getMetadata()->setIndex($index);
$dataProvider->addTest($test);
+ $index++;
}
$this->tests[] = $dataProvider;
continue;
diff --git a/src/Codeception/Test/Metadata.php b/src/Codeception/Test/Metadata.php
index 2159c01286..71459cdb7d 100644
--- a/src/Codeception/Test/Metadata.php
+++ b/src/Codeception/Test/Metadata.php
@@ -9,6 +9,7 @@ class Metadata
protected $name;
protected $filename;
protected $feature;
+ protected $index;
protected $params = [
'env' => [],
@@ -126,6 +127,22 @@ public function getFilename()
return $this->filename;
}
+ /**
+ * @param mixed $index
+ */
+ public function setIndex($index)
+ {
+ $this->index = $index;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getIndex()
+ {
+ return $this->index;
+ }
+
/**
* @param mixed $filename
*/
From 72caa1400e735e90a0c0bbe0e1dc2862eef7b251 Mon Sep 17 00:00:00 2001
From: Michael Bodnarchuk
Date: Wed, 7 Mar 2018 14:36:40 +0200
Subject: [PATCH 013/395] Fixing windows builds (#4849)
* Fixing windows builds
* Skip mongodb tests
* Update appveyor.yml
* Update appveyor.yml
* Update .travis.yml
Nor memory limit for composer
* Update .travis.yml
* Update .travis.yml
* Update .travis.yml
---
.travis.yml | 5 +++++
appveyor.yml | 7 +------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index fe5d526213..a78018cefe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,6 +33,11 @@ services:
- postgresql
- redis
+
+before_install:
+ - export INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+ - echo memory_limit = -1 >> $INI
+
install:
- export SF_VERSION=$(echo $SYMFONY | head -c 1)
- 'pecl install -f mongodb'
diff --git a/appveyor.yml b/appveyor.yml
index aa810db8ed..70955c10c8 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -35,11 +35,7 @@ install:
- net start wuauserv
- IF %PHP%==1 cinst -y php --version 7.1.14
- IF %PHP%==1 cd c:\tools\php71
- - IF %PHP%==1 cd ext
- - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/mongodb/1.2.0/php_mongodb-1.2.0-7.1-nts-vc14-x64.zip
- - IF %PHP%==1 7z x php_mongodb-1.2.0-7.1-nts-vc14-x64.zip -y >nul
- - IF %PHP%==1 cd ..
- - IF %PHP%==1 copy php.ini-production php.ini
+ - IF %PHP%==1 copy php.ini-production php.ini
- IF %PHP%==1 echo extension_dir=ext >> php.ini
- IF %PHP%==1 echo extension=php_openssl.dll >> php.ini
- IF %PHP%==1 echo date.timezone="UTC" >> php.ini
@@ -49,7 +45,6 @@ install:
- IF %PHP%==1 echo extension=php_pdo_pgsql.dll >> php.ini
- IF %PHP%==1 echo extension=php_pdo_sqlite.dll >> php.ini
- IF %PHP%==1 echo extension=php_pgsql.dll >> php.ini
- - IF %PHP%==1 echo extension=php_mongodb.dll >> php.ini
- SET PATH=C:\tools\php71;%PATH%
- cd %APPVEYOR_BUILD_FOLDER%
- appveyor DownloadFile https://getcomposer.org/composer.phar
From bfff25a16e0a81d51f070c7c03e825f48d2ba1ea Mon Sep 17 00:00:00 2001
From: Mohamed Aiman
Date: Sun, 11 Mar 2018 23:44:37 +0500
Subject: [PATCH 014/395] Laravel 5.4+ (5.1+ backward compatible) support for
callArtisan method in Laravel5 module. (#4860)
Added Laravel 5.4+ backward compatible support for callArtisan method in Laravel5 module.
Laravel 5.4 Laravel enables a third parameter can be passed to the call method (https://laravel.com/api/5.4/Illuminate/Foundation/Console/Kernel.html#method_call) of console Kernel. Which enables the developer to control the output while using commands within commands etc.
For example here is a sample command.
What does it do?
When the command is executed it calls an Artisan command which from inside calls to other Artisan commands.
If the proposed change is made the output interface (OutputInterface $output) that is being by default by Codeception execute method can be passed on to the Laravel artisan commands, which then will let the outputs be printed to the console as one would expect, else it won't be displayed.
```php
config['modules']['config'][$moduleName])
? $this->config['modules']['config'][$moduleName]
: [];
if (!isset($this->config['modules']['enabled'])) {
return $config;
}
if (!is_array($this->config['modules']['enabled'])) {
return $config;
}
foreach ($this->config['modules']['enabled'] as $enabledModuleConfig) {
if (!is_array($enabledModuleConfig)) {
continue;
}
$enabledModuleName = key($enabledModuleConfig);
if ($enabledModuleName === $moduleName) {
return Configuration::mergeConfigs(reset($enabledModuleConfig), $config);
}
}
return $config;
}
public function getDescription()
{
return "As the database is huge, this command does the initial migrations, seeding,
create initial users and attach roles, permissions ";
}
protected function execute(InputInterface $input, OutputInterface $output)
{
//just for example
$this->config = Configuration::suiteSettings('acceptance', Configuration::config());
$mc = $this->moduleContainer = new ModuleContainer(new Di(), $this->config);
$laravel = new \Helper\Laravel($mc, $this->getModuleConfig('Helper\Laravel'));
new \Codeception\Lib\Connector\Laravel5($laravel);
$laravel->callArtisan('multipleartisan:commandThatHasOtherCommandsInside', [], $output);
}
}
```php
---
src/Codeception/Module/Laravel5.php | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/Codeception/Module/Laravel5.php b/src/Codeception/Module/Laravel5.php
index a1633a0838..2c537b3681 100644
--- a/src/Codeception/Module/Laravel5.php
+++ b/src/Codeception/Module/Laravel5.php
@@ -14,6 +14,7 @@
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Support\Collection;
+use Symfony\Component\Console\Output\OutputInterface;
/**
*
@@ -423,13 +424,18 @@ public function dontSeeEventTriggered($events)
* @param string $command
* @param array $parameters
+ * @param OutputInterface $output
*/
- public function callArtisan($command, $parameters = [])
+ public function callArtisan($command, $parameters = [], OutputInterface $output = null)
{
$console = $this->app->make('Illuminate\Contracts\Console\Kernel');
- $console->call($command, $parameters);
-
- return trim($console->output());
+ if (!$output) {
+ $console->call($command, $parameters);
+ return trim($console->output());
+ }
+
+ $console->call($command, $parameters, $output);
+
}
/**
From 58104f1c8bdfe08e46f4315cecd7b366e99ca8f7 Mon Sep 17 00:00:00 2001
From: Nikolay Geo
Date: Tue, 13 Mar 2018 09:59:01 +1100
Subject: [PATCH 015/395] cleanup of unnecessary escaping in operation
arguments logging (#4856)
---
src/Codeception/Step.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/Codeception/Step.php b/src/Codeception/Step.php
index 3c0bdd4364..ad90235e90 100644
--- a/src/Codeception/Step.php
+++ b/src/Codeception/Step.php
@@ -164,8 +164,9 @@ protected function stringifyArgument($argument)
$argument = $this->getClassName($argument);
}
}
-
- return json_encode($argument, JSON_UNESCAPED_UNICODE);
+ $arg_str = json_encode($argument, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+ $arg_str = str_replace('\"', '"', $arg_str);
+ return $arg_str;
}
protected function getClassName($argument)
From 5089d2990094e0a50684a2e42f1b01aa4c3c19b8 Mon Sep 17 00:00:00 2001
From: Nikolay Geo
Date: Tue, 13 Mar 2018 10:00:45 +1100
Subject: [PATCH 016/395] Fixed humanize for utf8 strings (#4850)
* Fixed humanize for utf8 strings
* added encoding to case convertion and updated conversion to always be mb_
---
src/Codeception/Step.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Codeception/Step.php b/src/Codeception/Step.php
index ad90235e90..b5b9eb78a4 100644
--- a/src/Codeception/Step.php
+++ b/src/Codeception/Step.php
@@ -245,7 +245,7 @@ protected function humanize($text)
$text = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\\1 \\2', $text);
$text = preg_replace('/([a-z\d])([A-Z])/', '\\1 \\2', $text);
$text = preg_replace('~\bdont\b~', 'don\'t', $text);
- return strtolower($text);
+ return mb_strtolower($text, 'UTF-8');
}
public function run(ModuleContainer $container = null)
From 50f4edd284a0f0a9871ccc4c5fe44465b05d3fd5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=9E=D0=BB=D0=B5=D0=B3=20=D0=9C=D0=B0=D0=BA=D1=81=D0=B8?=
=?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BA=D0=BE?=
Date: Tue, 13 Mar 2018 01:27:40 +0200
Subject: [PATCH 017/395] Fixed making for $settings['path'] in
Codeception\Configuration::suiteSettings() on Windows (#4843)
---
src/Codeception/Configuration.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/Codeception/Configuration.php b/src/Codeception/Configuration.php
index a0f0b21dd8..e5ebe96402 100644
--- a/src/Codeception/Configuration.php
+++ b/src/Codeception/Configuration.php
@@ -320,6 +320,8 @@ public static function suiteSettings($suite, $config)
$settings['path'] = $suite;
}
+ $config['paths']['tests'] = str_replace('/', DIRECTORY_SEPARATOR, $config['paths']['tests']);
+
$settings['path'] = self::$dir . DIRECTORY_SEPARATOR . $config['paths']['tests']
. DIRECTORY_SEPARATOR . $settings['path'] . DIRECTORY_SEPARATOR;
From 93936b706cd3013264cda0af3258b1734be91563 Mon Sep 17 00:00:00 2001
From: quantum-x
Date: Tue, 13 Mar 2018 00:28:46 +0100
Subject: [PATCH 018/395] 2.4 bug 4847 (#4853)
* Update Uri.php
PHP's parse_url fails on specific relative URLs.
If the absolute URL is passed, it parses as expected.
PHP Known bug: https://bugs.php.net/bug.php?id=70942
Discussion thread: https://github.com/Codeception/Codeception/issues/4847
* Update UriTest.php
* Cleaning code
- Removing ternary
- Splitting $baseUri to $base.$uri (both work)
---
src/Codeception/Util/Uri.php | 7 +++++++
tests/unit/Codeception/Util/UriTest.php | 8 ++++++++
2 files changed, 15 insertions(+)
diff --git a/src/Codeception/Util/Uri.php b/src/Codeception/Util/Uri.php
index 3322488453..3719596e06 100644
--- a/src/Codeception/Util/Uri.php
+++ b/src/Codeception/Util/Uri.php
@@ -20,6 +20,13 @@ public static function mergeUrls($baseUri, $uri)
{
$base = new Psr7Uri($baseUri);
$parts = parse_url($uri);
+
+ //If the relative URL does not parse, attempt to parse the entire URL.
+ //PHP Known bug ( https://bugs.php.net/bug.php?id=70942 )
+ if ($parts === false) {
+ $parts = parse_url($base.$uri);
+ }
+
if ($parts === false) {
throw new \InvalidArgumentException("Invalid URI $uri");
}
diff --git a/tests/unit/Codeception/Util/UriTest.php b/tests/unit/Codeception/Util/UriTest.php
index 02117b97c7..2f44ec0218 100644
--- a/tests/unit/Codeception/Util/UriTest.php
+++ b/tests/unit/Codeception/Util/UriTest.php
@@ -50,6 +50,14 @@ public function testMergingPath()
$this->assertEquals('/form/?param=1#anchor2', Uri::mergeUrls('/form/?param=1#anchor1', '#anchor2'));
$this->assertEquals('/form/?param=2', Uri::mergeUrls('/form/?param=1#anchor', '?param=2'));
$this->assertEquals('/page/', Uri::mergeUrls('/form/?param=1#anchor', '/page/'));
+ }
+
+ /**
+ * @Issue https://github.com/Codeception/Codeception/pull/4847
+ */
+ public function testMergingNonParsingPath()
+ {
+ $this->assertEquals('/3.0/en/index/page:5', Uri::mergeUrls('https://cakephp.org/', '/3.0/en/index/page:5'));
}
/**
From 69150097f19bb408b79cda0c1364e1a18316276b Mon Sep 17 00:00:00 2001
From: Nick Denry
Date: Tue, 20 Mar 2018 22:55:28 +0300
Subject: [PATCH 019/395] Fix typo (#4882) [skip ci]
Fix typo at line 104, missing close square bracket
---
docs/modules/Yii2.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/modules/Yii2.md b/docs/modules/Yii2.md
index ed6bb2c955..ab0e376330 100644
--- a/docs/modules/Yii2.md
+++ b/docs/modules/Yii2.md
@@ -101,7 +101,7 @@ This commands allows input like:
$I->amOnPage(['site/view','page'=>'about']);
$I->amOnPage('index-test.php?site/index');
$I->amOnPage('http://localhost/index-test.php?site/index');
-$I->sendAjaxPostRequest(['/user/update', 'id' => 1], ['UserForm[name]' => 'G.Hopper');
+$I->sendAjaxPostRequest(['/user/update', 'id' => 1], ['UserForm[name]' => 'G.Hopper']);
```
## Status
From f88f50bcf79542731ddc9117b2c1e74c91956944 Mon Sep 17 00:00:00 2001
From: Sam
Date: Thu, 29 Mar 2018 11:30:56 +0200
Subject: [PATCH 020/395] Reorganized travis jobs (#4893)
* Reorganized travis jobs
* Disabled Yii2 tests
---
.travis.yml | 191 +++++++++++++++++++++++++---------------------------
1 file changed, 92 insertions(+), 99 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index a78018cefe..e55226708f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,20 +1,58 @@
sudo: false
language: php
-
+matrix:
+ fast_finish: true
+php:
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.2
+env:
+ global:
+ - XDEBUG=
+ - SUITES=
+ - FXP=
+ - PECL=
+ - TEST_PATH='framework-tests'
+ - SYMFONY_DEPRECATIONS_HELPER=weak
+ matrix:
+ - FRAMEWORK=Codeception SUITES=cli,unit TEST_PATH=. XDEBUG=1 PECL=mongodb
+ #- FRAMEWORK=Yii2 TEST_REPO="https://github.com/Codeception/yii2-tests"
+ - FRAMEWORK=Symfony VERSION=2.8 TEST_REPO='-b 2.1 https://github.com/Codeception/symfony-demo.git' SUITES=functional TEST_PATH=framework-tests/src/AppBundle
+ - FRAMEWORK=Symfony VERSION=3.4 TEST_REPO='--recurse-submodules https://github.com/Naktibalda/codeception-symfony-tests'
+ - FRAMEWORK=Symfony VERSION=4 TEST_REPO='https://github.com/Codeception/symfony-demo.git' SUITES=functional,unit
+ - FRAMEWORK=Lumen TEST_REPO='-b codeception-2.2 https://github.com/codeception/codeception-lumen-sample.git'
+ - FRAMEWORK=Laravel TEST_REPO='-b codeception-2.3 https://github.com/codeception/codeception-laravel5-sample.git'
+ - FRAMEWORK=Phalcon TEST_REPO=https://github.com/Codeception/phalcon-demo.git
+ - FRAMEWORK=Zend1 TEST_REPO='-b 2.2 --recurse-submodules https://github.com/Naktibalda/codeception-zf1-tests'
+ - FRAMEWORK=Zend2 TEST_REPO='-b 2.2 --recurse-submodules https://github.com/Naktibalda/codeception-zf2-tests' SUITES=functional
+ - FRAMEWORK=ZendExpressive TEST_REPO='-b 2.2 --recurse-submodules https://github.com/Naktibalda/codeception-zend-expressive-tests' SUITES=functional
matrix:
include:
- - php: 5.6
- env: SYMFONY=2.8.12 SYMFONY_DEPRECATIONS_HELPER=weak # latest version of 2.8.*
- - php: 7.0
- env: SYMFONY=3.2.9 SYMFONY_DEPRECATIONS_HELPER=weak # latest version of 3.2.*
- - php: 7.1
- env: SYMFONY=3.3.2 SYMFONY_DEPRECATIONS_HELPER=weak # latest version of 3.3.*
- - php: 7.1
- env: SYMFONY=4.0.1 SYMFONY_DEPRECATIONS_HELPER=weak # latest version of 4.0.*
- - php: 7.2
- env: SYMFONY=4.0.1 SYMFONY_DEPRECATIONS_HELPER=weak # latest version of 4.0.*
-
+ - php: 7.1
+ env: FRAMEWORK=Codeception SUITES=cli,unit,coverage TEST_PATH=. XDEBUG=1 PECL=mongodb
+ exclude:
+ - php: 7.1
+ env: FRAMEWORK=Codeception SUITES=cli,unit TEST_PATH=. XDEBUG=1 PECL=mongodb
+ - php: 7.0
+ env: FRAMEWORK=Symfony VERSION=2.8 TEST_REPO='-b 2.1 https://github.com/Codeception/symfony-demo.git' SUITES=functional TEST_PATH=framework-tests/src/AppBundle
+ - php: 7.1
+ env: FRAMEWORK=Symfony VERSION=2.8 TEST_REPO='-b 2.1 https://github.com/Codeception/symfony-demo.git' SUITES=functional TEST_PATH=framework-tests/src/AppBundle
+ - php: 7.2
+ env: FRAMEWORK=Symfony VERSION=2.8 TEST_REPO='-b 2.1 https://github.com/Codeception/symfony-demo.git' SUITES=functional TEST_PATH=framework-tests/src/AppBundle
+ - php: 5.6
+ env: FRAMEWORK=Symfony VERSION=3.4 TEST_REPO='--recurse-submodules https://github.com/Naktibalda/codeception-symfony-tests'
+ - php: 7.0
+ env: FRAMEWORK=Symfony VERSION=3.4 TEST_REPO='--recurse-submodules https://github.com/Naktibalda/codeception-symfony-tests'
+ - php: 5.6
+ env: FRAMEWORK=Symfony VERSION=4 TEST_REPO='https://github.com/Codeception/symfony-demo.git' SUITES=functional,unit
+ - php: 7.0
+ env: FRAMEWORK=Symfony VERSION=4 TEST_REPO='https://github.com/Codeception/symfony-demo.git' SUITES=functional,unit
+# - php: 7.1
+# env: FRAMEWORK=ZendExpressive TEST_REPO='-b 2.2 --recurse-submodules https://github.com/Naktibalda/codeception-zend-expressive-tests' functional
+# - php: 7.2
+# env: FRAMEWORK=ZendExpressive TEST_REPO='-b 2.2 --recurse-submodules https://github.com/Naktibalda/codeception-zend-expressive-tests' functional
addons:
postgresql: "9.2"
@@ -33,107 +71,62 @@ services:
- postgresql
- redis
-
before_install:
+ - '[[ !(-z "$XDEBUG") ]] || phpenv config-rm xdebug.ini'
- export INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- echo memory_limit = -1 >> $INI
-
install:
- - export SF_VERSION=$(echo $SYMFONY | head -c 1)
- - 'pecl install -f mongodb'
- - yes '' | pecl install imagick
- #- echo "extension = mongodb.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- - composer self-update && composer --version
- - if [ -n "$CI_USER_TOKEN" ]; then composer config github-oauth.github.com ${CI_USER_TOKEN}; echo "Configured Github token"; fi;
- - 'composer require mongodb/mongodb --no-update'
- - '[[ "$TRAVIS_PHP_VERSION" == "7.2" ]] || composer global require "fxp/composer-asset-plugin:~1.3.1"'
- - '[[ -z "$SYMFONY" ]] || composer require symfony/finder=~$SYMFONY --no-update --ignore-platform-reqs'
- - '[[ -z "$SYMFONY" ]] || composer require symfony/yaml=~$SYMFONY --no-update --ignore-platform-reqs'
- - '[[ -z "$SYMFONY" ]] || composer require symfony/console=~$SYMFONY --no-update --ignore-platform-reqs'
- - '[[ -z "$SYMFONY" ]] || composer require symfony/event-dispatcher=~$SYMFONY --no-update --ignore-platform-reqs'
- - '[[ -z "$SYMFONY" ]] || composer require symfony/css-selector=~$SYMFONY --no-update --ignore-platform-reqs'
- - '[[ -z "$SYMFONY" ]] || composer require symfony/dom-crawler=~$SYMFONY --no-update --ignore-platform-reqs'
- - '[[ -z "$SYMFONY" ]] || composer require symfony/browser-kit=~$SYMFONY --no-update --ignore-platform-reqs'
- - composer_parameters="-n --prefer-dist" # this variable will be used in all composer install commands
- - '[[ "$dependencies" != "lowest" ]] || composer_parameters="$composer_parameters --prefer-lowest"'
- - composer update $composer_parameters
- - composer_parameters="$composer_parameters --no-dev" # Codeception needs dev dependencies, but frameworks don't
- # Yii2
- - '[[ "$TRAVIS_PHP_VERSION" == "7.2" ]] || composer create-project "yiisoft/yii2-app-basic" frameworks-yii-basic --no-dev'
+ - '[[ -z "$CI_USER_TOKEN" ]] || composer config github-oauth.github.com ${CI_USER_TOKEN};'
+ # Add extensions
+ - '[[ -z "$PECL" ]] || (yes "" | pecl install $PECL)'
+ # Clone test repository
+ - '[[ "$FRAMEWORK" == "Codeception" ]] || git clone -q --depth=1 $TEST_REPO framework-tests'
+ - '[[ "$FRAMEWORK" == "Codeception" ]] || git --git-dir framework-tests/.git log -n 1'
+ - '[[ "$FRAMEWORK" != "Codeception" ]] || composer require mongodb/mongodb --no-update'
+ - '[[ -z "$FXP" ]] || composer global require "fxp/composer-asset-plugin:~1.3.1"'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/finder=~$VERSION --no-update --ignore-platform-reqs'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/yaml=~$VERSION --no-update --ignore-platform-reqs'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/console=~$VERSION --no-update --ignore-platform-reqs'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/event-dispatcher=~$VERSION --no-update --ignore-platform-reqs'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/css-selector=~$VERSION --no-update --ignore-platform-reqs'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/dom-crawler=~$VERSION --no-update --ignore-platform-reqs'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/browser-kit=~$VERSION --no-update --ignore-platform-reqs'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || composer require symfony/browser-kit=~$VERSION --no-update --ignore-platform-reqs'
# Phalcon
- - 'git clone -q --depth=1 https://github.com/phalcon/cphalcon.git'
- - '(cd cphalcon/build; bash ./install --phpize $(phpenv which phpize) --php-config $(phpenv which php-config) &>/dev/null && phpenv config-add ../tests/_ci/phalcon.ini &> /dev/null)'
- - 'git clone -q --depth=1 https://github.com/Codeception/phalcon-demo.git frameworks-phalcon'
- - 'composer update -d frameworks-phalcon $composer_parameters'
- # Laravel 5
- - 'git clone -q --depth=1 -b codeception-2.3 https://github.com/codeception/codeception-laravel5-sample.git frameworks-l5'
- - 'composer update -d frameworks-l5 $composer_parameters --no-dev'
- # Lumen
- - 'git clone -q --depth=1 -b codeception-2.2 https://github.com/codeception/codeception-lumen-sample.git frameworks-lumen'
- - 'composer update -d frameworks-lumen $composer_parameters --no-dev'
+ - '[[ "$FRAMEWORK" != "Phalcon" ]] || git clone -q --depth=1 https://github.com/phalcon/cphalcon.git'
+ - '[[ "$FRAMEWORK" != "Phalcon" ]] || (cd cphalcon/build; bash ./install --phpize $(phpenv which phpize) --php-config $(phpenv which php-config) &>/dev/null && phpenv config-add ../tests/_ci/phalcon.ini &> /dev/null)'
# Symfony
- - '[[ "$SF_VERSION" != "2" ]] || (git clone -q --depth=1 -b 2.1 https://github.com/Codeception/symfony-demo.git frameworks-symfony && echo "Cloned Symfony 2 site")'
- - '[[ "$SF_VERSION" != "3" ]] || (git clone -q --depth=1 -b master --recursive https://github.com/Naktibalda/codeception-symfony-tests frameworks-symfony && echo "Cloned Symfony 3 site")'
- - '[[ "$SF_VERSION" != "4" ]] || (git clone -q --depth=1 -b master https://github.com/Codeception/symfony-demo.git frameworks-symfony && echo "Cloned Symfony 4 site")'
- - '[[ "$SF_VERSION" == "4" ]] || composer require -d frameworks-symfony symfony/symfony=~$SYMFONY --no-update'
- - "mysql -e 'create database symfony_test;'"
- - 'composer update -d frameworks-symfony $composer_parameters --no-dev'
- # ZF1
- - git clone -q -b 2.2 --recursive https://github.com/Naktibalda/codeception-zf1-tests frameworks-zf1
- - composer update -d frameworks-zf1 $composer_parameters --no-dev
- # ZF2
- - git clone -q -b 2.2 --recursive https://github.com/Naktibalda/codeception-zf2-tests frameworks-zf2
- - composer update -d frameworks-zf2 $composer_parameters --no-dev
- # Zend Expressive
- - 'git clone -q -b 2.2 --recursive https://github.com/Naktibalda/codeception-zend-expressive-tests frameworks-zend-expressive'
- - 'composer update -d frameworks-zend-expressive $composer_parameters'
-
+ #- '[[ "$FRAMEWORK$VERSION" != "Symfony3" ]] || composer require -d framework-tests symfony/symfony=~$VERSION --no-update'
+ - composer install
+ - '[[ "$FRAMEWORK" == "Codeception" ]] || composer update -d framework-tests --no-dev --prefer-dist'
before_script:
- '[[ "$TRAVIS_PHP_VERSION" == 7.* ]] || echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini'
# preparing databases
- - "mysql -e 'create database codeception_test;'"
- - psql -c 'create database codeception_test;' -U postgres
+ - '[[ "$FRAMEWORK" != "Codeception" ]] || mysql -e "create database codeception_test;"'
+ - '[[ "$FRAMEWORK" != "Codeception" ]] || psql -c "create database codeception_test;" -U postgres'
+ - '[[ "$FRAMEWORK" != "Symfony" ]] || mysql -e "create database symfony_test;"'
# starting demo servers
- - 'php -S 127.0.0.1:8000 -t tests/data/app >/dev/null 2>&1 &'
- - 'php -S 127.0.0.1:8010 -t tests/data >/dev/null 2>&1 &'
+ - '[[ "$FRAMEWORK" != "Codeception" ]] || php -S 127.0.0.1:8000 -t tests/data/app >/dev/null 2>&1 &'
+ - '[[ "$FRAMEWORK" != "Codeception" ]] || php -S 127.0.0.1:8010 -t tests/data >/dev/null 2>&1 &'
# Phalcon
- - mysql -e 'CREATE DATABASE phalcon_demo CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'
- - 'cat frameworks-phalcon/schemas/phalcon_demo.sql | mysql phalcon_demo'
+ - '[[ "$FRAMEWORK" != "Phalcon" ]] || mysql -e "CREATE DATABASE phalcon_demo CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"'
+ - '[[ "$FRAMEWORK" != "Phalcon" ]] || cat framework-tests/schemas/phalcon_demo.sql | mysql phalcon_demo'
# Laravel 5
- - 'touch frameworks-l5/storage/testing.sqlite'
- - 'php frameworks-l5/artisan migrate --env=testing --database=sqlite_testing --force'
+ - '[[ "$FRAMEWORK" != "Laravel" ]] || touch framework-tests/storage/testing.sqlite'
+ - '[[ "$FRAMEWORK" != "Laravel" ]] || php framework-tests/artisan migrate --env=testing --database=sqlite_testing --force'
# Lumen
- - 'cp frameworks-lumen/.env.testing frameworks-lumen/.env'
- - 'touch frameworks-lumen/storage/testing.sqlite'
- - 'php frameworks-lumen/artisan migrate --database=testing --force'
+ - '[[ "$FRAMEWORK" != "Lumen" ]] || cp framework-tests/.env.testing framework-tests/.env'
+ - '[[ "$FRAMEWORK" != "Lumen" ]] || touch framework-tests/storage/testing.sqlite'
+ - '[[ "$FRAMEWORK" != "Lumen" ]] || php framework-tests/artisan migrate --database=testing --force'
# Symfony
- - '[[ "$SF_VERSION" != "2" ]] || php frameworks-symfony/app/console doctrine:schema:create -n --env test'
- - '[[ "$SF_VERSION" != "2" ]] || php frameworks-symfony/app/console doctrine:fixtures:load -n --env test'
- - '[[ "$SF_VERSION" != "3" ]] || php frameworks-symfony/bin/console doctrine:schema:update --force -n'
+ - '[[ "$FRAMEWORK$VERSION" != "Symfony2.8" ]] || php framework-tests/app/console doctrine:schema:create -n --env test'
+ - '[[ "$FRAMEWORK$VERSION" != "Symfony2.8" ]] || php framework-tests/app/console doctrine:fixtures:load -n --env test'
+ - '[[ "$FRAMEWORK$VERSION" != "Symfony3.4" ]] || php framework-tests/bin/console doctrine:schema:update --force -n'
# ZF2
- - "mysql -e 'create database zf2_test;'"
- - php frameworks-zf2/vendor/bin/doctrine-module orm:schema-tool:create
+ - '[[ "$FRAMEWORK" != "Zend2" ]] || mysql -e "create database zf2_test;"'
+ - '[[ "$FRAMEWORK" != "Zend2" ]] || php framework-tests/vendor/bin/doctrine-module orm:schema-tool:create'
# Build
- - '[[ "$TRAVIS_PHP_VERSION" == "7.2" ]] || php codecept build -c frameworks-yii-basic'
- - 'php codecept build -c frameworks-phalcon'
- - '[[ "$SF_VERSION" != "2" ]] || php codecept build -c frameworks-symfony/src/AppBundle'
- - '[[ "$SF_VERSION" == "2" ]] || php codecept build -c frameworks-symfony'
- - 'php codecept build -c frameworks-l5'
- - 'php codecept build -c frameworks-lumen'
- - php codecept build -c frameworks-zf1
- - php codecept build -c frameworks-zf2
- - 'php codecept build -c frameworks-zend-expressive'
-
+ - php codecept build -c $TEST_PATH
script:
- - php codecept run cli,unit # self tests
- - '[[ "$TRAVIS_PHP_VERSION" == "7.0" ]] || php codecept run coverage' # run coverage tests on php only
- - '[[ "$TRAVIS_PHP_VERSION" == "7.2" ]] || php codecept run functional -c frameworks-yii-basic' # Yii2 tests
- - 'php codecept run -c frameworks-l5 --skip=seeder' # Laravel5 Tests
- - 'php codecept run -c frameworks-lumen' # Lumen Tests
- - 'php codecept run functional -c frameworks-phalcon' # Phalcon Tests
- - '[[ "$SF_VERSION" != "2" ]] || php codecept run functional -c frameworks-symfony/src/AppBundle' # Symfony 2 Tests
- - '[[ "$SF_VERSION" != "3" ]] || php codecept run -c frameworks-symfony' # Symfony 3 Tests
- - '[[ "$SF_VERSION" != "4" ]] || php codecept run -c frameworks-symfony functional,unit' # Symfony 4 Tests
- - php codecept run functional -c frameworks-zf1 # ZF1 Tests
- - 'php codecept run -c frameworks-zf2 functional'
- - 'php codecept run functional -c frameworks-zend-expressive' # Zend Expressive Tests
+ #- '[[ !("$FRAMEWORK" == "Codeception" && "$TRAVIS_PHP_VERSION" == "7.1") ]] || php codecept run coverage' # run coverage tests on php only
+ - php codecept run $SUITES -c $TEST_PATH
\ No newline at end of file
From 7da268034b406c593d71c32abc7f1e7b5e3996fc Mon Sep 17 00:00:00 2001
From: Greg Heitz
Date: Sat, 31 Mar 2018 21:43:58 +0200
Subject: [PATCH 021/395] Improve support of PHPUnit warning status (#4901)
---
src/Codeception/Events.php | 7 +++++++
src/Codeception/Subscriber/Console.php | 11 +++++++++++
tests/cli/RunCest.php | 13 ++++++++++++-
tests/data/claypit/tests/unit/WarningTest.php | 15 +++++++++++++++
4 files changed, 45 insertions(+), 1 deletion(-)
create mode 100644 tests/data/claypit/tests/unit/WarningTest.php
diff --git a/src/Codeception/Events.php b/src/Codeception/Events.php
index 6150b36db1..6769200f66 100644
--- a/src/Codeception/Events.php
+++ b/src/Codeception/Events.php
@@ -93,6 +93,13 @@ private function __construct()
*/
const TEST_SKIPPED = 'test.skipped';
+
+ /**
+ * The event listener method receives a {@link Codeception\Event\FailEvent} instance.
+ */
+ const TEST_WARNING = 'test.warning';
+
+
/**
* The event listener method receives a {@link Codeception\Event\TestEvent} instance.
*/
diff --git a/src/Codeception/Subscriber/Console.php b/src/Codeception/Subscriber/Console.php
index 707f3ddd87..22b38b8d63 100644
--- a/src/Codeception/Subscriber/Console.php
+++ b/src/Codeception/Subscriber/Console.php
@@ -40,6 +40,7 @@ class Console implements EventSubscriberInterface
Events::TEST_ERROR => 'testError',
Events::TEST_INCOMPLETE => 'testIncomplete',
Events::TEST_SKIPPED => 'testSkipped',
+ Events::TEST_WARNING => 'testWarning',
Events::TEST_FAIL_PRINT => 'printFail',
Events::RESULT_PRINT_AFTER => 'afterResult',
];
@@ -236,6 +237,16 @@ public function endTest(TestEvent $e)
$this->printedTest = null;
}
+ public function testWarning(TestEvent $e)
+ {
+ if ($this->isDetailed($e->getTest())) {
+ $this->message('WARNING')->center(' ')->style('pending')->append("\n")->writeln();
+
+ return;
+ }
+ $this->writelnFinishedTest($e, $this->message('W')->style('pending'));
+ }
+
public function testFail(FailEvent $e)
{
if ($this->isDetailed($e->getTest())) {
diff --git a/tests/cli/RunCest.php b/tests/cli/RunCest.php
index 6aee7c5fde..51e5ef6e9d 100644
--- a/tests/cli/RunCest.php
+++ b/tests/cli/RunCest.php
@@ -474,7 +474,7 @@ public function runTestWithCustomSetupMethod(CliGuy $I)
$I->executeCommand('run powers PowerUpCest');
$I->dontSeeInShellOutput('FAILURES');
}
-
+
public function runCestWithTwoFailedTest(CliGuy $I)
{
$I->executeCommand('run scenario PartialFailedCest', false);
@@ -483,4 +483,15 @@ public function runCestWithTwoFailedTest(CliGuy $I)
$I->seeInShellOutput('Tests: 3,');
$I->seeInShellOutput('Failures: 2.');
}
+
+
+ public function runWarningTests(CliGuy $I)
+ {
+ $I->executeCommand('run unit WarningTest.php:testWarningInvalidDataProvider', false);
+ $I->seeInShellOutput('There was 1 warning');
+ $I->seeInShellOutput('WarningTest::testWarningInvalidDataProvider');
+ $I->seeInShellOutput('Tests: 1,');
+ $I->seeInShellOutput('Warnings: 1.');
+ }
+
}
diff --git a/tests/data/claypit/tests/unit/WarningTest.php b/tests/data/claypit/tests/unit/WarningTest.php
new file mode 100644
index 0000000000..b2d46b2368
--- /dev/null
+++ b/tests/data/claypit/tests/unit/WarningTest.php
@@ -0,0 +1,15 @@
+assertTrue(true);
+ }
+ public function dependentProvider()
+ {
+ throw new Exception;
+ }
+}
From 53d7af85a51324e8a256d87b09770a46c94cdd62 Mon Sep 17 00:00:00 2001
From: Greg Heitz
Date: Sat, 31 Mar 2018 21:44:45 +0200
Subject: [PATCH 022/395] Update Advanced Usage documentation for dataprovider
(#4900)
---
docs/07-AdvancedUsage.md | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/docs/07-AdvancedUsage.md b/docs/07-AdvancedUsage.md
index 637d0afca2..9d8377cc41 100644
--- a/docs/07-AdvancedUsage.md
+++ b/docs/07-AdvancedUsage.md
@@ -61,18 +61,18 @@ class BasicCest
}
```
-As you see, Cest classes have no parents.
+As you see, Cest classes have no parents.
This is done intentionally. It allows you to extend your classes with common behaviors and workarounds
that may be used in child classes. But don't forget to make these methods `protected` so they won't be executed as tests.
-Cest format also can contain hooks based on test results:
+Cest format also can contain hooks based on test results:
* `_failed` will be executed on failed test
* `_passed` will be executed on passed test
```php
sendGET($example[0]);
$I->seeResponseCodeIs($example[1]);
}
+}
```
JSON:
```php
see($example['title'], 'h1');
$I->seeInTitle($example['title']);
}
+}
```
@@ -230,6 +236,8 @@ Key-value data in Doctrine-style annotation syntax:
```php
see($example['title'], 'h1');
$I->seeInTitle($example['title']);
}
+}
```
-You can also use the `@dataprovider` annotation for creating dynamic examples, using a protected method for providing example data:
+## DataProvider Annotations
+
+You can also use the `@dataProvider` annotation for creating dynamic examples for [Cest classes](#Cest-Classes), using a **protected method** for providing example data:
```php
"/contact", 'title'=>"Contact Us"]
];
}
+}
```
-### Before/After Annotations
+`@dataprovider` annotation is also available for [unit tests](https://codeception.com/docs/05-UnitTests), in this case the data provider **method must be public**.
+For more details about how to use data provider for unit tests, please refer to [PHPUnit documentation](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers).
+
+## Before/After Annotations
You can control execution flow with `@before` and `@after` annotations. You may move common actions
into protected (non-test) methods and invoke them before or after the test method by putting them into annotations.
From 08e487b0854bcc1f8a8478a5d5b7cf9713cbbc76 Mon Sep 17 00:00:00 2001
From: Sam
Date: Sat, 31 Mar 2018 22:33:03 +0200
Subject: [PATCH 023/395] Yii2 rework, new PR same changes. (#4894)
* Reorganized travis jobs
* Improved Yii2 module
* Fixed issue and updated docs
* Added notice about absence of $app.
* Fixed weird sentence
---
.travis.yml | 2 +-
CHANGELOG-2.4.md | 10 +-
src/Codeception/Lib/Connector/Yii2.php | 173 +++++++--------
src/Codeception/Module/Yii2.php | 282 +++++++++++++++++++------
4 files changed, 300 insertions(+), 167 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index e55226708f..ebf56b4572 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,7 +18,7 @@ env:
- SYMFONY_DEPRECATIONS_HELPER=weak
matrix:
- FRAMEWORK=Codeception SUITES=cli,unit TEST_PATH=. XDEBUG=1 PECL=mongodb
- #- FRAMEWORK=Yii2 TEST_REPO="https://github.com/Codeception/yii2-tests"
+ - FRAMEWORK=Yii2 TEST_REPO="https://github.com/Codeception/yii2-tests"
- FRAMEWORK=Symfony VERSION=2.8 TEST_REPO='-b 2.1 https://github.com/Codeception/symfony-demo.git' SUITES=functional TEST_PATH=framework-tests/src/AppBundle
- FRAMEWORK=Symfony VERSION=3.4 TEST_REPO='--recurse-submodules https://github.com/Naktibalda/codeception-symfony-tests'
- FRAMEWORK=Symfony VERSION=4 TEST_REPO='https://github.com/Codeception/symfony-demo.git' SUITES=functional,unit
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 2cc68994fa..70b806a390 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -10,8 +10,14 @@
* `_failed` called when test fails
* `_passed` called when tests is successful
* `_after` is called for failing and successful tests
-
+* Yii2 Module request flow and database transactions refactored (by @sammousa):
+ * Multiple databases are now supported
+ * More reliable application state before and during test execution
+ * Fixtures method is now configurable
+ * Subset of misconfigurations are now detected and create informative messages
+ * Application is no longer available via the `$module->app`, now you must use `\Yii::$app` everywhere
**Upgrade Notice**: If you face issues with underscore PHPUnit class names (like PHPUnit_Framework_Assert) you have two options:
* Lock version for PHPUnit in composer.json: "phpunit/phpunit":"^5.0.0"
-* Update your codebase and replace underscore PHPUnit class names to namespaced (PHPUnit 6+ API)
\ No newline at end of file
+* Update your codebase and replace underscore PHPUnit class names to namespaced (PHPUnit 6+ API)
+
diff --git a/src/Codeception/Lib/Connector/Yii2.php b/src/Codeception/Lib/Connector/Yii2.php
index 667ee20a37..9624f05713 100644
--- a/src/Codeception/Lib/Connector/Yii2.php
+++ b/src/Codeception/Lib/Connector/Yii2.php
@@ -2,14 +2,16 @@
namespace Codeception\Lib\Connector;
use Codeception\Lib\Connector\Yii2\Logger;
-use Codeception\Lib\Connector\Yii2\TestMailer;
+use Codeception\Lib\InnerBrowser;
use Codeception\Util\Debug;
use Symfony\Component\BrowserKit\Client;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\BrowserKit\Response;
use Yii;
use yii\base\ExitException;
+use yii\base\Security;
use yii\web\HttpException;
+use yii\web\Request;
use yii\web\Response as YiiResponse;
class Yii2 extends Client
@@ -21,71 +23,41 @@ class Yii2 extends Client
*/
public $configFile;
- public $defaultServerVars = [];
-
- /**
- * @var array
- */
- public $headers;
- public $statusCode;
-
- /**
- * @var \yii\web\Application
- */
- private $app;
-
- /**
- * @var \yii\db\Connection
- */
- public static $db; // remember the db instance
-
- /**
- * @var TestMailer
- */
- public static $mailer;
-
/**
* @return \yii\web\Application
*/
public function getApplication()
{
- if (!isset($this->app)) {
+ if (!isset(Yii::$app)) {
$this->startApp();
}
- return $this->app;
+ return Yii::$app;
}
public function resetApplication()
{
- $this->app = null;
+ codecept_debug('Destroying application');
+ Yii::$app = null;
+ \yii\web\UploadedFile::reset();
+ if (method_exists(\yii\base\Event::className(), 'offAll')) {
+ \yii\base\Event::offAll();
+ }
+ Yii::setLogger(null);
}
public function startApp()
{
+ codecept_debug('Starting application');
$config = require($this->configFile);
if (!isset($config['class'])) {
$config['class'] = 'yii\web\Application';
}
- if (static::$db) {
- // If the DB conection already exists, make sure to pass it as early as possible
- // to prevent application from new connection creating during bootstrap
- $config['components']['db'] = static::$db;
- }
+
+ $config = $this->mockMailer($config);
/** @var \yii\web\Application $app */
- $this->app = Yii::createObject($config);
- $this->persistDb();
- $this->mockMailer($config);
- \Yii::setLogger(new Logger());
- }
+ Yii::$app = Yii::createObject($config);
- public function resetPersistentVars()
- {
- static::$db = null;
- static::$mailer = null;
- \yii\web\UploadedFile::reset();
- if (method_exists(\yii\base\Event::className(), 'offAll')) {
- \yii\base\Event::offAll();
- }
+ Yii::setLogger(new Logger());
}
/**
@@ -98,7 +70,6 @@ public function doRequest($request)
{
$_COOKIE = $request->getCookies();
$_SERVER = $request->getServer();
- $this->restoreServerVars();
$_FILES = $this->remapFiles($request->getFiles());
$_REQUEST = $this->remapRequestParameters($request->getParameters());
$_POST = $_GET = [];
@@ -123,20 +94,28 @@ public function doRequest($request)
$app = $this->getApplication();
- $app->getResponse()->on(YiiResponse::EVENT_AFTER_PREPARE, [$this, 'processResponse']);
+ /**
+ * Just before the request we set the response object so it is always fresh.
+ * @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
+ * those changes to be reflected in the reponse.
+ */
+ $app->set('response', $app->getComponents()['response']);
// disabling logging. Logs are slowing test execution down
foreach ($app->log->targets as $target) {
$target->enabled = false;
}
- $this->headers = [];
- $this->statusCode = null;
-
ob_start();
// recreating request object to reset headers and cookies collections
+ /**
+ * Just before the request we set the request object so it is always fresh.
+ * @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
+ * those changes to be reflected in the reponse.
+ */
$app->set('request', $app->getComponents()['request']);
+
$yiiRequest = $app->getRequest();
if ($request->getContent() !== null) {
$yiiRequest->setRawBody($request->getContent());
@@ -148,17 +127,23 @@ public function doRequest($request)
$yiiRequest->setQueryParams($_GET);
try {
+ /*
+ * This is basically equivalent to $app->run() without sending the response.
+ * Sending the response is problematic because it tries to send headers.
+ */
$app->trigger($app::EVENT_BEFORE_REQUEST);
-
- $app->handleRequest($yiiRequest)->send();
-
+ $response = $app->handleRequest($yiiRequest);
$app->trigger($app::EVENT_AFTER_REQUEST);
+ codecept_debug($response->isSent);
+ $response->send();
} catch (\Exception $e) {
if ($e instanceof HttpException) {
// Don't discard output and pass exception handling to Yii to be able
// to expect error response codes in tests.
$app->errorHandler->discardExistingOutput = false;
$app->errorHandler->handleException($e);
+ $response = $app->response;
+
} elseif (!$e instanceof ExitException) {
// for exceptions not related to Http, we pass them to Codeception
$this->resetApplication();
@@ -166,17 +151,18 @@ public function doRequest($request)
}
}
- $content = ob_get_clean();
+ $this->encodeCookies($response, $yiiRequest, $app->security);
- // catch "location" header and display it in debug, otherwise it would be handled
- // by symfony browser-kit and not displayed.
- if (isset($this->headers['location'])) {
- Debug::debug("[Headers] " . json_encode($this->headers));
+ if ($response->isRedirection) {
+ Debug::debug("[Redirect with headers]" . print_r($response->getHeaders()->toArray(), true));
}
- $this->resetApplication();
+ $content = ob_get_clean();
+ if (empty($content) && !empty($response->content)) {
+ throw new \Exception('No content was sent from Yii application');
+ }
- return new Response($content, $this->statusCode, $this->headers);
+ return new Response($content, $response->statusCode, $response->getHeaders()->toArray());
}
protected function revertErrorHandler()
@@ -186,36 +172,28 @@ protected function revertErrorHandler()
}
- public function restoreServerVars()
- {
- $this->server = $this->defaultServerVars;
- foreach ($this->server as $key => $value) {
- $_SERVER[$key] = $value;
- }
- }
-
- public function processResponse($event)
- {
- /** @var \yii\web\Response $response */
- $response = $event->sender;
- $request = Yii::$app->getRequest();
- $this->headers = $response->getHeaders()->toArray();
- $response->getHeaders()->removeAll();
- $this->statusCode = $response->getStatusCode();
- $cookies = $response->getCookies();
-
+ /**
+ * Encodes the cookies and adds them to the headers.
+ * @param \yii\web\Response $response
+ * @throws \yii\base\InvalidConfigException
+ */
+ protected function encodeCookies(
+ YiiResponse $response,
+ Request $request,
+ Security $security
+ ) {
if ($request->enableCookieValidation) {
$validationKey = $request->cookieValidationKey;
}
- foreach ($cookies as $cookie) {
+ foreach ($response->getCookies() as $cookie) {
/** @var \yii\web\Cookie $cookie */
$value = $cookie->value;
if ($cookie->expire != 1 && isset($validationKey)) {
$data = version_compare(Yii::getVersion(), '2.0.2', '>')
? [$cookie->name, $cookie->value]
: $cookie->value;
- $value = Yii::$app->security->hashData(serialize($data), $validationKey);
+ $value = $security->hashData(serialize($data), $validationKey);
}
$c = new Cookie(
$cookie->name,
@@ -228,21 +206,15 @@ public function processResponse($event)
);
$this->getCookieJar()->set($c);
}
- $cookies->removeAll();
}
/**
* Replace mailer with in memory mailer
- * @param $config
- * @param $app
+ * @param array $config Original configuration
+ * @return array New configuration
*/
- protected function mockMailer($config)
+ protected function mockMailer(array $config)
{
- if (static::$mailer) {
- $this->app->set('mailer', static::$mailer);
- return;
- }
-
// options that make sense for mailer mock
$allowedOptions = [
'htmlLayout',
@@ -267,21 +239,24 @@ protected function mockMailer($config)
}
}
}
+ $config['components']['mailer'] = $mailerConfig;
- $this->app->set('mailer', $mailerConfig);
- static::$mailer = $this->app->get('mailer');
+ return $config;
}
/**
- * @param $app
+ * A new client is created for every test, it is destroyed after every test.
+ * @see InnerBrowser::_after()
+ *
*/
- protected function persistDb()
+ public function __destruct()
{
- // always use the same DB connection
- if (static::$db) {
- $this->app->set('db', static::$db);
- } elseif ($this->app->has('db')) {
- static::$db = $this->app->get('db');
- }
+ $this->resetApplication();
+ }
+
+ public function restart()
+ {
+ parent::restart();
+ $this->resetApplication();
}
}
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index 76cfde3858..9d679ff896 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -8,14 +8,25 @@
use Codeception\Lib\Framework;
use Codeception\Lib\Interfaces\ActiveRecord;
use Codeception\Lib\Interfaces\PartedModule;
-use Codeception\Lib\Notification;
use Codeception\TestInterface;
+use Codeception\Util\Debug;
use Yii;
+use yii\base\Event;
use yii\db\ActiveRecordInterface;
+use yii\db\Connection;
+use yii\db\QueryInterface;
+use yii\db\Transaction;
/**
* This module provides integration with [Yii framework](http://www.yiiframework.com/) (2.0).
* It initializes Yii framework in test environment and provides actions for functional testing.
+ * ## Application state during testing
+ * This section details what you can expect when using this module.
+ * * You will get a fresh application in `\Yii::$app` at the start of each test (available in the test and in `_before()`).
+ * * When executing a request via one of the request functions the `request` and `response` component are both recreated.
+ * * After a request the whole application is available for inspection / interaction.
+ * * You may use multiple database connections, each will use a separate transaction; to prevent accidental mistakes we
+ * will warn you if you try to connect to the same database twice but we cannot reuse the same connection.
*
* ## Config
*
@@ -24,6 +35,8 @@
* * `entryScript` - front script title (like: index-test.php). If not set - taken from entryUrl.
* * `transaction` - (default: true) wrap all database connection inside a transaction and roll it back after the test. Should be disabled for acceptance testing..
* * `cleanup` - (default: true) cleanup fixtures after the test
+ * * `ignoreCollidingDSN` - (default: false) When 2 database connections use the same DSN but different settings an exception will be thrown, set this to true to disable this behavior.
+ * * `fixturesMethod` - (default: _fixtures) Name of the method used for creating fixtures.
*
* You can use this module by setting params in your functional.suite.yml:
*
@@ -122,67 +135,124 @@
* Maintainer: **samdark**
* Stability: **stable**
*
+ * @property \Codeception\Lib\Connector\Yii2 $client
*/
class Yii2 extends Framework implements ActiveRecord, PartedModule
{
- const TEST_FIXTURES_METHOD = '_fixtures';
-
/**
* Application config file must be set.
* @var array
*/
protected $config = [
+ 'fixturesMethod' => '_fixtures',
'cleanup' => true,
+ 'ignoreCollidingDSN' => false,
'transaction' => null,
'entryScript' => '',
'entryUrl' => 'http://localhost/index-test.php',
];
protected $requiredFields = ['configFile'];
- protected $transaction;
/**
- * @var \yii\base\Application
+ * @var array Array of Transaction objects indexed by a string key
+ */
+ private $transactions = [];
+ /**
+ * @var \PDO[] Array of PDO objects indexed by a string key
+ */
+ private $pdoCache = [];
+ /**
+ * @var string[] Array of cache keys indexes by their DSN
*/
- public $app;
+ private $dsnCache = [];
/**
* @var Yii2Connector\FixturesStore[]
*/
public $loadedFixtures = [];
+ /**
+ * @var array The contents of $_SERVER upon initialization of this object.
+ * This is only used to restore it upon object destruction.
+ * It MUST not be used anywhere else.
+ */
+ private $server;
public function _initialize()
{
if ($this->config['transaction'] === null) {
$this->config['transaction'] = $this->backupConfig['transaction'] = $this->config['cleanup'];
}
+ $this->defineConstants();
+ $this->server = $_SERVER;
+ $this->initServerGlobal();
+ }
+
+
+ /**
+ * Module configuration changed inside a test.
+ * We might need to re-create the application.
+ */
+ protected function onReconfigure()
+ {
+ parent::onReconfigure();
+ if (isset(\Yii::$app)) {
+ $this->client->restart();
+ }
+ }
+
+
+ /**
+ * Adds the required server params.
+ * Note this is done separately from the request cycle since someone might call
+ * `Url::to` before doing a request, which would instantiate the request component with incorrect server params.
+ */
+ private function initServerGlobal()
+ {
+
+ $entryUrl = $this->config['entryUrl'];
+ $entryFile = $this->config['entryScript'] ?: basename($entryUrl);
+ $entryScript = $this->config['entryScript'] ?: parse_url($entryUrl, PHP_URL_PATH);
+ $_SERVER = array_merge($_SERVER, [
+ 'SCRIPT_FILENAME' => $entryFile,
+ 'SCRIPT_NAME' => $entryScript,
+ 'SERVER_NAME' => parse_url($entryUrl, PHP_URL_HOST),
+ 'SERVER_PORT' => parse_url($entryUrl, PHP_URL_PORT) ?: '80',
+ 'HTTPS' => parse_url($entryUrl, PHP_URL_SCHEME) === 'https'
+ ]);
+ }
+
+ protected function validateConfig()
+ {
+ parent::validateConfig();
if (!is_file(Configuration::projectDir() . $this->config['configFile'])) {
throw new ModuleConfigException(
__CLASS__,
"The application config file does not exist: " . Configuration::projectDir() . $this->config['configFile']
);
}
- $this->defineConstants();
}
+
public function _before(TestInterface $test)
{
$entryUrl = $this->config['entryUrl'];
$entryFile = $this->config['entryScript'] ?: basename($entryUrl);
$entryScript = $this->config['entryScript'] ?: parse_url($entryUrl, PHP_URL_PATH);
- $this->client = new Yii2Connector();
- $this->client->defaultServerVars = [
+ $this->client = new Yii2Connector([
'SCRIPT_FILENAME' => $entryFile,
- 'SCRIPT_NAME' => $entryScript,
- 'SERVER_NAME' => parse_url($entryUrl, PHP_URL_HOST),
- 'SERVER_PORT' => parse_url($entryUrl, PHP_URL_PORT) ?: '80',
- ];
- $this->client->defaultServerVars['HTTPS'] = parse_url($entryUrl, PHP_URL_SCHEME) === 'https';
- $this->client->restoreServerVars();
+ 'SCRIPT_NAME' => $entryScript,
+ 'SERVER_NAME' => parse_url($entryUrl, PHP_URL_HOST),
+ 'SERVER_PORT' => parse_url($entryUrl, PHP_URL_PORT) ?: '80',
+ 'HTTPS' => parse_url($entryUrl, PHP_URL_SCHEME) === 'https'
+ ]);
+
$this->client->configFile = Configuration::projectDir() . $this->config['configFile'];
- $this->app = $this->client->getApplication();
+
+ $this->client->resetApplication();
+ $app = $this->client->getApplication();
// load fixtures before db transaction
if ($test instanceof \Codeception\Test\Cest) {
@@ -191,13 +261,7 @@ public function _before(TestInterface $test)
$this->loadFixtures($test);
}
- if ($this->config['transaction']
- && $this->app->has('db')
- && $this->app->db instanceof \yii\db\Connection
- ) {
- $this->transaction = $this->app->db->beginTransaction();
- $this->debugSection('Database', 'Transaction started');
- }
+ $this->startTransactions();
}
/**
@@ -207,11 +271,27 @@ public function _before(TestInterface $test)
*/
private function loadFixtures($test)
{
+ $this->debugSection('Fixtures', 'Loading fixtures');
+ /** @var Connection[] $connections */
+ $connections = [];
+ // Register event handler.
+ Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, function (Event $event) use (&$connections) {
+ $this->debugSection('Fixtures', 'Opened database connection: ' . $event->sender->dsn);
+ $connections[] = $event->sender;
+ });
if (empty($this->loadedFixtures)
- && method_exists($test, self::TEST_FIXTURES_METHOD)
+ && method_exists($test, $this->_getConfig('fixturesMethod'))
) {
- $this->haveFixtures(call_user_func([$test, self::TEST_FIXTURES_METHOD]));
+ $this->haveFixtures(call_user_func([$test, $this->_getConfig('fixturesMethod')]));
+ }
+
+ Event::offAll();
+ // Close all connections so they get properly reopened after the transaction handler has been attached.
+ foreach ($connections as $connection) {
+ $this->debugSection('Fixtures', 'Closing database connection: ' . $connection->dsn);
+ $connection->close();
}
+ $this->debugSection('Fixtures', 'Done');
}
public function _after(TestInterface $test)
@@ -223,10 +303,7 @@ public function _after(TestInterface $test)
$_COOKIE = [];
$_REQUEST = [];
- if ($this->config['transaction'] && $this->transaction) {
- $this->transaction->rollBack();
- $this->debugSection('Database', 'Transaction cancelled; all changes reverted.');
- }
+ $this->rollbackTransactions();
if ($this->config['cleanup']) {
foreach ($this->loadedFixtures as $fixture) {
@@ -235,20 +312,78 @@ public function _after(TestInterface $test)
$this->loadedFixtures = [];
}
- if ($this->client) {
- $this->client->resetPersistentVars();
+ if ($this->client->getApplication()->has('session', true)) {
+ $this->client->getApplication()->session->close();
}
- if (isset(\Yii::$app) && \Yii::$app->has('session', true)) {
- \Yii::$app->session->close();
- }
+ parent::_after($test);
+ }
- // Close connections if exists
- if (isset(\Yii::$app) && \Yii::$app->has('db', true)) {
- \Yii::$app->db->close();
+ protected function startTransactions()
+ {
+ if ($this->config['transaction']) {
+ // This should register handlers that start a transaction whenever a connection opens and add it to the transactions array.
+ Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, function (Event $event) {
+ if ($event->sender instanceof Connection) {
+ $connection = $event->sender;
+ /*
+ * We should check if the known PDO objects are the same, in which case we should reuse the PDO
+ * object so only 1 transaction is started and multiple connections to the same database see the
+ * same data (due to writes inside a transaction not being visible from the outside).
+ *
+ */
+ $key = md5(json_encode([
+ 'dsn' => $connection->dsn,
+ 'user' => $connection->username,
+ 'pass' => $connection->password,
+ 'attributes' => $connection->attributes,
+ 'emulatePrepare' => $connection->emulatePrepare,
+ 'charset' => $connection->charset
+ ]));
+
+ /*
+ * If keys match we assume connections are "similar enough".
+ */
+ if (isset($this->pdoCache[$key])) {
+ $connection->pdo = $this->pdoCache[$key];
+ }
+
+ if (isset($this->dsnCache[$connection->dsn])
+ && $this->dsnCache[$connection->dsn] !== $key
+ && !$this->config['ignoreCollidingDSN']
+ ) {
+ $this->debugSection('WARNING', <<dsn}) with different configuration.
+These connections will not see the same database state since we cannot share a transaction between different PDO
+instances.
+You can remove this message by adding 'ignoreCollidingDSN = true' in the module configuration.
+TEXT
+ );
+ Debug::pause();
+ }
+
+ if (isset($this->transactions[$key])) {
+ $this->debugSection('Database', 'Reusing PDO, so no need for a new transaction');
+ return;
+ }
+
+ $this->debugSection('Database', 'Transaction started for: ' . $connection->dsn);
+ $this->transactions[$key] = $connection->beginTransaction();
+ }
+ });
}
+ }
- parent::_after($test);
+ protected function rollbackTransactions()
+ {
+ /** @var Transaction $transaction */
+ foreach ($this->transactions as $transaction) {
+ $transaction->rollBack();
+ $this->debugSection('Database', 'Transaction cancelled; all changes reverted.');
+ }
+ $this->transactions = [];
+ $this->pdoCache = [];
+ $this->dsnCache = [];
}
public function _parts()
@@ -276,17 +411,17 @@ public function _parts()
*/
public function amLoggedInAs($user)
{
- if (!Yii::$app->has('user')) {
+ if (!$this->client->getApplication()->has('user')) {
throw new ModuleException($this, 'User component is not loaded');
}
if ($user instanceof \yii\web\IdentityInterface) {
$identity = $user;
} else {
// class name implementing IdentityInterface
- $identityClass = Yii::$app->user->identityClass;
+ $identityClass = $this->client->getApplication()->user->identityClass;
$identity = call_user_func([$identityClass, 'findIdentity'], $user);
}
- Yii::$app->user->login($identity);
+ $this->client->getApplication()->user->login($identity);
}
/**
@@ -407,7 +542,7 @@ public function grabFixture($name, $index = null)
public function haveRecord($model, $attributes = [])
{
/** @var $record \yii\db\ActiveRecord * */
- $record = $this->getModelRecord($model);
+ $record = \Yii::createObject($model);
$record->setAttributes($attributes, false);
$res = $record->save(false);
if (!$res) {
@@ -473,24 +608,32 @@ public function grabRecord($model, $attributes = [])
return $this->findRecord($model, $attributes);
}
+ /**
+ * @param string $model Class name
+ * @param array $attributes
+ * @return mixed
+ */
protected function findRecord($model, $attributes = [])
- {
- $this->getModelRecord($model);
- return call_user_func([$model, 'find'])
- ->andWhere($attributes)
- ->one();
- }
-
- protected function getModelRecord($model)
{
if (!class_exists($model)) {
- throw new \RuntimeException("Model $model does not exist");
+ throw new \RuntimeException("Class $model does not exist");
}
- $record = Yii::createObject($model);
- if (!$record instanceof ActiveRecordInterface) {
- throw new \RuntimeException("Model $model is not implement interface \\yii\\db\\ActiveRecordInterface");
+ $rc = new \ReflectionClass($model);
+ if ($rc->hasMethod('find')
+ && ($findMethod = $rc->getMethod('find'))
+ && $findMethod->isStatic()
+ && $findMethod->isPublic()
+ && $findMethod->getNumberOfRequiredParameters() === 0
+ ) {
+ $activeQuery = $findMethod->invoke(null);
+ if ($activeQuery instanceof QueryInterface) {
+ return $activeQuery->andWhere($attributes)->one();
+ }
+
+ throw new \RuntimeException("$model::find() must return an instance of yii\db\QueryInterface");
+
}
- return $record;
+ throw new \RuntimeException("Class $model does not have a public static find() method without required parameters");
}
/**
@@ -522,7 +665,7 @@ public function amOnRoute($route, array $params = [])
protected function clientRequest($method, $uri, array $parameters = [], array $files = [], array $server = [], $content = null, $changeHistory = true)
{
if (is_array($uri)) {
- $uri = Yii::$app->getUrlManager()->createUrl($uri);
+ $uri = $this->client->getApplication()->getUrlManager()->createUrl($uri);
}
return parent::clientRequest($method, $uri, $parameters, $files, $server, $content, $changeHistory);
}
@@ -541,10 +684,10 @@ protected function clientRequest($method, $uri, array $parameters = [], array $f
*/
public function grabComponent($component)
{
- if (!Yii::$app->has($component)) {
+ if (!$this->client->getApplication()->has($component)) {
throw new ModuleException($this, "Component $component is not available in current application");
}
- return Yii::$app->get($component);
+ return $this->client->getApplication()->get($component);
}
/**
@@ -660,10 +803,10 @@ function ($matches) use (&$parameters) {
*/
public function getInternalDomains()
{
- $domains = [$this->getDomainRegex(Yii::$app->urlManager->hostInfo)];
+ $domains = [$this->getDomainRegex($this->client->getApplication()->urlManager->hostInfo)];
- if (Yii::$app->urlManager->enablePrettyUrl) {
- foreach (Yii::$app->urlManager->rules as $rule) {
+ if ($this->client->getApplication()->urlManager->enablePrettyUrl) {
+ foreach ($this->client->getApplication()->urlManager->rules as $rule) {
/** @var \yii\web\UrlRule $rule */
if (isset($rule->host)) {
$domains[] = $this->getDomainRegex($rule->host);
@@ -689,8 +832,8 @@ private function defineConstants()
public function setCookie($name, $val, array $params = [])
{
// Sign the cookie.
- if ($this->app->request->enableCookieValidation) {
- $val = $this->app->security->hashData(serialize([$name, $val]), $this->app->request->cookieValidationKey);
+ if ($this->client->getApplication()->request->enableCookieValidation) {
+ $val = $this->client->getApplication()->security->hashData(serialize([$name, $val]), $this->client->getApplication()->request->cookieValidationKey);
}
parent::setCookie($name, $val, $params);
}
@@ -702,9 +845,18 @@ public function setCookie($name, $val, array $params = [])
*/
public function createAndSetCsrfCookie($val)
{
- $masked = $this->app->security->maskToken($val);
- $name = $this->app->request->csrfParam;
+ $masked = $this->client->getApplication()->security->maskToken($val);
+ $name = $this->client->getApplication()->request->csrfParam;
$this->setCookie($name, $val);
return [$name, $masked];
}
+
+ public function _afterSuite()
+ {
+ parent::_afterSuite();
+ codecept_debug('Suite done, restoring $_SERVER to original');
+
+ $_SERVER = $this->server;
+ }
+
}
From 59afc7c9c0dd1a653ab20842894528356426bca9 Mon Sep 17 00:00:00 2001
From: Michael Bodnarchuk
Date: Sun, 1 Apr 2018 01:30:08 +0300
Subject: [PATCH 024/395] Prepare 241 (#4904)
* updates to composer
* updated changelog
* fixed installing pecl modules
* * Added documentation for `callArtisan`
* Fixed warning tests for PHPUnit 5.6
* fixed travis builds
* fixed WebDriver tests
---
.travis.yml | 3 +-
CHANGELOG-2.4.md | 26 ++++++++---
RoboFile.php | 17 +-------
composer.json | 2 +-
src/Codeception/Module/Laravel5.php | 9 ++--
src/Codeception/Module/WebDriver.php | 64 +++++++++++++++++-----------
tests/cli/RunCest.php | 2 +-
tests/data/app/db | 2 +-
tests/web.suite.yml | 3 +-
tests/web/WebDriverTest.php | 10 ++---
10 files changed, 77 insertions(+), 61 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index ebf56b4572..febacbc628 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -78,7 +78,7 @@ before_install:
install:
- '[[ -z "$CI_USER_TOKEN" ]] || composer config github-oauth.github.com ${CI_USER_TOKEN};'
# Add extensions
- - '[[ -z "$PECL" ]] || (yes "" | pecl install $PECL)'
+ - '[[ -z "$PECL" ]] || (yes "" | pecl install -f $PECL)'
# Clone test repository
- '[[ "$FRAMEWORK" == "Codeception" ]] || git clone -q --depth=1 $TEST_REPO framework-tests'
- '[[ "$FRAMEWORK" == "Codeception" ]] || git --git-dir framework-tests/.git log -n 1'
@@ -128,5 +128,4 @@ before_script:
# Build
- php codecept build -c $TEST_PATH
script:
- #- '[[ !("$FRAMEWORK" == "Codeception" && "$TRAVIS_PHP_VERSION" == "7.1") ]] || php codecept run coverage' # run coverage tests on php only
- php codecept run $SUITES -c $TEST_PATH
\ No newline at end of file
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 70b806a390..0b17e0faab 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -1,3 +1,22 @@
+#### 2.4.1
+
+* Fixed `PHP Fatal error: Uncaught Error: Call to undefined method Codeception\Test\Descriptor::getTestDataSetIndex()` when filtering tests
+* Better support of PHPUnit warning status by @edno:
+ * support PHPUnit addWarning()
+ * display 'W' instead of success for warning test cases
+* Fixed Running test with invalid dataprovider by @okneloper. Fixed #4888 by @edno
+* [Yii2] **Request flow and database transactions refactored** (by @sammousa):
+ * **Breaking** Application is no longer available in helpers via `$this->getModule('Yii2'')->app`, now you must use `\Yii::$app` everywhere
+ * Multiple databases are now supported
+ * More reliable application state before and during test execution
+ * Fixtures method is now configurable
+ * Subset of misconfigurations are now detected and informative messages created
+* Fixed using `$settings['path']` in `Codeception\Configuration::suiteSettings()` on Windows by @olegpro
+* [Laravel5] Added Laravel 5.4+ (5.1+ backward compatible) support for `callArtisan` method in Laravel5 module. See #4860 by @mohamed-aiman
+* Fixed #4854: unnecessary escaping in operation arguments logging by @nicholascus
+* Fixed humanizing steps for utf8 strings by @nicholascus. See #4850
+* Fixed parsing relative urls in `parse_url`. See #4853 by @quantum-x
+
#### 2.4.0
* **PHPUnit 7.x compatibility**
@@ -10,12 +29,7 @@
* `_failed` called when test fails
* `_passed` called when tests is successful
* `_after` is called for failing and successful tests
-* Yii2 Module request flow and database transactions refactored (by @sammousa):
- * Multiple databases are now supported
- * More reliable application state before and during test execution
- * Fixtures method is now configurable
- * Subset of misconfigurations are now detected and create informative messages
- * Application is no longer available via the `$module->app`, now you must use `\Yii::$app` everywhere
+
**Upgrade Notice**: If you face issues with underscore PHPUnit class names (like PHPUnit_Framework_Assert) you have two options:
* Lock version for PHPUnit in composer.json: "phpunit/phpunit":"^5.0.0"
diff --git a/RoboFile.php b/RoboFile.php
index e06510c685..8e8e913a62 100644
--- a/RoboFile.php
+++ b/RoboFile.php
@@ -96,11 +96,6 @@ public function testCoverage()
public function testWebdriver($args = '', $opt = ['test|t' => null])
{
$test = $opt['test'] ? ':'.$opt['test'] : '';
- $container = $this->taskDockerRun('davert/selenium-env')
- ->detached()
- ->publish(4444, 4444)
- ->env('APP_PORT', 8000)
- ->run();
$this->taskServer(8000)
->dir('tests/data/app')
@@ -108,22 +103,14 @@ public function testWebdriver($args = '', $opt = ['test|t' => null])
->host('0.0.0.0')
->run();
- sleep(3); // wait for selenium to launch
-
$this->taskCodecept('./codecept')
- ->test('tests/web/WebDriverTest.php'.$test)
+ ->suite('web')
->args($args)
->run();
-
- $this->taskDockerStop($container)->run();
}
- public function testLaunchServer($pathToSelenium = '~/selenium-server.jar ')
+ public function testLaunchServer()
{
- $this->taskExec('java -jar '.$pathToSelenium)
- ->background()
- ->run();
-
$this->taskServer(8010)
->background()
->dir('tests/data/rest')
diff --git a/composer.json b/composer.json
index 80fda783a2..d707d4e5e8 100644
--- a/composer.json
+++ b/composer.json
@@ -29,7 +29,7 @@
"symfony/css-selector": ">=2.7 <5.0",
"symfony/dom-crawler": ">=2.7 <5.0",
"behat/gherkin": "^4.4.0",
- "codeception/phpunit-wrapper": "^6.0|^7.0",
+ "codeception/phpunit-wrapper": "^6.0.9|^7.0.6",
"codeception/stub": "^1.0"
},
"require-dev": {
diff --git a/src/Codeception/Module/Laravel5.php b/src/Codeception/Module/Laravel5.php
index 2c537b3681..e97f536b95 100644
--- a/src/Codeception/Module/Laravel5.php
+++ b/src/Codeception/Module/Laravel5.php
@@ -419,19 +419,22 @@ public function dontSeeEventTriggered($events)
* callArtisan('command:name');
* $I->callArtisan('command:name', ['parameter' => 'value']);
- * ?>
* ```
-
+ * Use 3rd parameter to pass in custom `OutputInterface`
+ *
* @param string $command
* @param array $parameters
* @param OutputInterface $output
+ * @return string
*/
public function callArtisan($command, $parameters = [], OutputInterface $output = null)
{
$console = $this->app->make('Illuminate\Contracts\Console\Kernel');
if (!$output) {
$console->call($command, $parameters);
- return trim($console->output());
+ $output = trim($console->output());
+ $this->debug($output);
+ return $output;
}
$console->call($command, $parameters, $output);
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index 942eaae15d..1b575f03f6 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -341,6 +341,18 @@ public function _requires()
return ['Facebook\WebDriver\Remote\RemoteWebDriver' => '"facebook/webdriver": "^1.0.1"'];
}
+ /**
+ * @return RemoteWebElement
+ * @throws ModuleException
+ */
+ protected function getBaseElement()
+ {
+ if (!$this->baseElement) {
+ throw new ModuleException($this, "Page not loaded. Use `\$I->amOnPage` (or hidden API methods `_request` and `_loadPage`) to open it");
+ }
+ return $this->baseElement;
+ }
+
public function _initialize()
{
$this->wdHost = sprintf('%s://%s:%s%s', $this->config['protocol'], $this->config['host'], $this->config['port'], $this->config['path']);
@@ -682,7 +694,7 @@ protected function getProxy()
public function _getCurrentUri()
{
$url = $this->webDriver->getCurrentURL();
- if ($url == 'about:blank') {
+ if ($url == 'about:blank' || strpos($url, 'data:') === 0) {
throw new ModuleException($this, 'Current url is blank, no page was opened');
}
return Uri::retrieveUri($url);
@@ -1087,7 +1099,7 @@ protected function findField($selector)
public function seeLink($text, $url = null)
{
$this->enableImplicitWait();
- $nodes = $this->baseElement->findElements(WebDriverBy::partialLinkText($text));
+ $nodes = $this->getBaseElement()->findElements(WebDriverBy::partialLinkText($text));
$this->disableImplicitWait();
$currentUri = $this->_getCurrentUri();
@@ -1102,7 +1114,7 @@ public function seeLink($text, $url = null)
public function dontSeeLink($text, $url = null)
{
- $nodes = $this->baseElement->findElements(WebDriverBy::partialLinkText($text));
+ $nodes = $this->getBaseElement()->findElements(WebDriverBy::partialLinkText($text));
$currentUri = $this->_getCurrentUri();
if (!$url) {
$this->assertEmpty($nodes, "Link containing text '$text' was found in page $currentUri");
@@ -1213,7 +1225,7 @@ public function dontSeeInFormFields($formSelector, array $params)
protected function proceedSeeInFormFields($formSelector, array $params, $assertNot)
{
- $form = $this->match($this->baseElement, $formSelector);
+ $form = $this->match($this->getBaseElement(), $formSelector);
if (empty($form)) {
throw new ElementNotFound($formSelector, "Form via CSS or XPath");
}
@@ -1540,7 +1552,7 @@ protected function findCheckable($context, $radioOrCheckbox, $byValue = false)
}
if (is_array($radioOrCheckbox) or ($radioOrCheckbox instanceof WebDriverBy)) {
- return $this->matchFirstOrFail($this->baseElement, $radioOrCheckbox);
+ return $this->matchFirstOrFail($this->getBaseElement(), $radioOrCheckbox);
}
$locator = Crawler::xpathLiteral($radioOrCheckbox);
@@ -1610,7 +1622,7 @@ public function checkOption($option)
public function uncheckOption($option)
{
- $field = $this->findCheckable($this->baseElement, $option);
+ $field = $this->findCheckable($this->getBaseElement(), $option);
if (!$field) {
throw new ElementNotFound($option, "Checkbox by Label or CSS or XPath");
}
@@ -1671,10 +1683,10 @@ public function attachFile($field, $filename)
*/
protected function getVisibleText()
{
- if ($this->baseElement instanceof RemoteWebElement) {
- return $this->baseElement->getText();
+ if ($this->getBaseElement() instanceof RemoteWebElement) {
+ return $this->getBaseElement()->getText();
}
- $els = $this->baseElement->findElements(WebDriverBy::cssSelector('body'));
+ $els = $this->getBaseElement()->findElements(WebDriverBy::cssSelector('body'));
if (isset($els[0])) {
return $els[0]->getText();
}
@@ -1683,7 +1695,7 @@ protected function getVisibleText()
public function grabTextFrom($cssOrXPathOrRegex)
{
- $els = $this->match($this->baseElement, $cssOrXPathOrRegex, false);
+ $els = $this->match($this->getBaseElement(), $cssOrXPathOrRegex, false);
if (count($els)) {
return $els[0]->getText();
}
@@ -1695,7 +1707,7 @@ public function grabTextFrom($cssOrXPathOrRegex)
public function grabAttributeFrom($cssOrXpath, $attribute)
{
- $el = $this->matchFirstOrFail($this->baseElement, $cssOrXpath);
+ $el = $this->matchFirstOrFail($this->getBaseElement(), $cssOrXpath);
return $el->getAttribute($attribute);
}
@@ -1712,7 +1724,7 @@ public function grabValueFrom($field)
public function grabMultiple($cssOrXpath, $attribute = null)
{
- $els = $this->match($this->baseElement, $cssOrXpath);
+ $els = $this->match($this->getBaseElement(), $cssOrXpath);
return array_map(
function (WebDriverElement $e) use ($attribute) {
if ($attribute) {
@@ -1769,7 +1781,7 @@ public function dontSeeElement($selector, $attributes = [])
public function seeElementInDOM($selector, $attributes = [])
{
$this->enableImplicitWait();
- $els = $this->match($this->baseElement, $selector);
+ $els = $this->match($this->getBaseElement(), $selector);
$els = $this->filterByAttributes($els, $attributes);
$this->disableImplicitWait();
$this->assertNotEmpty($els);
@@ -1784,7 +1796,7 @@ public function seeElementInDOM($selector, $attributes = [])
*/
public function dontSeeElementInDOM($selector, $attributes = [])
{
- $els = $this->match($this->baseElement, $selector);
+ $els = $this->match($this->getBaseElement(), $selector);
$els = $this->filterByAttributes($els, $attributes);
$this->assertEmpty($els);
}
@@ -1809,7 +1821,7 @@ public function seeNumberOfElements($selector, $expected)
public function seeNumberOfElementsInDOM($selector, $expected)
{
- $counted = count($this->match($this->baseElement, $selector));
+ $counted = count($this->match($this->getBaseElement(), $selector));
if (is_array($expected)) {
list($floor, $ceil) = $expected;
$this->assertTrue(
@@ -2157,7 +2169,7 @@ protected function getSubmissionFormFieldName($name)
*/
public function submitForm($selector, array $params, $button = null)
{
- $form = $this->matchFirstOrFail($this->baseElement, $selector);
+ $form = $this->matchFirstOrFail($this->getBaseElement(), $selector);
$fields = $form->findElements(
WebDriverBy::cssSelector('input:enabled,textarea:enabled,select:enabled,input[type=hidden]')
@@ -2255,7 +2267,7 @@ public function submitForm($selector, array $params, $button = null)
*/
public function waitForElementChange($element, \Closure $callback, $timeout = 30)
{
- $el = $this->matchFirstOrFail($this->baseElement, $element);
+ $el = $this->matchFirstOrFail($this->getBaseElement(), $element);
$checker = function () use ($el, $callback) {
return $callback($el);
};
@@ -2565,8 +2577,8 @@ public function maximizeWindow()
*/
public function dragAndDrop($source, $target)
{
- $snodes = $this->matchFirstOrFail($this->baseElement, $source);
- $tnodes = $this->matchFirstOrFail($this->baseElement, $target);
+ $snodes = $this->matchFirstOrFail($this->getBaseElement(), $source);
+ $tnodes = $this->matchFirstOrFail($this->getBaseElement(), $target);
$action = new WebDriverActions($this->webDriver);
$action->dragAndDrop($snodes, $tnodes)->perform();
@@ -2597,7 +2609,7 @@ public function moveMouseOver($cssOrXPath = null, $offsetX = null, $offsetY = nu
{
$where = null;
if (null !== $cssOrXPath) {
- $el = $this->matchFirstOrFail($this->baseElement, $cssOrXPath);
+ $el = $this->matchFirstOrFail($this->getBaseElement(), $cssOrXPath);
$where = $el->getCoordinates();
}
@@ -2678,7 +2690,7 @@ public function pauseExecution()
*/
public function doubleClick($cssOrXPath)
{
- $el = $this->matchFirstOrFail($this->baseElement, $cssOrXPath);
+ $el = $this->matchFirstOrFail($this->getBaseElement(), $cssOrXPath);
$this->webDriver->getMouse()->doubleClick($el->getCoordinates());
}
@@ -2819,7 +2831,7 @@ protected function matchFirstOrFail($page, $selector)
*/
public function pressKey($element, $char)
{
- $el = $this->matchFirstOrFail($this->baseElement, $element);
+ $el = $this->matchFirstOrFail($this->getBaseElement(), $element);
$args = func_get_args();
array_shift($args);
$keys = [];
@@ -2954,7 +2966,7 @@ public function appendField($field, $value)
if ($type == 'checkbox') {
//Find by value or css,id,xpath
- $field = $this->findCheckable($this->baseElement, $value, true);
+ $field = $this->findCheckable($this->getBaseElement(), $value, true);
if (!$field) {
throw new ElementNotFound($value, "Checkbox or Radio by Label or CSS or XPath");
}
@@ -2981,7 +2993,7 @@ public function appendField($field, $value)
*/
protected function matchVisible($selector)
{
- $els = $this->match($this->baseElement, $selector);
+ $els = $this->match($this->getBaseElement(), $selector);
$nodes = array_filter(
$els,
function (WebDriverElement $el) {
@@ -3096,7 +3108,7 @@ protected function isPhantom()
*/
public function scrollTo($selector, $offsetX = null, $offsetY = null)
{
- $el = $this->matchFirstOrFail($this->baseElement, $selector);
+ $el = $this->matchFirstOrFail($this->getBaseElement(), $selector);
$x = $el->getLocation()->getX() + $offsetX;
$y = $el->getLocation()->getY() + $offsetY;
$this->webDriver->executeScript("window.scrollTo($x, $y)");
@@ -3239,7 +3251,7 @@ public function performOn($element, $actions, $timeout = 10)
{
$this->waitForElement($element, $timeout);
$this->setBaseElement($element);
- $this->debugSection('InnerText', $this->baseElement->getText());
+ $this->debugSection('InnerText', $this->getBaseElement()->getText());
if (is_callable($actions)) {
$actions($this);
diff --git a/tests/cli/RunCest.php b/tests/cli/RunCest.php
index 51e5ef6e9d..1e01d040dc 100644
--- a/tests/cli/RunCest.php
+++ b/tests/cli/RunCest.php
@@ -487,7 +487,7 @@ public function runCestWithTwoFailedTest(CliGuy $I)
public function runWarningTests(CliGuy $I)
{
- $I->executeCommand('run unit WarningTest.php:testWarningInvalidDataProvider', false);
+ $I->executeCommand('run unit WarningTest.php', false);
$I->seeInShellOutput('There was 1 warning');
$I->seeInShellOutput('WarningTest::testWarningInvalidDataProvider');
$I->seeInShellOutput('Tests: 1,');
diff --git a/tests/data/app/db b/tests/data/app/db
index 609cdc8eb1..c856afcf97 100644
--- a/tests/data/app/db
+++ b/tests/data/app/db
@@ -1 +1 @@
-a:1:{s:6:"params";a:0:{}}
\ No newline at end of file
+a:0:{}
\ No newline at end of file
diff --git a/tests/web.suite.yml b/tests/web.suite.yml
index fb9e581807..4a9b562556 100644
--- a/tests/web.suite.yml
+++ b/tests/web.suite.yml
@@ -4,7 +4,7 @@ modules:
config:
WebDriver:
url: http://localhost:8000
- browser: firefox
+ browser: chrome
window_size: 1200x768
restart: true # Use a new browser window for each test (to isolate test cases from each other)
env:
@@ -30,6 +30,7 @@ env:
WebDriver:
browser: chrome
window_size: false
+ restart: false
capabilities:
chromeOptions:
args: ["--headless", "--disable-gpu", "--disable-extensions"]
diff --git a/tests/web/WebDriverTest.php b/tests/web/WebDriverTest.php
index 4d07285015..26ac63e4ae 100644
--- a/tests/web/WebDriverTest.php
+++ b/tests/web/WebDriverTest.php
@@ -92,7 +92,7 @@ public function testFailedSeeInPopup()
{
$this->notForPhantomJS();
$this->setExpectedException(
- 'PHPUnit_Framework_AssertionFailedError',
+ '\PHPUnit\Framework\AssertionFailedError',
'Failed asserting that \'Really?\' contains "Different text"'
);
$this->module->amOnPage('/form/popup');
@@ -114,7 +114,7 @@ public function testFailedDontSeeInPopup()
{
$this->notForPhantomJS();
$this->setExpectedException(
- 'PHPUnit_Framework_AssertionFailedError',
+ '\PHPUnit\Framework\AssertionFailedError',
'Failed asserting that \'Really?\' does not contain "Really?"'
);
$this->module->amOnPage('/form/popup');
@@ -508,7 +508,7 @@ public function testCreateCeptScreenshotFail()
]);
$module = Stub::make(self::MODULE_CLASS, ['webDriver' => $fakeWd]);
$cept = (new \Codeception\Test\Cept('loginCept', 'loginCept.php'));
- $module->_failed($cept, new PHPUnit_Framework_AssertionFailedError());
+ $module->_failed($cept, new \PHPUnit\Framework\AssertionFailedError());
}
public function testCreateCestScreenshotOnFail()
@@ -527,7 +527,7 @@ public function testCreateCestScreenshotOnFail()
]);
$module = Stub::make(self::MODULE_CLASS, ['webDriver' => $fakeWd]);
$cest = new \Codeception\Test\Cest(new stdClass(), 'login', 'someCest.php');
- $module->_failed($cest, new PHPUnit_Framework_AssertionFailedError());
+ $module->_failed($cest, new \PHPUnit\Framework\AssertionFailedError());
}
public function testCreateTestScreenshotOnFail()
@@ -549,7 +549,7 @@ public function testCreateTestScreenshotOnFail()
]),
]);
$module = Stub::make(self::MODULE_CLASS, ['webDriver' => $fakeWd]);
- $module->_failed($test, new PHPUnit_Framework_AssertionFailedError());
+ $module->_failed($test, new \PHPUnit\Framework\AssertionFailedError());
}
public function testWebDriverWaits()
From bca3547632556875f1cdd567d6057cc14fe472b8 Mon Sep 17 00:00:00 2001
From: Davert
Date: Sun, 1 Apr 2018 01:30:43 +0300
Subject: [PATCH 025/395] documentation updated
---
docs/modules/Laravel5.md | 4 +++-
docs/modules/Yii2.md | 12 +++++++++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/docs/modules/Laravel5.md b/docs/modules/Laravel5.md
index 3275146e2c..b30b0b2907 100644
--- a/docs/modules/Laravel5.md
+++ b/docs/modules/Laravel5.md
@@ -298,11 +298,13 @@ Call an Artisan command.
callArtisan('command:name');
$I->callArtisan('command:name', ['parameter' => 'value']);
-?>
```
+Use 3rd parameter to pass in custom `OutputInterface`
* `param string` $command
* `param array` $parameters
+ * `param OutputInterface` $output
+ * `return` string
### checkOption
diff --git a/docs/modules/Yii2.md b/docs/modules/Yii2.md
index ab0e376330..e95817f354 100644
--- a/docs/modules/Yii2.md
+++ b/docs/modules/Yii2.md
@@ -3,6 +3,13 @@
This module provides integration with [Yii framework](http://www.yiiframework.com/) (2.0).
It initializes Yii framework in test environment and provides actions for functional testing.
+## Application state during testing
+This section details what you can expect when using this module.
+* You will get a fresh application in `\Yii::$app` at the start of each test (available in the test and in `_before()`).
+* When executing a request via one of the request functions the `request` and `response` component are both recreated.
+* After a request the whole application is available for inspection / interaction.
+* You may use multiple database connections, each will use a separate transaction; to prevent accidental mistakes we
+will warn you if you try to connect to the same database twice but we cannot reuse the same connection.
## Config
@@ -11,6 +18,8 @@ It initializes Yii framework in test environment and provides actions for functi
* `entryScript` - front script title (like: index-test.php). If not set - taken from entryUrl.
* `transaction` - (default: true) wrap all database connection inside a transaction and roll it back after the test. Should be disabled for acceptance testing..
* `cleanup` - (default: true) cleanup fixtures after the test
+* `ignoreCollidingDSN` - (default: false) When 2 database connections use the same DSN but different settings an exception will be thrown, set this to true to disable this behavior.
+* `fixturesMethod` - (default: _fixtures) Name of the method used for creating fixtures.
You can use this module by setting params in your functional.suite.yml:
@@ -101,7 +110,7 @@ This commands allows input like:
$I->amOnPage(['site/view','page'=>'about']);
$I->amOnPage('index-test.php?site/index');
$I->amOnPage('http://localhost/index-test.php?site/index');
-$I->sendAjaxPostRequest(['/user/update', 'id' => 1], ['UserForm[name]' => 'G.Hopper']);
+$I->sendAjaxPostRequest(['/user/update', 'id' => 1], ['UserForm[name]' => 'G.Hopper');
```
## Status
@@ -109,6 +118,7 @@ $I->sendAjaxPostRequest(['/user/update', 'id' => 1], ['UserForm[name]' => 'G.Hop
Maintainer: **samdark**
Stability: **stable**
+@property \Codeception\Lib\Connector\Yii2 $client
## Actions
From 853683f3a802166d0786670a80340f9775377da0 Mon Sep 17 00:00:00 2001
From: Davert
Date: Sun, 1 Apr 2018 01:42:13 +0300
Subject: [PATCH 026/395] version bump, fixed changelog formatting
---
CHANGELOG-2.4.md | 2 +-
src/Codeception/Codecept.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 0b17e0faab..4a6bec80a9 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -1,6 +1,6 @@
#### 2.4.1
-* Fixed `PHP Fatal error: Uncaught Error: Call to undefined method Codeception\Test\Descriptor::getTestDataSetIndex()` when filtering tests
+* Fixed "Uncaught Error: Call to undefined method Codeception\Test\Descriptor::getTestDataSetIndex()" error when filtering tests.
* Better support of PHPUnit warning status by @edno:
* support PHPUnit addWarning()
* display 'W' instead of success for warning test cases
diff --git a/src/Codeception/Codecept.php b/src/Codeception/Codecept.php
index 8e1626d6bf..c144ddb1de 100644
--- a/src/Codeception/Codecept.php
+++ b/src/Codeception/Codecept.php
@@ -7,7 +7,7 @@
class Codecept
{
- const VERSION = "2.4.1";
+ const VERSION = "2.4.2";
/**
* @var \Codeception\PHPUnit\Runner
From 543839658a2ffd360ec10efc873f5d615b313116 Mon Sep 17 00:00:00 2001
From: Davert
Date: Sun, 1 Apr 2018 02:23:08 +0300
Subject: [PATCH 027/395] updated docs, removed mentions of Cept format
---
docs/01-Introduction.md | 4 +-
docs/02-GettingStarted.md | 134 ++++++++++++++-----------------
docs/03-AcceptanceTests.md | 19 +++--
docs/05-UnitTests.md | 14 ++--
docs/06-ReusingTestCode.md | 7 +-
docs/07-AdvancedUsage.md | 24 +++---
docs/07-BDD.md | 2 +-
docs/08-Customization.md | 10 +--
docs/10-WebServices.md | 57 ++++++-------
docs/12-ContinuousIntegration.md | 10 +--
10 files changed, 137 insertions(+), 144 deletions(-)
diff --git a/docs/01-Introduction.md b/docs/01-Introduction.md
index ff97b24663..5d365b7d5f 100644
--- a/docs/01-Introduction.md
+++ b/docs/01-Introduction.md
@@ -48,7 +48,6 @@ With acceptance tests, you can be confident that users, following all the define
```php
amOnPage('/');
$I->click('Sign Up');
$I->submitForm('#signup', ['username' => 'MilesDavis', 'email' => 'miles@davis.com']);
@@ -72,7 +71,6 @@ Codeception provides connectors to several popular PHP frameworks. You can also
```php
amOnPage('/');
$I->click('Sign Up');
$I->submitForm('#signup', ['username' => 'MilesDavis', 'email' => 'miles@davis.com']);
@@ -106,7 +104,7 @@ function testSavingUser()
$user->setSurname('Davis');
$user->save();
$this->assertEquals('Miles Davis', $user->getFullName());
- $this->unitTester->seeInDatabase('users', ['name' => 'Miles', 'surname' => 'Davis']);
+ $this->tester->seeInDatabase('users', ['name' => 'Miles', 'surname' => 'Davis']);
}
```
diff --git a/docs/02-GettingStarted.md b/docs/02-GettingStarted.md
index 058b13193c..bc3fb3174e 100644
--- a/docs/02-GettingStarted.md
+++ b/docs/02-GettingStarted.md
@@ -59,66 +59,64 @@ When you change the configuration, the actor classes are rebuilt automatically.
try to generate them manually with the `build` command:
```bash
-php codecept build
+php vendor/bin/codecept build
```
-## Writing a Sample Scenario
+## Writing a Sample Test
-By default tests are written as narrative scenarios. To make a PHP file a valid scenario, its name should have a `Cept` suffix.
-
-Let's say we have created a file `tests/acceptance/SigninCept.php`
-
-We can do that by running the following command:
+Codeception has its own testing format called Cest (Codecept + Test).
+To start writing a test we need to create a new Cest file. We can do that by running the following command:
```bash
-php codecept generate:cept acceptance Signin
+php vendor/bin/codecept generate:cest acceptance Signin
```
-A scenario always starts with actor class initialization. After that, writing a scenario is just like typing `$I->`
-and choosing a proper action from the auto-completion list. Let's log in to our website:
+This will generate `SigninCest.php` file inside `tests/acceptance` directory. Let's open it:
```php
wantTo('login to website');
-
-```
-
-The `wantTo` section describes your scenario in brief. There are additional comment methods that are useful to describe the context of a scenario:
+class SigninCest
+{
+ function _before(AcceptanceTester $I)
+ {
+ }
+
+ public function _after(AcceptanceTester $I)
+ {
+ }
-```php
-am('user'); // actor's role
-$I->wantTo('login to website'); // feature to test
-$I->lookForwardTo('access website features for logged-in users'); // result to achieve
+ public function tryToTest(AcceptanceTester $I)
+ {
+ // todo: write test
+ }
+}
```
-After we have described the story background, let's start writing a scenario.
+We have `_before` and `_after` methods to run some common actions before and after a test. And we have a placeholder action `tryToTest` which we need to implement.
+If we try to test a signin process it's a good start to test a successful signin. Let's rename this method to `signInSuccessfully`.
-We'll assume that we have a 'login' page where we get authenticated by providing a username and password.
+We'll assume that we have a 'login' page where we get authenticated by providing a username and password.
Then we are sent to a user page, where we see the text `Hello, %username%`. Let's look at how this scenario is written in Codeception:
```php
am('user');
-$I->wantTo('login to website');
-$I->lookForwardTo('access website features for logged-in users');
-$I->amOnPage('/login');
-$I->fillField('Username','davert');
-$I->fillField('Password','qwerty');
-$I->click('Login');
-$I->see('Hello, davert');
+class SigninCest
+{
+ public function loginSuccessfully(AcceptanceTester $I)
+ {
+ $I->amOnPage('/login');
+ $I->fillField('Username','davert');
+ $I->fillField('Password','qwerty');
+ $I->click('Login');
+ $I->see('Hello, davert');
+ }
+}
```
This scenario can probably be read by non-technical people. If you just remove all special chars like braces, arrows and `$`,
this test transforms into plain English text:
```
-I am user
-I wantTo login to website
-I lookForwardTo access website features for logged-in users
I amOnPage '/login'
I fillField 'Username','davert'
I fillField 'Password','qwerty'
@@ -129,7 +127,7 @@ I see 'Hello, davert'
Codeception generates this text representation from PHP code by executing:
```bash
-php codecept generate:scenarios
+php vendor/bin/codecept generate:scenarios
```
These generated scenarios will be stored in your `_data` directory in text files.
@@ -149,14 +147,14 @@ modules:
After configuring the URL we can run this test with the `run` command:
```bash
-php codecept run
+php vendor/bin/codecept run
```
This is the output we should see:
```bash
Acceptance Tests (1) -------------------------------
-✔ SigninCept: Login to website
+✔ SigninCest: sign in successfully
----------------------------------------------------
Time: 1 second, Memory: 21.00Mb
@@ -167,19 +165,17 @@ OK (1 test, 1 assertions)
Let's get some detailed output:
```bash
-php codecept run acceptance --steps
+php vendor/bin/codecept run acceptance --steps
```
We should see a step-by-step report on the performed actions:
```bash
Acceptance Tests (1) -------------------------------
-SigninCept: Login to website
-Signature: SigninCept.php
-Test: tests/acceptance/SigninCept.php
+SigninCest: Login to website
+Signature: SigninCest.php:signInSuccessfully
+Test: tests/acceptance/SigninCest.php:signInSuccessfully
Scenario --
- I am user
- I look forward to access website features for logged-in users
I am on page "/login"
I fill field "Username" "davert"
I fill field "Password" "qwerty"
@@ -196,54 +192,43 @@ OK (1 test, 1 assertions)
This simple test can be extended to a complete scenario of site usage, therefore,
by emulating the user's actions, you can test any of your websites.
-Give it a try!
+To run more tests create a public method for each of them. Include `AcceptanceTester` object as `$I` as a method parameter and use the same `$I->` API you've seen before.
+If your tests share common setup actions put them into `_before` method.
-## Cept, Cest and Test Formats
-
-Codeception supports three test formats. Beside the previously described scenario-based Cept format,
-Codeception can also execute [PHPUnit test files for unit testing](http://codeception.com/docs/05-UnitTests), and Cest format.
-
-**Cest** combines scenario-driven test approach with OOP design. In case you want to group a few testing scenarios into one, you should consider using Cest format.
-In the example below we are testing CRUD actions within a single file but with several tests (one per operation):
+For instance, to test CRUD we want 4 methods to be implemented and all next tests should start at `/task` page:
```php
amOnPage('/');
+ $I->amOnPage('/task');
}
- function createPage(AcceptanceTester $I)
+ function createTask(AcceptanceTester $I)
{
// todo: write test
}
- function viewPage(AcceptanceTester $I)
+ function viewTask(AcceptanceTester $I)
{
// todo: write test
}
- function updatePage(AcceptanceTester $I)
+ function updateTask(AcceptanceTester $I)
{
// todo: write test
}
- function deletePage(AcceptanceTester $I)
+ function deleteTask(AcceptanceTester $I)
{
// todo: write test
}
}
```
-Cest files such as this can be created by running a generator:
-
-```bash
-php codecept generate:cest acceptance PageCrud
-```
-
Learn more about the [Cest format](http://codeception.com/docs/07-AdvancedUsage#Cest-Classes) in the Advanced Testing section.
## BDD
@@ -262,44 +247,44 @@ The same goes for suite configs. For example, the `unit.suite.yml` will be merge
Tests can be started with the `run` command:
```bash
-php codecept run
+php vendor/bin/codecept run
```
With the first argument you can run all tests from one suite:
```bash
-php codecept run acceptance
+php vendor/bin/codecept run acceptance
```
To limit tests run to a single class, add a second argument. Provide a local path to the test class, from the suite directory:
```bash
-php codecept run acceptance SigninCept.php
+php vendor/bin/codecept run acceptance SigninCest.php
```
Alternatively you can provide the full path to test file:
```bash
-php codecept run tests/acceptance/SigninCept.php
+php vendor/bin/codecept run tests/acceptance/SigninCest.php
```
You can further filter which tests are run by appending a method name to the class, separated by a colon (for Cest or Test formats):
```bash
-php codecept run tests/acceptance/SignInCest.php:^anonymousLogin$
+php vendor/bin/codecept run tests/acceptance/SigninCest.php:^anonymousLogin$
```
You can provide a directory path as well. This will execute all acceptance tests from the `backend` dir:
```bash
-php codecept run tests/acceptance/backend
+php vendor/bin/codecept run tests/acceptance/backend
```
Using regular expressions, you can even run many different test methods from the same directory or class.
For example, this will execute all acceptance tests from the `backend` dir beginning with the word "login":
```bash
-php codecept run tests/acceptance/backend:^login
+php vendor/bin/codecept run tests/acceptance/backend:^login
```
To execute a group of tests that are not stored in the same directory, you can organize them in [groups](http://codeception.com/docs/07-AdvancedUsage#Groups).
@@ -309,7 +294,7 @@ To execute a group of tests that are not stored in the same directory, you can o
To generate JUnit XML output, you can provide the `--xml` option, and `--html` for HTML report.
```bash
-php codecept run --steps --xml --html
+php vendor/bin/codecept run --steps --xml --html
```
This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be stored in the `tests/_output/` directory.
@@ -317,7 +302,7 @@ This command will run all tests for all suites, displaying the steps, and buildi
To see all the available options, run the following command:
```bash
-php codecept help run
+php vendor/bin/codecept help run
```
## Debugging
@@ -329,7 +314,6 @@ You may print any information inside a test using the `codecept_debug` function.
There are plenty of useful Codeception commands:
-* `generate:cept` *suite* *filename* - Generates a sample Cept scenario
* `generate:cest` *suite* *filename* - Generates a sample Cest test
* `generate:test` *suite* *filename* - Generates a sample PHPUnit Test with Codeception hooks
* `generate:feature` *suite* *filename* - Generates Gherkin feature file
diff --git a/docs/03-AcceptanceTests.md b/docs/03-AcceptanceTests.md
index bab9320268..a091298d02 100644
--- a/docs/03-AcceptanceTests.md
+++ b/docs/03-AcceptanceTests.md
@@ -60,13 +60,23 @@ modules:
- \Helper\Acceptance
```
-We should start by creating a 'Cept' file:
+We should start by creating a test with the next command:
+
+```
+php vendor/bin/codecept g:cest acceptance Signin
+```
+
+It will be placed into `tests/acceptance` directory.
```php
wantTo('sign in');
+class SigninCest
+{
+ public function tryToTest(AcceptanceTester $I)
+ {
+ $I->wantTo('test my page');
+ }
+}
```
The `$I` object is used to write all interactions.
@@ -203,7 +213,6 @@ you can pass instance `\Codeception\Step\Argument\PasswordArgument` with the dat
```php
amOnPage('/form/password_argument');
diff --git a/docs/05-UnitTests.md b/docs/05-UnitTests.md
index 0aa9400710..60b538bab5 100644
--- a/docs/05-UnitTests.md
+++ b/docs/05-UnitTests.md
@@ -9,7 +9,7 @@ Codeception adds some nice helpers to simplify common tasks.
Create a test using `generate:test` command with a suite and test names as parameters:
```bash
-php codecept generate:test unit Example
+php vendor/bin/codecept generate:test unit Example
```
It creates a new `ExampleTest` file located in the `tests/unit` directory.
@@ -17,13 +17,13 @@ It creates a new `ExampleTest` file located in the `tests/unit` directory.
As always, you can run the newly created test with this command:
```bash
-php codecept run unit ExampleTest
+php vendor/bin/codecept run unit ExampleTest
```
Or simply run the whole set of unit tests with:
```bash
-php codecept run unit
+php vendor/bin/codecept run unit
```
A test created by the `generate:test` command will look like this:
@@ -73,15 +73,15 @@ class UserTest extends \Codeception\Test\Unit
{
public function testValidation()
{
- $user = User::create();
+ $user = new User();
- $user->username = null;
+ $user->setName(null);
$this->assertFalse($user->validate(['username']));
- $user->username = 'toolooooongnaaaaaaameeee';
+ $user->setName('toolooooongnaaaaaaameeee');
$this->assertFalse($user->validate(['username']));
- $user->username = 'davert';
+ $user->setName('davert');
$this->assertTrue($user->validate(['username']));
}
}
diff --git a/docs/06-ReusingTestCode.md b/docs/06-ReusingTestCode.md
index ba076e333c..5ac61a6398 100644
--- a/docs/06-ReusingTestCode.md
+++ b/docs/06-ReusingTestCode.md
@@ -12,7 +12,6 @@ We will get back to this later in this chapter, but for now let's look at the fo
```php
amOnPage('/');
$I->see('Hello');
$I->seeInDatabase('users', ['id' => 1]);
@@ -150,14 +149,14 @@ We call such a classes StepObjects.
Lets create an Admin StepObject with the generator:
```bash
-php codecept generate:stepobject acceptance Admin
+php vendor/bin/codecept generate:stepobject acceptance Admin
```
You can supply optional action names. Enter one at a time, followed by a newline.
End with an empty line to continue to StepObject creation.
```bash
-php codecept generate:stepobject acceptance Admin
+php vendor/bin/codecept generate:stepobject acceptance Admin
Add action to StepObject class (ENTER to exit): loginAsAdmin
Add action to StepObject class (ENTER to exit):
StepObject was created in /tests/acceptance/_support/Step/Acceptance/Admin.php
@@ -243,7 +242,7 @@ Do not hardcode complex CSS or XPath locators in your tests but rather move them
Codeception can generate a PageObject class for you with command:
```bash
-php codecept generate:pageobject Login
+php vendor/bin/codecept generate:pageobject Login
```
This will create a `Login` class in `tests/_support/Page`.
diff --git a/docs/07-AdvancedUsage.md b/docs/07-AdvancedUsage.md
index 9d8377cc41..dba333b58b 100644
--- a/docs/07-AdvancedUsage.md
+++ b/docs/07-AdvancedUsage.md
@@ -12,7 +12,7 @@ and you want to split it, you can easily move it into classes.
You can create a Cest file by running the command:
```bash
-$ php codecept generate:cest suitename CestName
+$ php vendor/bin/codecept generate:cest suitename CestName
```
The generated file will look like this:
@@ -387,7 +387,7 @@ The names of these files are used as environments names
You can generate a new file with this environment configuration by using the `generate:environment` command:
```bash
-$ php codecept g:env chrome
+$ php vendor/bin/codecept g:env chrome
```
In that file you can specify just the options you wish to override:
@@ -405,13 +405,13 @@ You can easily switch between those configs by running tests with `--env` option
To run the tests only for PhantomJS you just need to pass `--env phantom` as an option:
```bash
-$ php codecept run acceptance --env phantom
+$ php vendor/bin/codecept run acceptance --env phantom
```
To run the tests in all 3 browsers, list all the environments:
```bash
-$ php codecept run acceptance --env phantom --env chrome --env firefox
+$ php vendor/bin/codecept run acceptance --env phantom --env chrome --env firefox
```
The tests will be executed 3 times, each time in a different browser.
@@ -419,7 +419,7 @@ The tests will be executed 3 times, each time in a different browser.
It's also possible to merge multiple environments into a single configuration by separating them with a comma:
```bash
-$ php codecept run acceptance --env dev,phantom --env dev,chrome --env dev,firefox
+$ php vendor/bin/codecept run acceptance --env dev,phantom --env dev,chrome --env dev,firefox
```
The configuration is merged in the order given.
@@ -543,7 +543,7 @@ The interactive console was added to try Codeception commands before executing t
You can run the console with the following command:
``` bash
-$ php codecept console suitename
+$ php vendor/bin/codecept console suitename
```
Now you can execute all the commands of an appropriate Actor class and see the results immediately.
@@ -560,15 +560,15 @@ If you have several projects with Codeception tests, you can use a single `codec
You can pass the `-c` option to any Codeception command (except `bootstrap`), to execute Codeception in another directory:
```bash
-$ php codecept run -c ~/projects/ecommerce/
-$ php codecept run -c ~/projects/drupal/
-$ php codecept generate:cept acceptance CreateArticle -c ~/projects/drupal/
+$ php vendor/bin/codecept run -c ~/projects/ecommerce/
+$ php vendor/bin/codecept run -c ~/projects/drupal/
+$ php vendor/bin/codecept generate:cept acceptance CreateArticle -c ~/projects/drupal/
```
To create a project in directory different from the current one, just provide its path as a parameter:
```bash
-$ php codecept bootstrap ~/projects/drupal/
+$ php vendor/bin/codecept bootstrap ~/projects/drupal/
```
Also, the `-c` option allows you to specify another config file to be used.
@@ -580,13 +580,13 @@ and settings). Just pass the `.yml` filename as the `-c` parameter to execute te
There are several ways to execute a bunch of tests. You can run tests from a specific directory:
```bash
-$ php codecept run tests/acceptance/admin
+$ php vendor/bin/codecept run tests/acceptance/admin
```
You can execute one (or several) specific groups of tests:
```bash
-$ php codecept run -g admin -g editor
+$ php vendor/bin/codecept run -g admin -g editor
```
The concept of groups was taken from PHPUnit and behave in the same way.
diff --git a/docs/07-BDD.md b/docs/07-BDD.md
index 1c05986f37..c4e7bfcd1a 100644
--- a/docs/07-BDD.md
+++ b/docs/07-BDD.md
@@ -81,7 +81,7 @@ Feature file is written in Gherkin format. Codeception can generate a feature fi
We will assume that we will use scenarios in feature files for acceptance tests, so feature files to be placed in `acceptance` suite directory:
```bash
-php codecept g:feature acceptance checkout
+php vendor/bin/codecept g:feature acceptance checkout
```
Generated template will look like this:
diff --git a/docs/08-Customization.md b/docs/08-Customization.md
index dde87bfbd1..22e1d2f021 100644
--- a/docs/08-Customization.md
+++ b/docs/08-Customization.md
@@ -34,7 +34,7 @@ To avoid naming conflicts between Actor classes and Helper classes, they should
To create test suites with namespaces you can add `--namespace` option to the bootstrap command:
```bash
-php codecept bootstrap --namespace frontend
+php vendor/bin/codecept bootstrap --namespace frontend
```
This will bootstrap a new project with the `namespace: frontend` parameter in the `codeception.yml` file.
@@ -44,7 +44,7 @@ Once each of your applications (bundles) has its own namespace and different Hel
you can execute all the tests in a single runner. Run the Codeception tests as usual, using the meta-config we created earlier:
```bash
-php codecept run
+php vendor/bin/codecept run
```
This will launch the test suites for all three applications and merge the reports from all of them.
@@ -54,7 +54,7 @@ and you want to get a single report in JUnit and HTML format. The code coverage
If you want to run a specific suite from the application you can execute:
```
-php codecept run unit -c frontend
+php vendor/bin/codecept run unit -c frontend
```
Where `unit` is the name of suite and the `-c` option specifies the path to the `codeception.yml` configuration file to use.
@@ -71,7 +71,7 @@ By default, one `RunFailed` Extension is already enabled in your global `codecep
It allows you to rerun failed tests by using the `-g failed` option:
```
-php codecept run -g failed
+php vendor/bin/codecept run -g failed
```
Codeception comes with bundled extensions located in `ext` directory.
@@ -293,7 +293,7 @@ For instance, for `nocleanup` group we prevent Doctrine2 module from wrapping te
}
```
-A group class can be created with `php codecept generate:group groupname` command.
+A group class can be created with `php vendor/bin/codecept generate:group groupname` command.
Group classes will be stored in the `tests/_support/Group` directory.
A group class can be enabled just like you enable an extension class. In the file `codeception.yml`:
diff --git a/docs/10-WebServices.md b/docs/10-WebServices.md
index 7c5556294d..79a907bf7d 100644
--- a/docs/10-WebServices.md
+++ b/docs/10-WebServices.md
@@ -5,7 +5,7 @@ The same way we tested a web site, Codeception allows you to test web services.
You should start by creating a new test suite, (which was not provided by the `bootstrap` command). We recommend calling it **api** and using the `ApiTester` class for it.
```bash
-$ php codecept generate:suite api
+$ php vendor/bin/codecept generate:suite api
```
We will put all the api tests there.
@@ -51,22 +51,36 @@ modules:
Once we have configured our new testing suite, we can create the first sample test:
```bash
-$ php codecept generate:cept api CreateUser
+$ codecept generate:cest api CreateUser
```
-It will be called `CreateUserCept.php`. We can use it to test the creation of a user via the REST API.
+It will be called `CreateUserCest.php`.
+We need to implement a public method for each test. Let's make `createUserViaAPI` to test creation of a user via the REST API.
```php
wantTo('create a user via API');
-$I->amHttpAuthenticated('service_user', '123456');
-$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
-$I->sendPOST('/users', ['name' => 'davert', 'email' => 'davert@codeception.com']);
-$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
-$I->seeResponseIsJson();
-$I->seeResponseContains('{"result":"ok"}');
-
+class CreateUserCest
+{
+ public function _before(\ApiTester $I)
+ {
+ }
+
+ public function _after(\ApiTester $I)
+ {
+ }
+
+ // tests
+ public function createUserViaAPI(\ApiTester $I)
+ {
+ $I->amHttpAuthenticated('service_user', '123456');
+ $I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
+ $I->sendPOST('/users', ['name' => 'davert', 'email' => 'davert@codeception.com']);
+ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
+ $I->seeResponseIsJson();
+ $I->seeResponseContains('{"result":"ok"}');
+
+ }
+}
```
We can use HTTP code constants from `Codeception\Util\HttpCode` instead of numeric values to check response code in `seeResponseCodeIs` and `dontSeeResponseCodeIs` methods.
@@ -117,14 +131,11 @@ If we expect a JSON response to be received we can check its structure with [JSO
```php
wantTo('validate structure of GitHub api responses');
$I->sendGET('/users');
$I->seeResponseCodeIs(HttpCode::OK); // 200
$I->seeResponseIsJson();
$I->seeResponseJsonMatchesJsonPath('$[0].user.login');
$I->seeResponseJsonMatchesXpath('//user/login');
-
```
More detailed check can be applied if you need to validate the type of fields in a response.
@@ -155,25 +166,21 @@ There is `seeXmlResponseIncludes` method to match inclusion of XML parts in resp
```php
wantTo('validate structure of GitHub api responses');
$I->sendGET('/users.xml');
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->seeResponseIsXml();
$I->seeXmlResponseMatchesXpath('//user/login');
-$I->seeXmlResponseIncludes(XmlUtils::toXml(
+$I->seeXmlResponseIncludes(\Codeception\Util\Xml::toXml([
'user' => [
'name' => 'davert',
'email' => 'davert@codeception.com',
'status' => 'inactive'
]
-));
+]));
```
-We are using XmlUtils class which allows us to build XML structures in a clean manner. The `toXml` method may accept a string or array and returns \DOMDocument instance. If your XML contains attributes and so can't be represented as a PHP array you can create XML using the [XmlBuilder](http://codeception.com/docs/reference/XmlBuilder) class. We will take a look at it a bit more in next section.
+We are using `Codeception\Util\Xml` class which allows us to build XML structures in a clean manner. The `toXml` method may accept a string or array and returns \DOMDocument instance. If your XML contains attributes and so can't be represented as a PHP array you can create XML using the [XmlBuilder](http://codeception.com/docs/reference/XmlBuilder) class. We will take a look at it a bit more in next section.
Use `\Codeception\Util\Xml::build()` to create XmlBuilder instance.
@@ -247,14 +254,10 @@ In the next example we will use `XmlBuilder` instead of regular XML.
```php
wantTo('create user');
$I->haveSoapHeader('Session', array('token' => '123456'));
$I->sendSoapRequest('CreateUser', Xml::build()
->user->email->val('miles@davis.com'));
-$I->seeSoapResponseIncludes(Xml::build()
+$I->seeSoapResponseIncludes(\Codeception\Util\Xml::build()
->result->val('Ok')
->user->attr('id', 1)
);
diff --git a/docs/12-ContinuousIntegration.md b/docs/12-ContinuousIntegration.md
index bf077354af..ae89177be1 100644
--- a/docs/12-ContinuousIntegration.md
+++ b/docs/12-ContinuousIntegration.md
@@ -31,7 +31,7 @@ At first we need to create build project. Depending on your needs you can set up
We need to define build steps. The most simple setup may look like this:
```
-php codecept run
+php vendor/bin/codecept run
```

@@ -47,7 +47,7 @@ But we don't want to analyze console output for each failing build. Especially I
Now let's update our build step to generate xml:
```
-php codecept run --xml
+php vendor/bin/codecept run --xml
```
and ask Jenkins to collect resulted XML. This can be done as part of Post-build actions. Let's add *Publish xUnit test result report* action and configure it to use with PHPUnit reports.
@@ -65,7 +65,7 @@ Now for all builds we will see results trend graph that shows us percentage of p
To get more details on steps executed you can generate HTML report and use Jenkins to display them.
```
-php codecept run --html
+php vendor/bin/codecept run --html
```
Now we need HTML Publisher plugin configured to display generated HTML files. It should be added as post-build action similar way we did it for XML reports.
@@ -93,7 +93,7 @@ As an alternative you can use 3rd-party [TeamCity extension](https://github.com/
After you create build project you should define build step with Codeception which is
```
-php codecept run --report
+php vendor/bin/codecept run --report
```

@@ -109,7 +109,7 @@ Once you execute your first build you should see detailed report inside TeamCity
Travis CI is popular service CI with good GitHub integration. Codeception is self-tested with Travis CI. There nothing special about configuration. Just add to the bottom line of travis configuration:
```yaml
-php codecept run
+php vendor/bin/codecept run
```
More details on configuration can be learned from Codeception's [`.travis.yml`](https://github.com/Codeception/Codeception/blob/master/.travis.yml).
From 20aedae166684dacde4cfffb5cdefac06a4c6ddb Mon Sep 17 00:00:00 2001
From: Greg Heitz
Date: Sun, 1 Apr 2018 18:06:28 +0200
Subject: [PATCH 028/395] Goodbye PHP 5.4 (fix #4836 and #4837) (#4905)
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index d707d4e5e8..fbb47559f5 100644
--- a/composer.json
+++ b/composer.json
@@ -15,7 +15,7 @@
"minimum-stability": "RC",
"require": {
- "php": ">=5.4.0 <8.0",
+ "php": ">=5.6.0 <8.0",
"ext-json": "*",
"ext-mbstring": "*",
"facebook/webdriver": ">=1.1.3 <2.0",
From 37d60db1822af1b17d9fadbea0b89a55c6cede05 Mon Sep 17 00:00:00 2001
From: edno
Date: Sun, 1 Apr 2018 20:25:20 +0200
Subject: [PATCH 029/395] Fix #4846
---
src/Codeception/Module/WebDriver.php | 13 +++++++++++--
tests/web/WebDriverTest.php | 25 ++++++++++++++++++++++---
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index 1b575f03f6..3afca58de9 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -2867,12 +2867,21 @@ protected function convertKeyModifier($keys)
protected function assertNodesContain($text, $nodes, $selector = null)
{
- $this->assertThat($nodes, new WebDriverConstraint($text, $this->_getCurrentUri()), $selector);
+ $this->assertNodeConstraint($nodes, new WebDriverConstraint($text, $this->_getCurrentUri()), $selector);
}
protected function assertNodesNotContain($text, $nodes, $selector = null)
{
- $this->assertThat($nodes, new WebDriverConstraintNot($text, $this->_getCurrentUri()), $selector);
+ $this->assertNodeConstraint($nodes, new WebDriverConstraintNot($text, $this->_getCurrentUri()), $selector);
+ }
+
+ protected function assertNodeConstraint($nodes, WebDriverConstraint $constraint, $selector = null)
+ {
+ $message = $selector;
+ if (is_array($selector)) {
+ $message = implode(array_keys($selector)) . ':' . implode($selector);
+ }
+ $this->assertThat($nodes, $constraint, $message);
}
protected function assertPageContains($needle, $message = '')
diff --git a/tests/web/WebDriverTest.php b/tests/web/WebDriverTest.php
index 26ac63e4ae..f14d35c547 100644
--- a/tests/web/WebDriverTest.php
+++ b/tests/web/WebDriverTest.php
@@ -802,7 +802,7 @@ public function testSeeInFieldForTextarea()
$this->module->amOnPage('/form/bug2921');
$this->module->seeInField('foo', 'bar baz');
}
-
+
/**
* @Issue 4726
*/
@@ -811,8 +811,8 @@ public function testClearField()
$this->module->amOnPage('/form/textarea');
$this->module->fillField('#description', 'description');
$this->module->clearField('#description');
- $this->module->dontSeeInField('#description', 'description');
- }
+ $this->module->dontSeeInField('#description', 'description');
+ }
public function testClickHashLink()
{
@@ -1106,4 +1106,23 @@ public function testChangingCapabilities()
$this->module->_initializeSession();
$this->assertTrue(true, $this->module->webDriver->getCapabilities()->getCapability('acceptInsecureCerts'));
}
+
+ /**
+ * @dataProvider strictBug4846Provider
+ **/
+ public function testBug4846($selector)
+ {
+ $this->module->amOnPage('/');
+ $this->module->see('Welcome to test app!', $selector);
+ $this->module->dontSee('You cannot see that', $selector);
+ }
+
+ public function strictBug4846Provider()
+ {
+ return [
+ 'by id' => ['h1'],
+ 'by css' => [['css' => 'body h1']],
+ 'by xpath' => ['//body/h1'],
+ ];
+ }
}
From 9345d946800b18fcff5df387712ebf3fa62b4016 Mon Sep 17 00:00:00 2001
From: Sam
Date: Wed, 4 Apr 2018 15:26:20 +0200
Subject: [PATCH 030/395] Implemented alternate strategies for clearing
response / request objects (#4915)
* Implemented alternate strategies for clearing response / request objects
* Fixed nitpick CS
* Removed constant visibility, which is not supported in older PHP versions
---
src/Codeception/Lib/Connector/Yii2.php | 127 ++++++++++++++++++++++++-
src/Codeception/Module/Yii2.php | 24 ++++-
2 files changed, 147 insertions(+), 4 deletions(-)
diff --git a/src/Codeception/Lib/Connector/Yii2.php b/src/Codeception/Lib/Connector/Yii2.php
index 9624f05713..ac219362d1 100644
--- a/src/Codeception/Lib/Connector/Yii2.php
+++ b/src/Codeception/Lib/Connector/Yii2.php
@@ -10,6 +10,8 @@
use Yii;
use yii\base\ExitException;
use yii\base\Security;
+use yii\web\Application;
+use yii\web\ErrorHandler;
use yii\web\HttpException;
use yii\web\Request;
use yii\web\Response as YiiResponse;
@@ -18,11 +20,50 @@ class Yii2 extends Client
{
use Shared\PhpSuperGlobalsConverter;
+ const CLEAN_METHODS = [
+ self::CLEAN_RECREATE,
+ self::CLEAN_CLEAR,
+ self::CLEAN_FORCE_RECREATE,
+ self::CLEAN_MANUAL
+ ];
+ /**
+ * Clean the response object by recreating it.
+ * This might lose behaviors / event handlers / other changes that are done in the application bootstrap phase.
+ */
+ const CLEAN_RECREATE = 'recreate';
+ /**
+ * Same as recreate but will not warn when behaviors / event handlers are lost.
+ */
+ const CLEAN_FORCE_RECREATE = 'force_recreate';
+ /**
+ * Clean the response object by resetting specific properties via its' `clear()` method.
+ * This will keep behaviors / event handlers, but could inadvertently leave some changes intact.
+ * @see \Yii\web\Response::clear()
+ */
+ const CLEAN_CLEAR = 'clear';
+
+ /**
+ * Do not clean the response, instead the test writer will be responsible for manually resetting the response in
+ * between requests during one test
+ */
+ const CLEAN_MANUAL = 'manual';
+
+
/**
* @var string application config file
*/
public $configFile;
+ /**
+ * @var string method for cleaning the response object before each request
+ */
+ public $responseCleanMethod;
+
+ /**
+ * @var string method for cleaning the request object before each request
+ */
+ public $requestCleanMethod;
+
/**
* @return \yii\web\Application
*/
@@ -99,7 +140,9 @@ public function doRequest($request)
* @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
* those changes to be reflected in the reponse.
*/
- $app->set('response', $app->getComponents()['response']);
+ $this->resetResponse($app);
+
+
// disabling logging. Logs are slowing test execution down
foreach ($app->log->targets as $target) {
@@ -114,7 +157,7 @@ public function doRequest($request)
* @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
* those changes to be reflected in the reponse.
*/
- $app->set('request', $app->getComponents()['request']);
+ $this->resetRequest($app);
$yiiRequest = $app->getRequest();
if ($request->getContent() !== null) {
@@ -134,7 +177,6 @@ public function doRequest($request)
$app->trigger($app::EVENT_BEFORE_REQUEST);
$response = $app->handleRequest($yiiRequest);
$app->trigger($app::EVENT_AFTER_REQUEST);
- codecept_debug($response->isSent);
$response->send();
} catch (\Exception $e) {
if ($e instanceof HttpException) {
@@ -259,4 +301,83 @@ public function restart()
parent::restart();
$this->resetApplication();
}
+
+ /**
+ * Resets the applications' response object.
+ * The method used depends on the module configuration.
+ */
+ protected function resetResponse(Application $app)
+ {
+ $method = $this->responseCleanMethod;
+ // First check the current response object.
+ if (($app->response->hasEventHandlers(\yii\web\Response::EVENT_BEFORE_SEND)
+ || $app->response->hasEventHandlers(\yii\web\Response::EVENT_AFTER_SEND)
+ || $app->response->hasEventHandlers(\yii\web\Response::EVENT_AFTER_PREPARE)
+ || count($app->response->getBehaviors()) > 0
+ ) && $method === self::CLEAN_RECREATE
+ ) {
+ Debug::debug(<<set('response', $app->getComponents()['response']);
+ break;
+ case self::CLEAN_CLEAR:
+ $app->response->clear();
+ break;
+ case self::CLEAN_MANUAL:
+ break;
+ }
+ }
+
+ protected function resetRequest(Application $app)
+ {
+ $method = $this->requestCleanMethod;
+ $request = $app->request;
+
+ // First check the current request object.
+ if (count($request->getBehaviors()) > 0 && $method === self::CLEAN_RECREATE) {
+ Debug::debug(<<set('request', $app->getComponents()['request']);
+ break;
+ case self::CLEAN_CLEAR:
+ $request->getHeaders()->removeAll();
+ $request->getCookies()->removeAll();
+ $request->setBaseUrl(null);
+ $request->setHostInfo(null);
+ $request->setPathInfo(null);
+ $request->setScriptFile(null);
+ $request->setScriptUrl(null);
+ $request->setUrl(null);
+ $request->setPort(null);
+ $request->setSecurePort(null);
+ $request->setAcceptableContentTypes(null);
+ $request->setAcceptableLanguages(null);
+
+ break;
+ case self::CLEAN_MANUAL:
+ break;
+ }
+ }
}
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index 9d679ff896..15b8eb48de 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -37,7 +37,10 @@
* * `cleanup` - (default: true) cleanup fixtures after the test
* * `ignoreCollidingDSN` - (default: false) When 2 database connections use the same DSN but different settings an exception will be thrown, set this to true to disable this behavior.
* * `fixturesMethod` - (default: _fixtures) Name of the method used for creating fixtures.
- *
+ * * `responseCleanMethod` - (default: clear) Method for cleaning the response object. Note that this is only for multiple requests inside a single test case.
+ * Between test casesthe whole application is always recreated
+ * * `requestCleanMethod` - (default: clear) Method for cleaning the request object. Note that this is only for multiple requests inside a single test case.
+ * Between test cases the whole application is always recreated
* You can use this module by setting params in your functional.suite.yml:
*
* ```yaml
@@ -150,6 +153,8 @@ class Yii2 extends Framework implements ActiveRecord, PartedModule
'transaction' => null,
'entryScript' => '',
'entryUrl' => 'http://localhost/index-test.php',
+ 'responseCleanMethod' => Yii2Connector::CLEAN_CLEAR,
+ 'requestCleanMethod' => Yii2Connector::CLEAN_RECREATE
];
protected $requiredFields = ['configFile'];
@@ -178,6 +183,7 @@ class Yii2 extends Framework implements ActiveRecord, PartedModule
* It MUST not be used anywhere else.
*/
private $server;
+
public function _initialize()
{
if ($this->config['transaction'] === null) {
@@ -232,6 +238,20 @@ protected function validateConfig()
"The application config file does not exist: " . Configuration::projectDir() . $this->config['configFile']
);
}
+
+ if (!in_array($this->config['responseCleanMethod'], Yii2Connector::CLEAN_METHODS)) {
+ throw new ModuleConfigException(
+ __CLASS__,
+ "The response clean method must be one of: " . implode(", ", Yii2Connector::CLEAN_METHODS)
+ );
+ }
+
+ if (!in_array($this->config['requestCleanMethod'], Yii2Connector::CLEAN_METHODS)) {
+ throw new ModuleConfigException(
+ __CLASS__,
+ "The response clean method must be one of: " . implode(", ", Yii2Connector::CLEAN_METHODS)
+ );
+ }
}
@@ -250,6 +270,7 @@ public function _before(TestInterface $test)
]);
$this->client->configFile = Configuration::projectDir() . $this->config['configFile'];
+ $this->client->responseCleanMethod = $this->config['responseCleanMethod'];
$this->client->resetApplication();
$app = $this->client->getApplication();
@@ -352,6 +373,7 @@ protected function startTransactions()
&& $this->dsnCache[$connection->dsn] !== $key
&& !$this->config['ignoreCollidingDSN']
) {
+
$this->debugSection('WARNING', <<dsn}) with different configuration.
These connections will not see the same database state since we cannot share a transaction between different PDO
From 30ec967a18bd866369df77c776c363c225eea656 Mon Sep 17 00:00:00 2001
From: Sam
Date: Thu, 5 Apr 2018 11:53:20 +0200
Subject: [PATCH 031/395] Support reconfiguration (#4918)
* Add support for reconfiguration during tests and fix issue with sqlite transactions
* Fixed nitpick CS
* Fixed docs, don't attempt to clear cookies since they won't get reloaded.
---
src/Codeception/Lib/Connector/Yii2.php | 1 -
src/Codeception/Module/Yii2.php | 136 ++++++++++++++-----------
2 files changed, 78 insertions(+), 59 deletions(-)
diff --git a/src/Codeception/Lib/Connector/Yii2.php b/src/Codeception/Lib/Connector/Yii2.php
index ac219362d1..5a485ef132 100644
--- a/src/Codeception/Lib/Connector/Yii2.php
+++ b/src/Codeception/Lib/Connector/Yii2.php
@@ -363,7 +363,6 @@ protected function resetRequest(Application $app)
break;
case self::CLEAN_CLEAR:
$request->getHeaders()->removeAll();
- $request->getCookies()->removeAll();
$request->setBaseUrl(null);
$request->setHostInfo(null);
$request->setPathInfo(null);
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index 15b8eb48de..958b6202a8 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -39,7 +39,7 @@
* * `fixturesMethod` - (default: _fixtures) Name of the method used for creating fixtures.
* * `responseCleanMethod` - (default: clear) Method for cleaning the response object. Note that this is only for multiple requests inside a single test case.
* Between test casesthe whole application is always recreated
- * * `requestCleanMethod` - (default: clear) Method for cleaning the request object. Note that this is only for multiple requests inside a single test case.
+ * * `requestCleanMethod` - (default: recreate) Method for cleaning the request object. Note that this is only for multiple requests inside a single test case.
* Between test cases the whole application is always recreated
* You can use this module by setting params in your functional.suite.yml:
*
@@ -198,17 +198,16 @@ public function _initialize()
/**
* Module configuration changed inside a test.
- * We might need to re-create the application.
+ * We always re-create the application.
*/
protected function onReconfigure()
{
parent::onReconfigure();
- if (isset(\Yii::$app)) {
- $this->client->restart();
- }
+ $this->client->resetApplication();
+ $this->configureClient($this->config);
+ $this->client->startApp();
}
-
/**
* Adds the required server params.
* Note this is done separately from the request cycle since someone might call
@@ -254,8 +253,22 @@ protected function validateConfig()
}
}
+ protected function configureClient(array $settings)
+ {
+ $settings['configFile'] = Configuration::projectDir() . $settings['configFile'];
- public function _before(TestInterface $test)
+ foreach ($settings as $key => $value) {
+ if (property_exists($this->client, $key)) {
+ $this->client->$key = $value;
+ }
+ }
+ $this->client->resetApplication();
+ }
+
+ /**
+ * Instantiates the client based on module configuration
+ */
+ protected function recreateClient()
{
$entryUrl = $this->config['entryUrl'];
$entryFile = $this->config['entryScript'] ?: basename($entryUrl);
@@ -269,11 +282,13 @@ public function _before(TestInterface $test)
'HTTPS' => parse_url($entryUrl, PHP_URL_SCHEME) === 'https'
]);
- $this->client->configFile = Configuration::projectDir() . $this->config['configFile'];
- $this->client->responseCleanMethod = $this->config['responseCleanMethod'];
+ $this->configureClient($this->config);
+ }
- $this->client->resetApplication();
- $app = $this->client->getApplication();
+ public function _before(TestInterface $test)
+ {
+ $this->recreateClient();
+ $this->client->startApp();
// load fixtures before db transaction
if ($test instanceof \Codeception\Test\Cest) {
@@ -336,68 +351,73 @@ public function _after(TestInterface $test)
if ($this->client->getApplication()->has('session', true)) {
$this->client->getApplication()->session->close();
}
-
parent::_after($test);
}
- protected function startTransactions()
- {
- if ($this->config['transaction']) {
- // This should register handlers that start a transaction whenever a connection opens and add it to the transactions array.
- Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, function (Event $event) {
- if ($event->sender instanceof Connection) {
- $connection = $event->sender;
- /*
- * We should check if the known PDO objects are the same, in which case we should reuse the PDO
- * object so only 1 transaction is started and multiple connections to the same database see the
- * same data (due to writes inside a transaction not being visible from the outside).
- *
- */
- $key = md5(json_encode([
- 'dsn' => $connection->dsn,
- 'user' => $connection->username,
- 'pass' => $connection->password,
- 'attributes' => $connection->attributes,
- 'emulatePrepare' => $connection->emulatePrepare,
- 'charset' => $connection->charset
- ]));
-
- /*
- * If keys match we assume connections are "similar enough".
- */
- if (isset($this->pdoCache[$key])) {
- $connection->pdo = $this->pdoCache[$key];
- }
-
- if (isset($this->dsnCache[$connection->dsn])
- && $this->dsnCache[$connection->dsn] !== $key
- && !$this->config['ignoreCollidingDSN']
- ) {
-
- $this->debugSection('WARNING', <<sender instanceof Connection) {
+ $connection = $event->sender;
+ /*
+ * We should check if the known PDO objects are the same, in which case we should reuse the PDO
+ * object so only 1 transaction is started and multiple connections to the same database see the
+ * same data (due to writes inside a transaction not being visible from the outside).
+ *
+ */
+ $key = md5(json_encode([
+ 'dsn' => $connection->dsn,
+ 'user' => $connection->username,
+ 'pass' => $connection->password,
+ 'attributes' => $connection->attributes,
+ 'emulatePrepare' => $connection->emulatePrepare,
+ 'charset' => $connection->charset
+ ]));
+
+ /*
+ * If keys match we assume connections are "similar enough".
+ */
+ if (isset($this->pdoCache[$key])) {
+ $connection->pdo = $this->pdoCache[$key];
+ }
+
+ if (isset($this->dsnCache[$connection->dsn])
+ && $this->dsnCache[$connection->dsn] !== $key
+ && !$this->config['ignoreCollidingDSN']
+ ) {
+ $this->debugSection('WARNING', <<dsn}) with different configuration.
These connections will not see the same database state since we cannot share a transaction between different PDO
instances.
You can remove this message by adding 'ignoreCollidingDSN = true' in the module configuration.
TEXT
- );
- Debug::pause();
- }
+ );
+ Debug::pause();
+ }
- if (isset($this->transactions[$key])) {
- $this->debugSection('Database', 'Reusing PDO, so no need for a new transaction');
- return;
- }
+ if (isset($this->transactions[$key])) {
+ $this->debugSection('Database', 'Reusing PDO, so no need for a new transaction');
+ return;
+ }
- $this->debugSection('Database', 'Transaction started for: ' . $connection->dsn);
- $this->transactions[$key] = $connection->beginTransaction();
- }
- });
+ $this->debugSection('Database', 'Transaction started for: ' . $connection->dsn);
+ $this->transactions[$key] = $connection->beginTransaction();
+ }
+
+ }
+
+ protected function startTransactions()
+ {
+ if ($this->config['transaction']) {
+ // This should register handlers that start a transaction whenever a connection opens and add it to the transactions array.
+ $this->debug('Transaction', 'Registering connection event handler');
+ Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, [$this, 'connectionOpenHandler']);
}
}
protected function rollbackTransactions()
{
+ $this->debugSection('Transaction', 'Rolling back ' . count($this->transactions) . ' transactions');
+ Event::off(Connection::class, Connection::EVENT_AFTER_OPEN, [$this, 'connectionOpenHandler']);
/** @var Transaction $transaction */
foreach ($this->transactions as $transaction) {
$transaction->rollBack();
From 8794a9a501f0e9ad0f411e05789e15719c1dab8d Mon Sep 17 00:00:00 2001
From: Sam
Date: Thu, 5 Apr 2018 16:16:55 +0200
Subject: [PATCH 032/395] Improved test speed (#4921)
* This PR improves test speed by skipping framework tests if we're certain that changes don't impact them
* Fixed NitPick CS
* Fix typo
* Only skip frameworks if code changes actually limited to framework code.
* Fix NitPick CS
* Stop nitpicking!
---
.travis.yml | 5 +++--
PruneTest.php | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 PruneTest.php
diff --git a/.travis.yml b/.travis.yml
index febacbc628..c1665990c2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -72,6 +72,7 @@ services:
- redis
before_install:
+ - '$(php PruneTest.php)'
- '[[ !(-z "$XDEBUG") ]] || phpenv config-rm xdebug.ini'
- export INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- echo memory_limit = -1 >> $INI
@@ -126,6 +127,6 @@ before_script:
- '[[ "$FRAMEWORK" != "Zend2" ]] || mysql -e "create database zf2_test;"'
- '[[ "$FRAMEWORK" != "Zend2" ]] || php framework-tests/vendor/bin/doctrine-module orm:schema-tool:create'
# Build
- - php codecept build -c $TEST_PATH
+ - '[[ -z "$FRAMEWORK" ]] || php codecept build -c $TEST_PATH'
script:
- - php codecept run $SUITES -c $TEST_PATH
\ No newline at end of file
+ - '[[ -z "$FRAMEWORK" ]] || php codecept run $SUITES -c $TEST_PATH'
\ No newline at end of file
diff --git a/PruneTest.php b/PruneTest.php
new file mode 100644
index 0000000000..f2145f51ef
--- /dev/null
+++ b/PruneTest.php
@@ -0,0 +1,61 @@
+ '/.*Yii2.*/',
+ 'Lumen' => '/.*(Lumen|LaravelCommon).*/',
+ 'Laravel' => '/.*Laravel.*/',
+ 'Phalcon' => '/.*Phalcon.*/',
+ 'Symfony' => '/.*Symfony.*/',
+ 'Yii1' => '/.*Yii1.*/',
+ 'ZendExpressive' => '/.*ZendExpressive.*/',
+ 'Zend1' => '/.*ZF1.*/',
+ 'Zend2' => '/.*ZF2.*/',
+];
+
+// First check if changes include files that are not framework files.
+$frameworkOnly = true;
+$frameworks = [];
+foreach ($files as $file) {
+ $match = false;
+ foreach ($regexes as $framework => $regex) {
+ if (preg_match($regex, $file)) {
+ $match = true;
+ $frameworks[$framework] = $framework;
+ break;
+ }
+ }
+ if (!$match) {
+ $frameworkOnly = false;
+ break;
+ }
+}
+
+if ($frameworkOnly) {
+ stderr('Changes limited to frameworks: ' . implode(', ', $frameworks));
+ if (!isset($frameworks[$currentFramework])) {
+ stderr("Skipping test for framework: $currentFramework");
+ echo "export FRAMEWORK=\n";
+ echo "export PECL=\n";
+ echo "export FXP=\n";
+ echo "export CI_USER_TOKEN=\n";
+ }
+}
From 8316c9f8695e719b025639ed04619467b0fbb1db Mon Sep 17 00:00:00 2001
From: Sam
Date: Thu, 5 Apr 2018 20:56:57 +0200
Subject: [PATCH 033/395] Fixed an issue with exit exceptions (#4923)
* Fixed an issue where exceptions in the Yii app resulted in exceptions in the Yii module
* Fix test skipping
* Fix syntax error
* Update comments
---
.travis.yml | 7 ++++---
src/Codeception/Lib/Connector/Yii2.php | 3 +--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index c1665990c2..d57db9e6df 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -98,8 +98,8 @@ install:
- '[[ "$FRAMEWORK" != "Phalcon" ]] || (cd cphalcon/build; bash ./install --phpize $(phpenv which phpize) --php-config $(phpenv which php-config) &>/dev/null && phpenv config-add ../tests/_ci/phalcon.ini &> /dev/null)'
# Symfony
#- '[[ "$FRAMEWORK$VERSION" != "Symfony3" ]] || composer require -d framework-tests symfony/symfony=~$VERSION --no-update'
- - composer install
- - '[[ "$FRAMEWORK" == "Codeception" ]] || composer update -d framework-tests --no-dev --prefer-dist'
+ - '[[ -z "$FRAMEWORK" ]] || composer install'
+ - '[[ "$FRAMEWORK" == "Codeception" ]] || [[ -z "$FRAMEWORK" ]] || composer update -d framework-tests --no-dev --prefer-dist'
before_script:
- '[[ "$TRAVIS_PHP_VERSION" == 7.* ]] || echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini'
# preparing databases
@@ -129,4 +129,5 @@ before_script:
# Build
- '[[ -z "$FRAMEWORK" ]] || php codecept build -c $TEST_PATH'
script:
- - '[[ -z "$FRAMEWORK" ]] || php codecept run $SUITES -c $TEST_PATH'
\ No newline at end of file
+ # Run tests if $FRAMEWORK is not empty
+ - '[[ -z "$FRAMEWORK" ]] || php codecept run $SUITES -c $TEST_PATH'
diff --git a/src/Codeception/Lib/Connector/Yii2.php b/src/Codeception/Lib/Connector/Yii2.php
index 5a485ef132..a99214ef30 100644
--- a/src/Codeception/Lib/Connector/Yii2.php
+++ b/src/Codeception/Lib/Connector/Yii2.php
@@ -184,13 +184,12 @@ public function doRequest($request)
// to expect error response codes in tests.
$app->errorHandler->discardExistingOutput = false;
$app->errorHandler->handleException($e);
- $response = $app->response;
-
} elseif (!$e instanceof ExitException) {
// for exceptions not related to Http, we pass them to Codeception
$this->resetApplication();
throw $e;
}
+ $response = $app->response;
}
$this->encodeCookies($response, $yiiRequest, $app->security);
From 5c4872bebc9c9dbe0cae8072f6fc3ff702173c68 Mon Sep 17 00:00:00 2001
From: Sam
Date: Fri, 6 Apr 2018 15:27:14 +0200
Subject: [PATCH 034/395] =?UTF-8?q?This=20adds=20support=20for=20component?=
=?UTF-8?q?s=20that=20keep=20state=20that=20must=20be=20cleared=E2=80=A6?=
=?UTF-8?q?=20(#4924)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* This adds support for components that keep state that must be cleared between requests
* Fixed issue in test skip logic + nitpick CS
* Fix application reset after exception
* Add configuration option to recreate the whole application before each request
* Add default configuration
---
PruneTest.php | 5 +++
src/Codeception/Lib/Connector/Yii2.php | 57 ++++++++++++++++++--------
src/Codeception/Module/Yii2.php | 11 ++++-
3 files changed, 54 insertions(+), 19 deletions(-)
diff --git a/PruneTest.php b/PruneTest.php
index f2145f51ef..308be87bbd 100644
--- a/PruneTest.php
+++ b/PruneTest.php
@@ -15,6 +15,11 @@ function stderr($message)
}
$currentFramework = getenv('FRAMEWORK');
+
+if ($currentFramework === 'Codeception') {
+ stderr('Codeception tests are always executed');
+ die();
+}
$files = [];
exec("git diff --name-only $branch", $files);
diff --git a/src/Codeception/Lib/Connector/Yii2.php b/src/Codeception/Lib/Connector/Yii2.php
index a99214ef30..b7c750d006 100644
--- a/src/Codeception/Lib/Connector/Yii2.php
+++ b/src/Codeception/Lib/Connector/Yii2.php
@@ -64,6 +64,18 @@ class Yii2 extends Client
*/
public $requestCleanMethod;
+ /**
+ * @var string[] List of component names that must be recreated before each request
+ */
+ public $recreateComponents = [];
+
+ /**
+ * This option is there primarily for backwards compatibility.
+ * It means you cannot make any modification to application state inside your app, since they will get discarded.
+ * @var bool whether to recreate the whole application before each request
+ */
+ public $recreateApplication = false;
+
/**
* @return \yii\web\Application
*/
@@ -133,31 +145,19 @@ public function doRequest($request)
$_GET[$k] = $v;
}
- $app = $this->getApplication();
-
- /**
- * Just before the request we set the response object so it is always fresh.
- * @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
- * those changes to be reflected in the reponse.
- */
- $this->resetResponse($app);
+ ob_start();
+ $this->beforeRequest();
+ $app = $this->getApplication();
// disabling logging. Logs are slowing test execution down
foreach ($app->log->targets as $target) {
$target->enabled = false;
}
- ob_start();
- // recreating request object to reset headers and cookies collections
- /**
- * Just before the request we set the request object so it is always fresh.
- * @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
- * those changes to be reflected in the reponse.
- */
- $this->resetRequest($app);
+
$yiiRequest = $app->getRequest();
if ($request->getContent() !== null) {
@@ -186,7 +186,6 @@ public function doRequest($request)
$app->errorHandler->handleException($e);
} elseif (!$e instanceof ExitException) {
// for exceptions not related to Http, we pass them to Codeception
- $this->resetApplication();
throw $e;
}
$response = $app->response;
@@ -378,4 +377,28 @@ protected function resetRequest(Application $app)
break;
}
}
+
+ /**
+ * Called before each request, preparation happens here.
+ */
+ protected function beforeRequest()
+ {
+ if ($this->recreateApplication) {
+ $this->resetApplication();
+ return;
+ }
+
+ $application = $this->getApplication();
+
+ $this->resetResponse($application);
+ $this->resetRequest($application);
+
+ $definitions = $application->getComponents(true);
+ foreach ($this->recreateComponents as $component) {
+ // Only recreate if it has actually been instantiated.
+ if ($application->has($component, true)) {
+ $application->set($component, $definitions[$component]);
+ }
+ }
+ }
}
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index 958b6202a8..2a240a80b7 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -23,6 +23,7 @@
* ## Application state during testing
* This section details what you can expect when using this module.
* * You will get a fresh application in `\Yii::$app` at the start of each test (available in the test and in `_before()`).
+ * * Inside your test you may change application state; however these changes will be lost when doing a request if you have enabled `recreateApplication`.
* * When executing a request via one of the request functions the `request` and `response` component are both recreated.
* * After a request the whole application is available for inspection / interaction.
* * You may use multiple database connections, each will use a separate transaction; to prevent accidental mistakes we
@@ -41,8 +42,12 @@
* Between test casesthe whole application is always recreated
* * `requestCleanMethod` - (default: recreate) Method for cleaning the request object. Note that this is only for multiple requests inside a single test case.
* Between test cases the whole application is always recreated
+ * * `recreateComponents` - (default: []) Some components change their state making them unsuitable for processing multiple requests. In production this is usually
+ * not a problem since web apps tend to die and start over after each request. This allows you to list application components that need to be recreated before each request.
+ * As a consequence, any components specified here should not be changed inside a test since those changes will get regarded.
+ * You can use this module by setting params in your functional.suite.yml:
+ * * `recreateApplication` - (default: false) whether to recreate the whole application before each request
* You can use this module by setting params in your functional.suite.yml:
- *
* ```yaml
* actor: FunctionalTester
* modules:
@@ -154,7 +159,9 @@ class Yii2 extends Framework implements ActiveRecord, PartedModule
'entryScript' => '',
'entryUrl' => 'http://localhost/index-test.php',
'responseCleanMethod' => Yii2Connector::CLEAN_CLEAR,
- 'requestCleanMethod' => Yii2Connector::CLEAN_RECREATE
+ 'requestCleanMethod' => Yii2Connector::CLEAN_RECREATE,
+ 'recreateComponents' => [],
+ 'recreateApplication' => false
];
protected $requiredFields = ['configFile'];
From 6f0f6db334930aba49481e61a34824e6c2b0f588 Mon Sep 17 00:00:00 2001
From: Etki
Date: Tue, 10 Apr 2018 21:49:05 +0300
Subject: [PATCH 035/395] Added safety check for runtimes emulating php 7.1+
but not supporting pcntl_async_signals() (#4912)
---
src/Codeception/Subscriber/GracefulTermination.php | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/Codeception/Subscriber/GracefulTermination.php b/src/Codeception/Subscriber/GracefulTermination.php
index 0d9650534b..687b3b1fed 100644
--- a/src/Codeception/Subscriber/GracefulTermination.php
+++ b/src/Codeception/Subscriber/GracefulTermination.php
@@ -9,6 +9,7 @@
class GracefulTermination implements EventSubscriberInterface
{
const SIGNAL_FUNC = 'pcntl_signal';
+ const ASYNC_SIGNAL_HANDLING_FUNC = 'pcntl_async_signals';
/**
* @var SuiteEvent
@@ -17,10 +18,11 @@ class GracefulTermination implements EventSubscriberInterface
public function handleSuite(SuiteEvent $event)
{
- if (PHP_MAJOR_VERSION === 7) {
- if (PHP_MINOR_VERSION === 0) {
- return; // skip for PHP 7.0: https://github.com/Codeception/Codeception/issues/3607
- }
+ if (PHP_MAJOR_VERSION === 7 && PHP_MINOR_VERSION === 0) {
+ // skip for PHP 7.0: https://github.com/Codeception/Codeception/issues/3607
+ return;
+ }
+ if (function_exists(self::ASYNC_SIGNAL_HANDLING_FUNC)) {
pcntl_async_signals(true);
}
if (function_exists(self::SIGNAL_FUNC)) {
From 36ae1350a8cf4e0fa244dbb2932df9cf33a021c2 Mon Sep 17 00:00:00 2001
From: Viktor Robev
Date: Wed, 11 Apr 2018 03:30:09 +0300
Subject: [PATCH 036/395] Add session snapshot deletion (#4909)
* Fix typo in split documentation (#4455) [skip ci]
* Added new method seeOptionValueIsSelected (#4075)
* Added test for expected functionality
* Added new method seeOptionValueIsSelected
This method checks only into the value attribute of the specified selector
* Revert "Added new method seeOptionValueIsSelected (#4075)" (#4831)
This reverts commit 8881d642baf93bd8c41a19ca571602e6d680422e.
* Add session snapshot deletion
* Fix codestyle
---
src/Codeception/Module/WebDriver.php | 11 +++++++++++
tests/web/WebDriverTest.php | 12 ++++++++++++
2 files changed, 23 insertions(+)
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index 1b575f03f6..740e3b12ab 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -3065,6 +3065,17 @@ public function loadSessionSnapshot($name)
return true;
}
+ /**
+ * @param string $name
+ */
+ public function deleteSessionSnapshot($name)
+ {
+ if (isset($this->sessionSnapshots[$name])) {
+ unset($this->sessionSnapshots[$name]);
+ }
+ $this->debugSection('Snapshot', "Deleted \"$name\" session snapshot");
+ }
+
/**
* Check if the cookie domain matches the config URL.
*
diff --git a/tests/web/WebDriverTest.php b/tests/web/WebDriverTest.php
index 26ac63e4ae..85e9f6a48d 100644
--- a/tests/web/WebDriverTest.php
+++ b/tests/web/WebDriverTest.php
@@ -652,6 +652,18 @@ public function testSessionSnapshots()
$this->module->seeCookie('PHPSESSID');
}
+ public function testSessionSnapshotsAreDeleted()
+ {
+ $this->notForPhantomJS();
+ $this->module->amOnPage('/');
+ $this->module->setCookie('PHPSESSID', '123456', ['path' => '/']);
+ $this->module->saveSessionSnapshot('login');
+ $this->webDriver->manage()->deleteAllCookies();
+ $this->module->deleteSessionSnapshot('login');
+ $this->assertFalse($this->module->loadSessionSnapshot('login'));
+ $this->module->dontSeeCookie('PHPSESSID');
+ }
+
public function testSaveSessionSnapshotsExcludeInvalidCookieDomains()
{
$this->notForPhantomJS();
From 10d57842753b281b7f2dd84908de4396c58a5de9 Mon Sep 17 00:00:00 2001
From: Pavel
Date: Mon, 16 Apr 2018 01:03:59 +0300
Subject: [PATCH 037/395] Fixed compatibility with ZF2 ServiceManager (#4934)
---
.../Lib/Connector/ZF2/PersistentServiceManager.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Codeception/Lib/Connector/ZF2/PersistentServiceManager.php b/src/Codeception/Lib/Connector/ZF2/PersistentServiceManager.php
index fe1f1b1e3b..a8952dcd0d 100644
--- a/src/Codeception/Lib/Connector/ZF2/PersistentServiceManager.php
+++ b/src/Codeception/Lib/Connector/ZF2/PersistentServiceManager.php
@@ -17,17 +17,17 @@ public function __construct(ServiceLocatorInterface $serviceManager)
$this->serviceManager = $serviceManager;
}
- public function get($name)
+ public function get($name, $usePeeringServiceManagers = true)
{
if (parent::has($name)) {
- return parent::get($name);
+ return parent::get($name, $usePeeringServiceManagers);
}
return $this->serviceManager->get($name);
}
- public function has($name)
+ public function has($name, $checkAbstractFactories = true, $usePeeringServiceManagers = true)
{
- if (parent::has($name)) {
+ if (parent::has($name, $checkAbstractFactories, $usePeeringServiceManagers)) {
return true;
}
if (preg_match('/doctrine/i', $name)) {
From 5e3530a665ef74519c9c6f8663356d48c9da3d54 Mon Sep 17 00:00:00 2001
From: Wolfgang Kritzinger
Date: Tue, 17 Apr 2018 00:45:55 +1000
Subject: [PATCH 038/395] Restore null check for client in Yii2 (fix #4929)
(#4940)
---
src/Codeception/Module/Yii2.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index 2a240a80b7..c162894a39 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -355,7 +355,7 @@ public function _after(TestInterface $test)
$this->loadedFixtures = [];
}
- if ($this->client->getApplication()->has('session', true)) {
+ if ($this->client !== null && $this->client->getApplication()->has('session', true)) {
$this->client->getApplication()->session->close();
}
parent::_after($test);
From b574ef21a011621dd57b6446a770255566204853 Mon Sep 17 00:00:00 2001
From: Sam
Date: Tue, 17 Apr 2018 11:53:31 +0200
Subject: [PATCH 039/395] Manual app reset (#4928)
* Due to modules keeping references to the client, destructor is not a good place for clean up. Instead manually reset application in _after
* Fix pdoCache never being filled
* Improved garbage collection, fixes #4926
---
src/Codeception/Lib/Connector/Yii2.php | 12 ++----------
src/Codeception/Module/Yii2.php | 4 ++++
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/Codeception/Lib/Connector/Yii2.php b/src/Codeception/Lib/Connector/Yii2.php
index b7c750d006..67e44caf49 100644
--- a/src/Codeception/Lib/Connector/Yii2.php
+++ b/src/Codeception/Lib/Connector/Yii2.php
@@ -96,6 +96,8 @@ public function resetApplication()
\yii\base\Event::offAll();
}
Yii::setLogger(null);
+ // This resolves an issue with database connections not closing properly.
+ gc_collect_cycles();
}
public function startApp()
@@ -284,16 +286,6 @@ protected function mockMailer(array $config)
return $config;
}
- /**
- * A new client is created for every test, it is destroyed after every test.
- * @see InnerBrowser::_after()
- *
- */
- public function __destruct()
- {
- $this->resetApplication();
- }
-
public function restart()
{
parent::restart();
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index c162894a39..d714b18ad0 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -358,6 +358,8 @@ public function _after(TestInterface $test)
if ($this->client !== null && $this->client->getApplication()->has('session', true)) {
$this->client->getApplication()->session->close();
}
+
+ $this->client->resetApplication();
parent::_after($test);
}
@@ -385,6 +387,8 @@ public function connectionOpenHandler(Event $event)
*/
if (isset($this->pdoCache[$key])) {
$connection->pdo = $this->pdoCache[$key];
+ } else {
+ $this->pdoCache[$key] = $connection->pdo;
}
if (isset($this->dsnCache[$connection->dsn])
From 0e91291e22b1dd4ac526f05fda7c5a91e5462e2c Mon Sep 17 00:00:00 2001
From: bscheshirwork
Date: Fri, 20 Apr 2018 12:53:56 +0300
Subject: [PATCH 040/395] remove typehint for php7 compability (#4937)
---
src/Codeception/Event/FailEvent.php | 2 +-
src/Codeception/Subscriber/Console.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Codeception/Event/FailEvent.php b/src/Codeception/Event/FailEvent.php
index 372411ce43..0f64570b74 100644
--- a/src/Codeception/Event/FailEvent.php
+++ b/src/Codeception/Event/FailEvent.php
@@ -13,7 +13,7 @@ class FailEvent extends TestEvent
*/
protected $count;
- public function __construct(\PHPUnit\Framework\Test $test, $time, \Exception $e, $count = 0)
+ public function __construct(\PHPUnit\Framework\Test $test, $time, $e, $count = 0)
{
parent::__construct($test, $time);
$this->fail = $e;
diff --git a/src/Codeception/Subscriber/Console.php b/src/Codeception/Subscriber/Console.php
index 22b38b8d63..081d7ac0cb 100644
--- a/src/Codeception/Subscriber/Console.php
+++ b/src/Codeception/Subscriber/Console.php
@@ -441,7 +441,7 @@ public function printScenarioFail(ScenarioDriven $failedTest, $fail)
}
}
- public function printExceptionTrace(\Exception $e)
+ public function printExceptionTrace($e)
{
static $limit = 10;
From b23e8be85e50919d898d3f7d669445ed33273e0d Mon Sep 17 00:00:00 2001
From: Filippo Tessarotto
Date: Fri, 20 Apr 2018 11:54:57 +0200
Subject: [PATCH 041/395] Verbose fail message when no Exception caught (#4933)
---
src/Codeception/Module/Asserts.php | 4 ++--
tests/unit/Codeception/Module/AssertsTest.php | 11 +++++++++++
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/Codeception/Module/Asserts.php b/src/Codeception/Module/Asserts.php
index 69fb64a82c..6bb7927ebc 100644
--- a/src/Codeception/Module/Asserts.php
+++ b/src/Codeception/Module/Asserts.php
@@ -465,8 +465,8 @@ public function expectException($exception, $callback)
));
}
$this->assertTrue(true); // increment assertion counter
- return;
+ return;
}
- $this->fail("Expected exception to be thrown, but nothing was caught");
+ $this->fail("Expected exception of $class to be thrown, but nothing was caught");
}
}
diff --git a/tests/unit/Codeception/Module/AssertsTest.php b/tests/unit/Codeception/Module/AssertsTest.php
index cba9cd9c48..5d71f3b152 100644
--- a/tests/unit/Codeception/Module/AssertsTest.php
+++ b/tests/unit/Codeception/Module/AssertsTest.php
@@ -53,4 +53,15 @@ public function testExceptionFails()
throw new Exception('here', 2);
});
}
+
+ /**
+ * @expectedException PHPUnit\Framework\AssertionFailedError
+ * @expectedExceptionMessageRegExp /RuntimeException/
+ */
+ public function testOutputExceptionTimeWhenNothingCaught()
+ {
+ $module = new \Codeception\Module\Asserts(make_container());
+ $module->expectException(RuntimeException::class, function () {
+ });
+ }
}
From db8a3bbc389fb85375100f2bcd38aa4798d13ee7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Barou=C5=A1?=
Date: Fri, 20 Apr 2018 12:44:31 +0200
Subject: [PATCH 042/395] Makes JsonArray convert all decoded non-arrays to
array (#4946)
Also adds test covering this case.
Issue on GitHub: Codeception/Codeception#4944
---
src/Codeception/Util/JsonArray.php | 8 +++++++-
tests/unit/Codeception/Util/JsonArrayTest.php | 9 +++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/Codeception/Util/JsonArray.php b/src/Codeception/Util/JsonArray.php
index 279f257487..6b2d553271 100644
--- a/src/Codeception/Util/JsonArray.php
+++ b/src/Codeception/Util/JsonArray.php
@@ -23,7 +23,13 @@ public function __construct($jsonString)
throw new InvalidArgumentException('$jsonString param must be a string.');
}
- $this->jsonArray = json_decode($jsonString, true);
+ $jsonDecode = json_decode($jsonString, true);
+
+ if (!is_array($jsonDecode)) {
+ $jsonDecode = [$jsonDecode];
+ }
+
+ $this->jsonArray = $jsonDecode;
if (JSON_ERROR_NONE !== json_last_error()) {
throw new InvalidArgumentException(
diff --git a/tests/unit/Codeception/Util/JsonArrayTest.php b/tests/unit/Codeception/Util/JsonArrayTest.php
index 5907bc7359..6e0dfcf774 100644
--- a/tests/unit/Codeception/Util/JsonArrayTest.php
+++ b/tests/unit/Codeception/Util/JsonArrayTest.php
@@ -59,6 +59,15 @@ public function testThrowsInvalidArgumentExceptionIfJsonIsInvalid()
new JsonArray('{"test":');
}
+ /**
+ * @issue https://github.com/Codeception/Codeception/issues/4944
+ */
+ public function testConvertsBareJson()
+ {
+ $jsonArray = new JsonArray('"I am a {string}."');
+ $this->assertEquals(['I am a {string}.'], $jsonArray->toArray());
+ }
+
/**
* @Issue https://github.com/Codeception/Codeception/issues/2899
*/
From f29f457f3bc3cd7a6a2b9fc2153f34dc8c3fbcf1 Mon Sep 17 00:00:00 2001
From: Gabriel Caruso
Date: Mon, 23 Apr 2018 15:00:44 -0300
Subject: [PATCH 043/395] Use dedicated PHPUnit assertions (#4950)
---
src/Codeception/Module/Memcache.php | 4 +-
src/Codeception/Module/REST.php | 2 +-
tests/unit/Codeception/Module/TestsForWeb.php | 40 +++++++++----------
tests/unit/Codeception/Util/JsonArrayTest.php | 6 +--
4 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/src/Codeception/Module/Memcache.php b/src/Codeception/Module/Memcache.php
index f46ba0517b..69ce2e01ac 100644
--- a/src/Codeception/Module/Memcache.php
+++ b/src/Codeception/Module/Memcache.php
@@ -139,7 +139,7 @@ public function seeInMemcached($key, $value = null)
$this->debugSection("Value", $actual);
if (null === $value) {
- $this->assertTrue(false !== $actual, "Cannot find key '$key' in Memcached");
+ $this->assertNotFalse($actual, "Cannot find key '$key' in Memcached");
} else {
$this->assertEquals($value, $actual, "Cannot find key '$key' in Memcached with the provided value");
}
@@ -169,7 +169,7 @@ public function dontSeeInMemcached($key, $value = null)
$this->debugSection("Value", $actual);
if (null === $value) {
- $this->assertTrue(false === $actual, "The key '$key' exists in Memcached");
+ $this->assertFalse($actual, "The key '$key' exists in Memcached");
} else {
if (false !== $actual) {
$this->assertEquals($value, $actual, "The key '$key' exists in Memcached with the provided value");
diff --git a/src/Codeception/Module/REST.php b/src/Codeception/Module/REST.php
index aff9d2b5a0..3f1db8c6b5 100644
--- a/src/Codeception/Module/REST.php
+++ b/src/Codeception/Module/REST.php
@@ -241,7 +241,7 @@ public function dontSeeHttpHeader($name, $value = null)
public function seeHttpHeaderOnce($name)
{
$headers = $this->getRunningClient()->getInternalResponse()->getHeader($name, false);
- $this->assertEquals(1, count($headers));
+ $this->assertCount(1, $headers);
}
/**
diff --git a/tests/unit/Codeception/Module/TestsForWeb.php b/tests/unit/Codeception/Module/TestsForWeb.php
index 02ede2d14a..a37976582e 100644
--- a/tests/unit/Codeception/Module/TestsForWeb.php
+++ b/tests/unit/Codeception/Module/TestsForWeb.php
@@ -1042,10 +1042,10 @@ public function testSubmitForm()
$form = data::get('form');
$this->assertEquals('Davert', $form['name']);
$this->assertEquals('Is Codeception maintainer', $form['description']);
- $this->assertFalse(isset($form['disabled_fieldset']));
- $this->assertFalse(isset($form['disabled_fieldset_textarea']));
- $this->assertFalse(isset($form['disabled_fieldset_select']));
- $this->assertFalse(isset($form['disabled_field']));
+ $this->assertArrayNotHasKey('disabled_fieldset', $form);
+ $this->assertArrayNotHasKey('disabled_fieldset_textarea', $form);
+ $this->assertArrayNotHasKey('disabled_fieldset_select', $form);
+ $this->assertArrayNotHasKey('disabled_field', $form);
$this->assertEquals('kill_all', $form['action']);
}
@@ -1209,8 +1209,8 @@ public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValue()
$this->module->seeElement("#button2");
$this->module->click("#button2");
$form = data::get('form');
- $this->assertTrue(isset($form['button2']));
- $this->assertTrue(isset($form['username']));
+ $this->assertArrayHasKey('button2', $form);
+ $this->assertArrayHasKey('username', $form);
$this->assertEquals('value2', $form['button2']);
$this->assertEquals('fred', $form['username']);
}
@@ -1224,8 +1224,8 @@ public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValueAfterFillFi
$this->module->fillField("username", "bob");
$this->module->click("#button2");
$form = data::get('form');
- $this->assertTrue(isset($form['button2']));
- $this->assertTrue(isset($form['username']));
+ $this->assertArrayHasKey('button2', $form);
+ $this->assertArrayHasKey('username', $form);
$this->assertEquals('value2', $form['button2']);
$this->assertEquals('bob', $form['username']);
}
@@ -1268,8 +1268,8 @@ public function testSubmitFormWithDefaultRadioAndCheckboxValues()
'test' => 'value'
));
$form = data::get('form');
- $this->assertTrue(isset($form['checkbox1']), 'Checkbox value not sent');
- $this->assertTrue(isset($form['radio1']), 'Radio button value not sent');
+ $this->assertArrayHasKey('checkbox1', $form, 'Checkbox value not sent');
+ $this->assertArrayHasKey('radio1', $form, 'Radio button value not sent');
$this->assertEquals('testing', $form['checkbox1']);
$this->assertEquals('to be sent', $form['radio1']);
}
@@ -1281,7 +1281,7 @@ public function testSubmitFormCheckboxWithBoolean()
'checkbox1' => true
));
$form = data::get('form');
- $this->assertTrue(isset($form['checkbox1']), 'Checkbox value not sent');
+ $this->assertArrayHasKey('checkbox1', $form, 'Checkbox value not sent');
$this->assertEquals('testing', $form['checkbox1']);
$this->module->amOnPage('/form/example16');
@@ -1289,7 +1289,7 @@ public function testSubmitFormCheckboxWithBoolean()
'checkbox1' => false
));
$form = data::get('form');
- $this->assertFalse(isset($form['checkbox1']), 'Checkbox value sent');
+ $this->assertArrayNotHasKey('checkbox1', $form, 'Checkbox value sent');
}
public function testSubmitFormWithCheckboxesWithoutValue()
@@ -1320,7 +1320,7 @@ public function testSubmitFormWithButtons()
isset($form['button1']) || isset($form['button2']) || isset($form['button4']),
'Button values for buttons 1, 2 and 4 should not be set'
);
- $this->assertTrue(isset($form['button3']), 'Button value for button3 should be set');
+ $this->assertArrayHasKey('button3', $form, 'Button value for button3 should be set');
$this->assertEquals($form['button3'], 'third', 'Button value for button3 should equal third');
$this->module->amOnPage('/form/form_with_buttons');
@@ -1332,7 +1332,7 @@ public function testSubmitFormWithButtons()
isset($form['button1']) || isset($form['button2']) || isset($form['button3']),
'Button values for buttons 1, 2 and 3 should not be set'
);
- $this->assertTrue(isset($form['button4']), 'Button value for button4 should be set');
+ $this->assertArrayHasKey('button4', $form, 'Button value for button4 should be set');
$this->assertEquals($form['button4'], 'fourth', 'Button value for button4 should equal fourth');
}
@@ -1441,8 +1441,8 @@ public function testSubmitAdjacentForms()
$this->module->amOnPage('/form/submit_adjacentforms');
$this->module->submitForm('#form-2', []);
$data = data::get('form');
- $this->assertTrue(isset($data['second-field']));
- $this->assertFalse(isset($data['first-field']));
+ $this->assertArrayHasKey('second-field', $data);
+ $this->assertArrayNotHasKey('first-field', $data);
$this->assertEquals('Killgore Trout', $data['second-field']);
}
@@ -1453,8 +1453,8 @@ public function testSubmitAdjacentFormsByButton()
$this->module->fillField('second-field', 'Second');
$this->module->click('#submit1');
$data = data::get('form');
- $this->assertTrue(isset($data['first-field']));
- $this->assertFalse(isset($data['second-field']));
+ $this->assertArrayHasKey('first-field', $data);
+ $this->assertArrayNotHasKey('second-field', $data);
$this->assertEquals('First', $data['first-field']);
$this->module->amOnPage('/form/submit_adjacentforms');
@@ -1462,8 +1462,8 @@ public function testSubmitAdjacentFormsByButton()
$this->module->fillField('second-field', 'Second');
$this->module->click('#submit2');
$data = data::get('form');
- $this->assertFalse(isset($data['first-field']));
- $this->assertTrue(isset($data['second-field']));
+ $this->assertArrayNotHasKey('first-field', $data);
+ $this->assertArrayHasKey('second-field', $data);
$this->assertEquals('Second', $data['second-field']);
}
diff --git a/tests/unit/Codeception/Util/JsonArrayTest.php b/tests/unit/Codeception/Util/JsonArrayTest.php
index 6e0dfcf774..a2dbcedd24 100644
--- a/tests/unit/Codeception/Util/JsonArrayTest.php
+++ b/tests/unit/Codeception/Util/JsonArrayTest.php
@@ -36,9 +36,9 @@ public function testXmlArrayConversion2()
public function testXPathLocation()
{
- $this->assertTrue($this->jsonArray->filterByXPath('//ticket/title')->length > 0);
- $this->assertTrue($this->jsonArray->filterByXPath('//ticket/user/name')->length > 0);
- $this->assertTrue($this->jsonArray->filterByXPath('//user/name')->length > 0);
+ $this->assertGreaterThan(0, $this->jsonArray->filterByXPath('//ticket/title')->length);
+ $this->assertGreaterThan(0, $this->jsonArray->filterByXPath('//ticket/user/name')->length);
+ $this->assertGreaterThan(0, $this->jsonArray->filterByXPath('//user/name')->length);
}
public function testJsonPathLocation()
From 39a510f9646f5d0d54228a11ec3f7a0f2a9a7b61 Mon Sep 17 00:00:00 2001
From: Gintautas Miselis
Date: Mon, 30 Apr 2018 19:17:19 +0100
Subject: [PATCH 044/395] WebDriverTest: fixed incorrect assertion (#4957)
---
tests/web/WebDriverTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/web/WebDriverTest.php b/tests/web/WebDriverTest.php
index 85e9f6a48d..f220463a2e 100644
--- a/tests/web/WebDriverTest.php
+++ b/tests/web/WebDriverTest.php
@@ -1116,6 +1116,6 @@ public function testChangingCapabilities()
});
$this->assertNotTrue($this->module->webDriver->getCapabilities()->getCapability('acceptInsecureCerts'));
$this->module->_initializeSession();
- $this->assertTrue(true, $this->module->webDriver->getCapabilities()->getCapability('acceptInsecureCerts'));
+ $this->assertTrue($this->module->webDriver->getCapabilities()->getCapability('acceptInsecureCerts'));
}
}
From d29f0e1e77ad709e07b42d1b6be6d3c65d8fbbd0 Mon Sep 17 00:00:00 2001
From: Jack Robbers <31850261+JackRobbers@users.noreply.github.com>
Date: Tue, 1 May 2018 05:36:19 +1000
Subject: [PATCH 045/395] Fix broken links to code in customisation docs
(#4951)
---
docs/08-Customization.md | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/docs/08-Customization.md b/docs/08-Customization.md
index 22e1d2f021..2abd32b29a 100644
--- a/docs/08-Customization.md
+++ b/docs/08-Customization.md
@@ -95,29 +95,29 @@ All listed events are available as constants in `Codeception\Events` class.
| Event | When? | Triggered by
|:--------------------:| --------------------------------------- | --------------------------:
-| `suite.before` | Before suite is executed | [Suite, Settings](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/SuiteEvent.php)
-| `test.start` | Before test is executed | [Test](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/TestEvent.php)
-| `test.before` | At the very beginning of test execution | [Codeception Test](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/TestEvent.php)
-| `step.before` | Before step | [Step](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/StepEvent.php)
-| `step.after` | After step | [Step](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/StepEvent.php)
-| `step.fail` | After failed step | [Step](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/StepEvent.php)
-| `test.fail` | After failed test | [Test, Fail](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/FailEvent.php)
-| `test.error` | After test ended with error | [Test, Fail](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/FailEvent.php)
-| `test.incomplete` | After executing incomplete test | [Test, Fail](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/FailEvent.php)
-| `test.skipped` | After executing skipped test | [Test, Fail](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/FailEvent.php)
-| `test.success` | After executing successful test | [Test](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/TestEvent.php)
-| `test.after` | At the end of test execution | [Codeception Test](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/TestEvent.php)
-| `test.end` | After test execution | [Test](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/TestEvent.php)
-| `suite.after` | After suite was executed | [Suite, Result, Settings](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/SuiteEvent.php)
-| `test.fail.print` | When test fails are printed | [Test, Fail](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/FailEvent.php)
-| `result.print.after` | After result was printed | [Result, Printer](https://github.com/Codeception/Codeception/blob/master/src/Codeception/Event/PrintResultEvent.php)
+| `suite.before` | Before suite is executed | [Suite, Settings](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/SuiteEvent.php)
+| `test.start` | Before test is executed | [Test](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/TestEvent.php)
+| `test.before` | At the very beginning of test execution | [Codeception Test](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/TestEvent.php)
+| `step.before` | Before step | [Step](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/StepEvent.php)
+| `step.after` | After step | [Step](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/StepEvent.php)
+| `step.fail` | After failed step | [Step](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/StepEvent.php)
+| `test.fail` | After failed test | [Test, Fail](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/FailEvent.php)
+| `test.error` | After test ended with error | [Test, Fail](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/FailEvent.php)
+| `test.incomplete` | After executing incomplete test | [Test, Fail](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/FailEvent.php)
+| `test.skipped` | After executing skipped test | [Test, Fail](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/FailEvent.php)
+| `test.success` | After executing successful test | [Test](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/TestEvent.php)
+| `test.after` | At the end of test execution | [Codeception Test](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/TestEvent.php)
+| `test.end` | After test execution | [Test](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/TestEvent.php)
+| `suite.after` | After suite was executed | [Suite, Result, Settings](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/SuiteEvent.php)
+| `test.fail.print` | When test fails are printed | [Test, Fail](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/FailEvent.php)
+| `result.print.after` | After result was printed | [Result, Printer](https://github.com/Codeception/Codeception/blob/2.4/src/Codeception/Event/PrintResultEvent.php)
There may be some confusion between `test.start`/`test.before` and `test.after`/`test.end`.
The start and end events are triggered by PHPUnit, but the before and after events are triggered by Codeception.
Thus, when you are using classical PHPUnit tests (extended from `PHPUnit\Framework\TestCase`),
the before/after events won't be triggered for them. During the `test.before` event you can mark a test
as skipped or incomplete, which is not possible in `test.start`. You can learn more from
-[Codeception internal event listeners](https://github.com/Codeception/Codeception/tree/master/src/Codeception/Subscriber).
+[Codeception internal event listeners](https://github.com/Codeception/Codeception/tree/2.4/src/Codeception/Subscriber).
The extension class itself is inherited from `Codeception\Extension`:
From df7f10a35f8223f1e92c73e3409dc8b82faa4900 Mon Sep 17 00:00:00 2001
From: Pavel
Date: Mon, 30 Apr 2018 22:48:45 +0300
Subject: [PATCH 046/395] Added support for custom kernel names for Symfony
(#4949)
---
src/Codeception/Module/Symfony.php | 38 ++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php
index 3009434a6c..2ceab3dbcc 100644
--- a/src/Codeception/Module/Symfony.php
+++ b/src/Codeception/Module/Symfony.php
@@ -1,7 +1,9 @@
'app',
'var_path' => 'app',
+ 'kernel_class' => null,
'environment' => 'test',
'debug' => true,
'cache_router' => false,
@@ -284,10 +295,8 @@ protected function getKernelClass()
require_once $file;
- $possibleKernelClasses = [
- 'AppKernel', // Symfony Standard
- 'App\Kernel', // Symfony Flex
- ];
+ $possibleKernelClasses = $this->getPossibleKernelClasses();
+
foreach ($possibleKernelClasses as $class) {
if (class_exists($class)) {
$refClass = new \ReflectionClass($class);
@@ -624,4 +633,25 @@ private function dataRevealsValue(Data $data)
{
return method_exists($data, 'getValue');
}
+
+ /**
+ * Returns list of the possible kernel classes based on the module configuration
+ *
+ * @return array
+ */
+ private function getPossibleKernelClasses()
+ {
+ if (empty($this->config['kernel_class'])) {
+ return self::$possibleKernelClasses;
+ }
+
+ if (!is_string($this->config['kernel_class'])) {
+ throw new ModuleException(
+ __CLASS__,
+ "Parameter 'kernel_class' must have 'string' type.\n"
+ );
+ }
+
+ return [$this->config['kernel_class']];
+ }
}
From 604e62c191f51363c69246b8082767ca60364ac5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9?=
Date: Mon, 30 Apr 2018 21:51:12 +0200
Subject: [PATCH 047/395] Added dochead for grabFromDatabase (#4945)
Added dochead for proceedSeeInDatabase
---
src/Codeception/Module/Db.php | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/Codeception/Module/Db.php b/src/Codeception/Module/Db.php
index e48ff7156f..2e372a8f44 100644
--- a/src/Codeception/Module/Db.php
+++ b/src/Codeception/Module/Db.php
@@ -534,6 +534,16 @@ protected function countInDatabase($table, array $criteria = [])
return (int) $this->proceedSeeInDatabase($table, 'count(*)', $criteria);
}
+ /**
+ * Fetches all values from the column in database.
+ * Provide table name, desired column and criteria.
+ *
+ * @param string $table
+ * @param string $column
+ * @param array $criteria
+ *
+ * @return array
+ */
protected function proceedSeeInDatabase($table, $column, $criteria)
{
$query = $this->driver->select($column, $table, $criteria);
@@ -573,6 +583,21 @@ public function grabColumnFromDatabase($table, $column, array $criteria = [])
return $sth->fetchAll(\PDO::FETCH_COLUMN, 0);
}
+ /**
+ * Fetches all values from the column in database.
+ * Provide table name, desired column and criteria.
+ *
+ * ``` php
+ * grabFromDatabase('users', 'email', array('name' => 'RebOOter'));
+ * ```
+ *
+ * @param string $table
+ * @param string $column
+ * @param array $criteria
+ *
+ * @return array
+ */
public function grabFromDatabase($table, $column, $criteria = [])
{
return $this->proceedSeeInDatabase($table, $column, $criteria);
From c498dcb30f8c884a4b487b960297901640c7f7ea Mon Sep 17 00:00:00 2001
From: Dmitry Naumenko
Date: Thu, 3 May 2018 16:09:26 +0300
Subject: [PATCH 048/395] Handle absolute paths in ParamsLoader properly
(#4960)
---
src/Codeception/Lib/ParamsLoader.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Codeception/Lib/ParamsLoader.php b/src/Codeception/Lib/ParamsLoader.php
index 309334ad8e..ce60a4d147 100644
--- a/src/Codeception/Lib/ParamsLoader.php
+++ b/src/Codeception/Lib/ParamsLoader.php
@@ -22,7 +22,7 @@ public function load($paramStorage)
return $this->loadEnvironmentVars();
}
- $this->paramsFile = codecept_root_dir($paramStorage);
+ $this->paramsFile = $paramStorage[0] === '/' ? $paramStorage : codecept_root_dir($paramStorage);
if (!file_exists($this->paramsFile)) {
throw new ConfigurationException("Params file {$this->paramsFile} not found");
}
From fd45d579f0f50ba2d664b23438ed44947fe67751 Mon Sep 17 00:00:00 2001
From: Adrian Skierniewski
Date: Wed, 16 May 2018 23:19:15 +0200
Subject: [PATCH 049/395] Fix memory leak when using Laravel factories inside
Codeception (#4971)
---
src/Codeception/Module/Laravel5.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/Codeception/Module/Laravel5.php b/src/Codeception/Module/Laravel5.php
index e97f536b95..54357d3cb8 100644
--- a/src/Codeception/Module/Laravel5.php
+++ b/src/Codeception/Module/Laravel5.php
@@ -217,6 +217,10 @@ public function _after(\Codeception\TestInterface $test)
$connection->disconnect();
}
}
+
+ // Remove references to Faker in factories to prevent memory leak
+ unset($this->app[\Faker\Generator::class]);
+ unset($this->app[\Illuminate\Database\Eloquent\Factory::class]);
}
}
From 889a32ff7b57cb3881d906e87ab189a0a25fafd5 Mon Sep 17 00:00:00 2001
From: philek
Date: Sat, 26 May 2018 02:26:44 +0200
Subject: [PATCH 050/395] added support for null (#4987)
---
src/Codeception/Lib/Driver/SqlSrv.php | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/Codeception/Lib/Driver/SqlSrv.php b/src/Codeception/Lib/Driver/SqlSrv.php
index b0858d5530..5d4fbbc89e 100644
--- a/src/Codeception/Lib/Driver/SqlSrv.php
+++ b/src/Codeception/Lib/Driver/SqlSrv.php
@@ -56,6 +56,12 @@ protected function generateWhereClause(array &$criteria)
$params = [];
foreach ($criteria as $k => $v) {
+ if ($v === null) {
+ $params[] = $this->getQuotedName($k) . " IS NULL ";
+ unset($criteria[$k]);
+ continue;
+ }
+
if (strpos(strtolower($k), ' like') > 0) {
$k = str_replace(' like', '', strtolower($k));
$params[] = $this->getQuotedName($k) . " LIKE ? ";
From 4364068d81b9d44dc56849d3812335a88de5d454 Mon Sep 17 00:00:00 2001
From: Dmytro Naumenko
Date: Sat, 26 May 2018 03:31:53 +0300
Subject: [PATCH 051/395] Respect absolute paths in Yii2 module (#4961)
* Respect absoulte paths in Yii2 module
* Added codecept_absolute_path function
* Added CHANGELOG
* Use codecept_absolute_path() in ParamsLoader
---
CHANGELOG-2.4.md | 2 ++
autoload.php | 15 +++++++++++++++
src/Codeception/Lib/ParamsLoader.php | 2 +-
src/Codeception/Module/Yii2.php | 10 ++++++----
4 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 4a6bec80a9..4ddcba25cd 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -12,6 +12,8 @@
* Fixtures method is now configurable
* Subset of misconfigurations are now detected and informative messages created
* Fixed using `$settings['path']` in `Codeception\Configuration::suiteSettings()` on Windows by @olegpro
+* **Breaking** `$settings['configFile']` now supports absolute paths. In you have defined relative path to config in absolute manner
+(starting with `/`), you must change it. @silverfire
* [Laravel5] Added Laravel 5.4+ (5.1+ backward compatible) support for `callArtisan` method in Laravel5 module. See #4860 by @mohamed-aiman
* Fixed #4854: unnecessary escaping in operation arguments logging by @nicholascus
* Fixed humanizing steps for utf8 strings by @nicholascus. See #4850
diff --git a/autoload.php b/autoload.php
index 61b67589d9..ee043a39b6 100644
--- a/autoload.php
+++ b/autoload.php
@@ -101,3 +101,18 @@ function codecept_relative_path($path)
);
}
}
+
+if (!function_exists('codecept_absolute_path')) {
+ /**
+ * If $path is absolute, it will be returned without changes.
+ * If $path is relative, it will be passed to `codecept_root_dir()` function
+ * to make it absolute.
+ *
+ * @param string $path
+ * @return string the absolute path
+ */
+ function codecept_absolute_path($path)
+ {
+ return mb_substr($path, 0, 1) === DIRECTORY_SEPARATOR ? $path : codecept_root_dir($path);
+ }
+}
diff --git a/src/Codeception/Lib/ParamsLoader.php b/src/Codeception/Lib/ParamsLoader.php
index ce60a4d147..b863c6dd5a 100644
--- a/src/Codeception/Lib/ParamsLoader.php
+++ b/src/Codeception/Lib/ParamsLoader.php
@@ -22,7 +22,7 @@ public function load($paramStorage)
return $this->loadEnvironmentVars();
}
- $this->paramsFile = $paramStorage[0] === '/' ? $paramStorage : codecept_root_dir($paramStorage);
+ $this->paramsFile = codecept_absolute_path($paramStorage);
if (!file_exists($this->paramsFile)) {
throw new ConfigurationException("Params file {$this->paramsFile} not found");
}
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index d714b18ad0..213e2b8983 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -53,7 +53,7 @@
* modules:
* enabled:
* - Yii2:
- * configFile: '/path/to/config.php'
+ * configFile: 'path/to/config.php'
* ```
*
* ### Parts
@@ -238,10 +238,12 @@ private function initServerGlobal()
protected function validateConfig()
{
parent::validateConfig();
- if (!is_file(Configuration::projectDir() . $this->config['configFile'])) {
+
+ $pathToConfig = codecept_absolute_path($this->config['configFile']);
+ if (!is_file($pathToConfig)) {
throw new ModuleConfigException(
__CLASS__,
- "The application config file does not exist: " . Configuration::projectDir() . $this->config['configFile']
+ "The application config file does not exist: " . $pathToConfig
);
}
@@ -262,7 +264,7 @@ protected function validateConfig()
protected function configureClient(array $settings)
{
- $settings['configFile'] = Configuration::projectDir() . $settings['configFile'];
+ $settings['configFile'] = codecept_absolute_path($settings['configFile']);
foreach ($settings as $key => $value) {
if (property_exists($this->client, $key)) {
From 8b3e3b4e03217bb11e3a1af87aa2005e5e3d2c19 Mon Sep 17 00:00:00 2001
From: Gintautas Miselis
Date: Sat, 26 May 2018 01:45:55 +0100
Subject: [PATCH 052/395] Stub 2.0 (#4981)
I released Stub 2.0, because the change is incompatible with Codeception 2.3
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index fbb47559f5..03397bf643 100644
--- a/composer.json
+++ b/composer.json
@@ -30,7 +30,7 @@
"symfony/dom-crawler": ">=2.7 <5.0",
"behat/gherkin": "^4.4.0",
"codeception/phpunit-wrapper": "^6.0.9|^7.0.6",
- "codeception/stub": "^1.0"
+ "codeception/stub": "^2.0"
},
"require-dev": {
"monolog/monolog": "~1.8",
From e7ef7a2d99f0d62dc282d4d12250b9eb0e177e14 Mon Sep 17 00:00:00 2001
From: Michail
Date: Sat, 26 May 2018 22:27:24 +0300
Subject: [PATCH 053/395] Fix error on single file test: headers already sent
(#4986)
Notice: Undefined index: tests in Codeception\Command\Run.php on line 389
---
src/Codeception/Command/Run.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Codeception/Command/Run.php b/src/Codeception/Command/Run.php
index 1ef490ba80..a6686f641b 100644
--- a/src/Codeception/Command/Run.php
+++ b/src/Codeception/Command/Run.php
@@ -386,7 +386,7 @@ protected function matchSingleTest($suite, $config)
{
// Workaround when codeception.yml is inside tests directory and tests path is set to "."
// @see https://github.com/Codeception/Codeception/issues/4432
- if ($config['paths']['tests'] === '.' && !preg_match('~^\.[/\\\]~', $suite)) {
+ if (isset($config['paths']['tests']) && $config['paths']['tests'] === '.' && !preg_match('~^\.[/\\\]~', $suite)) {
$suite = './' . $suite;
}
From 8fa27b72a3d3ad75f0dd456c24730c15cae07dff Mon Sep 17 00:00:00 2001
From: Johannes Schobel
Date: Sat, 26 May 2018 21:48:01 +0200
Subject: [PATCH 054/395] Features: Allow PRESETs for codeception and suite
config files (#4984)
* feature to load presetfile in main codeception file
* same for the suites
* add tests
* changelog and docs
* change presetfile to extends
---
CHANGELOG-2.4.md | 3 ++
docs/reference/Configuration.md | 3 +-
src/Codeception/Configuration.php | 32 +++++++++++++++----
tests/cli/ConfigWithPresetsCest.php | 12 +++++++
.../presets/_presets/preset.codeception.yml | 10 ++++++
.../presets/_presets/preset.unit.suite.yml | 3 ++
tests/data/presets/codeception.yml | 1 +
tests/data/presets/codeception_2.yml | 1 +
.../presets/tests/_support/DummyTester.php | 26 +++++++++++++++
.../presets/tests/_support/Helper/Dummy.php | 27 ++++++++++++++++
.../tests/_support/_generated/.gitignore | 1 +
tests/data/presets/tests/unit.suite.yml | 2 ++
tests/data/presets/tests/unit/PresetTest.php | 11 +++++++
13 files changed, 125 insertions(+), 7 deletions(-)
create mode 100644 tests/cli/ConfigWithPresetsCest.php
create mode 100644 tests/data/presets/_presets/preset.codeception.yml
create mode 100644 tests/data/presets/_presets/preset.unit.suite.yml
create mode 100644 tests/data/presets/codeception.yml
create mode 100644 tests/data/presets/codeception_2.yml
create mode 100644 tests/data/presets/tests/_support/DummyTester.php
create mode 100644 tests/data/presets/tests/_support/Helper/Dummy.php
create mode 100644 tests/data/presets/tests/_support/_generated/.gitignore
create mode 100644 tests/data/presets/tests/unit.suite.yml
create mode 100644 tests/data/presets/tests/unit/PresetTest.php
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 4ddcba25cd..46eca2907a 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -1,3 +1,6 @@
+#### 2.4.2
+* Added support for `extends` in the `codeception.yml` and `*.suite.yml` files; by @johannesschobel
+
#### 2.4.1
* Fixed "Uncaught Error: Call to undefined method Codeception\Test\Descriptor::getTestDataSetIndex()" error when filtering tests.
diff --git a/docs/reference/Configuration.md b/docs/reference/Configuration.md
index c00ecb8ace..41c068a1f1 100644
--- a/docs/reference/Configuration.md
+++ b/docs/reference/Configuration.md
@@ -93,7 +93,7 @@ modules:
password: ''
dump: tests/_data/dump.sql
```
-
+* `extends`: allows you to specify a file (relative to the `codeception.yml` file) that holds some already pre-defined values. This can be used to always use the same configuration for modules or whatever.
* `extensions`: allows to enable and configure [Codeception extensions](http://codeception.com/docs/08-Customization#Extension), [Group Objects](http://codeception.com/docs/08-Customization#Group-Objects), and [Custom Commands](http://codeception.com/docs/08-Customization#Custom-Commands).
* `reporters`: allows to [change default reporters](http://codeception.com/docs/08-Customization#Custom-Reporters) of Codeception
* `coverage`: [CodeCoverage](http://codeception.com/docs/11-Codecoverage#Configuration) settings.
@@ -134,6 +134,7 @@ modules:
```
+* `extends`: allows you to specify a file (relative to the `*.suite.yml` file) that holds some already pre-defined values. This can be used to always use the same configuration for modules or whatever.
* `namespace`: default namespace of actor, support classes and tests.
* `suite_namespace`: default namespace for new tests of this suite (ignores `namespace` option)
* `env`: override any configuration per [environment](http://codeception.com/docs/07-AdvancedUsage#Environments).
diff --git a/src/Codeception/Configuration.php b/src/Codeception/Configuration.php
index e5ebe96402..8914191403 100644
--- a/src/Codeception/Configuration.php
+++ b/src/Codeception/Configuration.php
@@ -69,6 +69,7 @@ class Configuration
'namespace' => '',
'include' => [],
'paths' => [],
+ 'extends' => null,
'suites' => [],
'modules' => [],
'extensions' => [
@@ -109,6 +110,7 @@ class Configuration
'depends' => []
],
'path' => null,
+ 'extends' => null,
'namespace' => null,
'groups' => [],
'shuffle' => false,
@@ -180,6 +182,16 @@ public static function config($configFile = null)
throw new ConfigurationException("Configuration file is invalid");
}
+ // we check for the "extends" key in the yml file
+ if (isset($config['extends'])) {
+ // and now we search for the file
+ $presetFilePath = realpath(self::$dir . DIRECTORY_SEPARATOR . $config['extends']);
+ if (file_exists($presetFilePath)) {
+ // and merge it with our configuration file
+ $config = self::mergeConfigs(self::getConfFromFile($presetFilePath), $config);
+ }
+ }
+
self::$config = $config;
// compatibility with suites created by Codeception < 2.3.0
@@ -670,14 +682,22 @@ protected static function loadSuiteConfig($suite, $path, $settings)
return self::mergeConfigs($settings, self::$config['suites'][$suite]);
}
- $suiteDistConf = self::getConfFromFile(
- self::$dir . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . "$suite.suite.dist.yml"
- );
- $suiteConf = self::getConfFromFile(
- self::$dir . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . "$suite.suite.yml"
- );
+ $suiteDir = self::$dir . DIRECTORY_SEPARATOR . $path;
+
+ $suiteDistConf = self::getConfFromFile($suiteDir . DIRECTORY_SEPARATOR . "$suite.suite.dist.yml");
+ $suiteConf = self::getConfFromFile($suiteDir . DIRECTORY_SEPARATOR . "$suite.suite.yml");
+
+ // now we check the suite config file, if a extends key is defined
+ if (isset($suiteConf['extends'])) {
+ $presetFilePath = realpath($suiteDir . DIRECTORY_SEPARATOR . $suiteConf['extends']);
+ if (file_exists($presetFilePath)) {
+ $settings = self::mergeConfigs(self::getConfFromFile($presetFilePath), $settings);
+ }
+ }
+
$settings = self::mergeConfigs($settings, $suiteDistConf);
$settings = self::mergeConfigs($settings, $suiteConf);
+
return $settings;
}
diff --git a/tests/cli/ConfigWithPresetsCest.php b/tests/cli/ConfigWithPresetsCest.php
new file mode 100644
index 0000000000..5e79a113aa
--- /dev/null
+++ b/tests/cli/ConfigWithPresetsCest.php
@@ -0,0 +1,12 @@
+amInPath('tests/data/presets');
+ $I->executeCommand('run -c codeception.yml');
+ $I->seeInShellOutput('OK (1 test');
+ }
+
+}
diff --git a/tests/data/presets/_presets/preset.codeception.yml b/tests/data/presets/_presets/preset.codeception.yml
new file mode 100644
index 0000000000..f0446cc8a1
--- /dev/null
+++ b/tests/data/presets/_presets/preset.codeception.yml
@@ -0,0 +1,10 @@
+paths:
+ tests: tests
+ output: tests/_output
+ data: tests/_data
+ support: tests/_support
+ envs: tests/_envs
+actor_suffix: Tester
+extensions:
+ enabled:
+ - Codeception\Extension\RunFailed
diff --git a/tests/data/presets/_presets/preset.unit.suite.yml b/tests/data/presets/_presets/preset.unit.suite.yml
new file mode 100644
index 0000000000..6e8aea8013
--- /dev/null
+++ b/tests/data/presets/_presets/preset.unit.suite.yml
@@ -0,0 +1,3 @@
+modules:
+ enabled:
+ - \Helper\Dummy
\ No newline at end of file
diff --git a/tests/data/presets/codeception.yml b/tests/data/presets/codeception.yml
new file mode 100644
index 0000000000..1fd32bd717
--- /dev/null
+++ b/tests/data/presets/codeception.yml
@@ -0,0 +1 @@
+extends: ./_presets/preset.codeception.yml
diff --git a/tests/data/presets/codeception_2.yml b/tests/data/presets/codeception_2.yml
new file mode 100644
index 0000000000..bbbc1a614b
--- /dev/null
+++ b/tests/data/presets/codeception_2.yml
@@ -0,0 +1 @@
+extends: ./_presets/missing.preset.codeception.yml
diff --git a/tests/data/presets/tests/_support/DummyTester.php b/tests/data/presets/tests/_support/DummyTester.php
new file mode 100644
index 0000000000..3f333003bc
--- /dev/null
+++ b/tests/data/presets/tests/_support/DummyTester.php
@@ -0,0 +1,26 @@
+debug($this->config);
+ }
+
+ public function seePathIsSet()
+ {
+ $this->assertNotEmpty($this->config['path']);
+ }
+
+ public function seeVarsAreSet()
+ {
+ $vars = $this->config['vars'];
+ $this->assertContains('val1', $vars);
+ $this->assertContains('val2', $vars);
+ }
+}
diff --git a/tests/data/presets/tests/_support/_generated/.gitignore b/tests/data/presets/tests/_support/_generated/.gitignore
new file mode 100644
index 0000000000..cde8069e12
--- /dev/null
+++ b/tests/data/presets/tests/_support/_generated/.gitignore
@@ -0,0 +1 @@
+*.php
diff --git a/tests/data/presets/tests/unit.suite.yml b/tests/data/presets/tests/unit.suite.yml
new file mode 100644
index 0000000000..2d0b4bf877
--- /dev/null
+++ b/tests/data/presets/tests/unit.suite.yml
@@ -0,0 +1,2 @@
+presetfile: ./../_presets/preset.unit.suite.yml
+class_name: DummyTester
\ No newline at end of file
diff --git a/tests/data/presets/tests/unit/PresetTest.php b/tests/data/presets/tests/unit/PresetTest.php
new file mode 100644
index 0000000000..5b345378eb
--- /dev/null
+++ b/tests/data/presets/tests/unit/PresetTest.php
@@ -0,0 +1,11 @@
+assertEquals(true, true);
+ $this->assertNotEquals(true, false);
+ }
+
+}
\ No newline at end of file
From f280db96c06291e0d33e89b01f4bbfd84d22eab2 Mon Sep 17 00:00:00 2001
From: Davert
Date: Sun, 27 May 2018 01:16:48 +0300
Subject: [PATCH 055/395] removed incorrect coverage tests
---
tests/coverage/RemoteServerWithCrap4jCept.php | 7 -------
tests/coverage/RemoteServerWithPHPUnitCept.php | 7 -------
2 files changed, 14 deletions(-)
delete mode 100644 tests/coverage/RemoteServerWithCrap4jCept.php
delete mode 100644 tests/coverage/RemoteServerWithPHPUnitCept.php
diff --git a/tests/coverage/RemoteServerWithCrap4jCept.php b/tests/coverage/RemoteServerWithCrap4jCept.php
deleted file mode 100644
index e333fc27b4..0000000000
--- a/tests/coverage/RemoteServerWithCrap4jCept.php
+++ /dev/null
@@ -1,7 +0,0 @@
-wantTo('try generate remote codecoverage crap4j report');
-$I->amInPath('tests/data/sandbox');
-$I->executeCommand('run remote_server --coverage-crap4j remote_crap.xml');
-$I->seeFileFound('remote_crap.xml', 'tests/_output');
-$I->seeInThisFile('Method Crap Stats');
\ No newline at end of file
diff --git a/tests/coverage/RemoteServerWithPHPUnitCept.php b/tests/coverage/RemoteServerWithPHPUnitCept.php
deleted file mode 100644
index 63dadcb7db..0000000000
--- a/tests/coverage/RemoteServerWithPHPUnitCept.php
+++ /dev/null
@@ -1,7 +0,0 @@
-wantTo('try generate remote codecoverage phpunit report');
-$I->amInPath('tests/data/sandbox');
-$I->executeCommand('run remote_server --coverage-phpunit remote_server');
-$I->seeFileFound('index.xml', 'tests/_output/remote_server');
From 356c286aaf77e89cf280ac17d835af9e667474ec Mon Sep 17 00:00:00 2001
From: Michael Bodnarchuk
Date: Sun, 27 May 2018 01:17:36 +0300
Subject: [PATCH 056/395] Preparing 2.4.2 release; Updated changelog (#4990)
---
CHANGELOG-2.4.md | 31 +++++++++++++++++--
docs/12-ParallelExecution.md | 19 ++++--------
.../Lib/Interfaces/SessionSnapshot.php | 16 ++++++++--
src/Codeception/Module/WebDriver.php | 10 ------
4 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 46eca2907a..02a7f56ce2 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -1,5 +1,31 @@
#### 2.4.2
-* Added support for `extends` in the `codeception.yml` and `*.suite.yml` files; by @johannesschobel
+
+* Added support for `extends` in the `codeception.yml` and `*.suite.yml` files; by @johannesschobel.
+ Allows to inherit current config from a provided file. See example for `functional.suite.yml`:
+
+
+```yml
+actor: FunctionalTester
+extends: shared.functional.suite.yml
+modules:
+ enabled:
+ - \App\Modules\X\Tests\Helper\Functional
+```
+
+* [Yii2] Restore null check for client in Yii2 by @wkritzinger. See #4940
+* [Yii2] Resetting Yii application in `_after`. By @SamMousa. See #4928
+* [Yii2] **Breaking** `$settings['configFile']` now supports absolute paths. In you have defined relative path to config in absolute manner
+* [WebDriverIO] Added `deleteSessionSnapshot` by @vi4o
+* [Symfony] Added support for custom kernel names with `kernel_class` config option. By @omnilight.
+* [Asserts] Better exception message for `expectException` by @Slamdunk
+* [REST] Decode all non-arrays to array. See #4946 by @Amunak, fixes #4944.
+* [ZF2] Fixed compatibility with ZF2 ServiceManager by @omnilight.
+* [Laravel5] Fixed memory leak when using Laravel factories inside Codeception. See #4971 by @AdrianSkierniewski
+* [Db] Added support for `null` values in MSSQL driver by @philek
+* Handle absolute paths in ParamsLoader by @SilverFire
+* Fix error on single file test. See #4986 by @mikbox74
+* Upgraded to Codeception/Stub 2.0 by @Naktibalda, fixed compatibility.
+
#### 2.4.1
@@ -14,8 +40,7 @@
* More reliable application state before and during test execution
* Fixtures method is now configurable
* Subset of misconfigurations are now detected and informative messages created
-* Fixed using `$settings['path']` in `Codeception\Configuration::suiteSettings()` on Windows by @olegpro
-* **Breaking** `$settings['configFile']` now supports absolute paths. In you have defined relative path to config in absolute manner
+* Fixed using `$settings['path']` in `Codeception\Configuration::suiteSettings()` on Windows by @olegpro
(starting with `/`), you must change it. @silverfire
* [Laravel5] Added Laravel 5.4+ (5.1+ backward compatible) support for `callArtisan` method in Laravel5 module. See #4860 by @mohamed-aiman
* Fixed #4854: unnecessary escaping in operation arguments logging by @nicholascus
diff --git a/docs/12-ParallelExecution.md b/docs/12-ParallelExecution.md
index fce0be60c9..a7c18e0549 100644
--- a/docs/12-ParallelExecution.md
+++ b/docs/12-ParallelExecution.md
@@ -28,7 +28,7 @@ Run official Codeception image from DockerHub:
docker run codeception/codeception
Running tests from a project, by mounting the current path as a host-volume into the container.
-The default working directory in the container is `/project`.
+The **default working directory in the container is `/project`**.
docker run -v ${PWD}:/project codeception/codeception run
@@ -39,17 +39,15 @@ Define all required services in `docker-compose.yml` file. Make sure to follow D
We prepared a sample config with codeception, web server, database, and selenium with firefox to be executed together.
```yaml
-version: '2'
+version: '3'
services:
codecept:
image: codeception/codeception
depends_on:
- - firefox
+ - chrome
- web
volumes:
- - ./src:/src
- - ./tests:/tests
- - ./codeception.yml:/codeception.yml
+ - .:/project
web:
image: php:7-apache
depends_on:
@@ -58,13 +56,8 @@ services:
- .:/var/www/html
db:
image: percona:5.6
- ports:
- - '3306'
- firefox:
- image: selenium/standalone-firefox-debug:2.53.0
- ports:
- - '4444'
- - '5900'
+ chrome:
+ image: selenium/standalone-chrome
```
Codeception service will execute command `codecept run` but only after all services are started. This is defined using `depends_on` parameter.
diff --git a/src/Codeception/Lib/Interfaces/SessionSnapshot.php b/src/Codeception/Lib/Interfaces/SessionSnapshot.php
index 84074b391e..00ee66a892 100644
--- a/src/Codeception/Lib/Interfaces/SessionSnapshot.php
+++ b/src/Codeception/Lib/Interfaces/SessionSnapshot.php
@@ -36,11 +36,23 @@ interface SessionSnapshot
public function saveSessionSnapshot($name);
/**
- * Loads cookies from saved snapshot.
+ * Loads cookies from a saved snapshot.
+ * Allows to reuse same session across tests without additional login.
+ *
+ * See [saveSessionSnapshot](#saveSessionSnapshot)
*
* @param $name
- * @see saveSessionSnapshot
* @return mixed
*/
public function loadSessionSnapshot($name);
+
+ /**
+ * Deletes session snapshot.
+ *
+ * See [saveSessionSnapshot](#saveSessionSnapshot)
+ *
+ * @param $name
+ * @return mixed
+ */
+ public function deleteSessionSnapshot($name);
}
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index 740e3b12ab..0848e1755e 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -3028,9 +3028,6 @@ protected function getLocator($selector)
throw new \InvalidArgumentException("Only CSS or XPath allowed");
}
- /**
- * @param string $name
- */
public function saveSessionSnapshot($name)
{
$this->sessionSnapshots[$name] = [];
@@ -3048,10 +3045,6 @@ public function saveSessionSnapshot($name)
$this->debugSection('Snapshot', "Saved \"$name\" session snapshot");
}
- /**
- * @param string $name
- * @return bool
- */
public function loadSessionSnapshot($name)
{
if (!isset($this->sessionSnapshots[$name])) {
@@ -3065,9 +3058,6 @@ public function loadSessionSnapshot($name)
return true;
}
- /**
- * @param string $name
- */
public function deleteSessionSnapshot($name)
{
if (isset($this->sessionSnapshots[$name])) {
From 0c4ad4feae6e0681d5675976e9208c7f3b516ab6 Mon Sep 17 00:00:00 2001
From: Cladis
Date: Thu, 7 Jun 2018 09:53:44 +0300
Subject: [PATCH 057/395] =?UTF-8?q?it's=20=E2=86=92=20its=20(#5003)=20[ski?=
=?UTF-8?q?p=20ci]?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/reference/Mock.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/reference/Mock.md b/docs/reference/Mock.md
index 20b859e31f..2d53316572 100644
--- a/docs/reference/Mock.md
+++ b/docs/reference/Mock.md
@@ -24,8 +24,8 @@ $this->make(new User, ['name' => 'davert']);
?>
```
-To replace method provide it's name as a key in second parameter
-and it's return value or callback function as parameter
+To replace method provide its name as a key in second parameter
+and its return value or callback function as parameter
``` php
Date: Wed, 20 Jun 2018 16:49:10 -0300
Subject: [PATCH 058/395] Bug fix with multiple kernels (#5022)
* Bug fix with multiple kernels
It's not possible to set a Kernel different of the AppKernel, and I have
two kernels an Admin and an Api, and I need use ApiKernel to run tests
This commit makes a checking if kernel defined exists in the path.
Because the previous version he gets the first kernel in my case it gets
AdminKernel and always returns Kernel not found
* Remove 1 space after closing parenthesis
---
src/Codeception/Module/Symfony.php | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php
index 2ceab3dbcc..d9674fbee7 100644
--- a/src/Codeception/Module/Symfony.php
+++ b/src/Codeception/Module/Symfony.php
@@ -286,21 +286,23 @@ protected function getKernelClass()
. "Specify directory where file with Kernel class for your application is located with `app_path` parameter."
);
}
- $file = current($results);
if (file_exists(codecept_root_dir() . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php')) {
// ensure autoloader from this dir is loaded
require_once codecept_root_dir() . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
}
- require_once $file;
+ $filesRealPath = array_map(function ($file) {
+ require_once $file;
+ return $file->getRealPath();
+ }, $results);
$possibleKernelClasses = $this->getPossibleKernelClasses();
foreach ($possibleKernelClasses as $class) {
if (class_exists($class)) {
$refClass = new \ReflectionClass($class);
- if ($refClass->getFileName() === $file->getRealpath()) {
+ if ($file = array_search($refClass->getFileName(), $filesRealPath)) {
return $class;
}
}
From 534dc68c4ac79a251733f04547dcd963c76429a1 Mon Sep 17 00:00:00 2001
From: Joseph Zidell
Date: Wed, 20 Jun 2018 15:50:10 -0400
Subject: [PATCH 059/395] Update shim.php (#5013)
Fix indentation [skip ci]
---
shim.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/shim.php b/shim.php
index edc3efe727..7ba3df6e31 100644
--- a/shim.php
+++ b/shim.php
@@ -6,7 +6,7 @@
}
namespace Symfony\Component\CssSelector {
-if (!class_exists('Symfony\Component\CssSelector\CssSelectorConverter')) {
+ if (!class_exists('Symfony\Component\CssSelector\CssSelectorConverter')) {
class CssSelectorConverter {
function toXPath($cssExpr, $prefix = 'descendant-or-self::') {
return CssSelector::toXPath($cssExpr, $prefix);
@@ -69,4 +69,4 @@ class WebDriverTimeouts extends Facebook\WebDriver\WebDriverTimeouts {};
class WebDriverWindow extends Facebook\WebDriver\WebDriverWindow {};
interface WebDriverElement extends Facebook\WebDriver\WebDriverElement {};
}
-}
\ No newline at end of file
+}
From b903a8220ac5dbca8580ec8dd9baabafd995b7a7 Mon Sep 17 00:00:00 2001
From: Mark Lambley
Date: Thu, 21 Jun 2018 06:01:01 +1000
Subject: [PATCH 060/395] Add your own test format classes to the loader
(#5009)
---
docs/07-AdvancedUsage.md | 44 +++++++++++++++++++++++++++++++
docs/reference/Configuration.md | 1 +
src/Codeception/Configuration.php | 1 +
src/Codeception/Test/Loader.php | 5 ++++
4 files changed, 51 insertions(+)
diff --git a/docs/07-AdvancedUsage.md b/docs/07-AdvancedUsage.md
index dba333b58b..616c706168 100644
--- a/docs/07-AdvancedUsage.md
+++ b/docs/07-AdvancedUsage.md
@@ -661,6 +661,50 @@ groups:
This will load all found `p*` files in `tests/_data` as groups. Group names will be as follows p1,p2,...,pN.
+## Formats
+
+In addition to the standard test formats (Cept, Cest, Unit, Gherkin) you can implement your own format classes to customise your test execution.
+Specify these in your suite configuration:
+
+```yaml
+formats:
+ - \My\Namespace\MyFormat
+```
+
+Then define a class which implements the LoaderInterface
+
+```php
+namespace My\Namespace;
+
+class MyFormat implements \Codeception\Test\Loader\LoaderInterface
+{
+ protected $tests;
+
+ protected $settings;
+
+ public function __construct($settings = [])
+ {
+ //These are the suite settings
+ $this->settings = $settings;
+ }
+
+ public function loadTests($filename)
+ {
+ //Load file and create tests
+ }
+
+ public function getTests()
+ {
+ return $this->tests;
+ }
+
+ public function getPattern()
+ {
+ return '~Myformat\.php$~';
+ }
+}
+```
+
## Shell autocompletion
For bash and zsh shells, you can use autocompletion for your Codeception projects by executing the following in your shell (or add it to your .bashrc/.zshrc):
diff --git a/docs/reference/Configuration.md b/docs/reference/Configuration.md
index 41c068a1f1..234d6b77d0 100644
--- a/docs/reference/Configuration.md
+++ b/docs/reference/Configuration.md
@@ -139,6 +139,7 @@ modules:
* `suite_namespace`: default namespace for new tests of this suite (ignores `namespace` option)
* `env`: override any configuration per [environment](http://codeception.com/docs/07-AdvancedUsage#Environments).
* `groups`: [groups](http://codeception.com/docs/07-AdvancedUsage#Groups) with the list of tests of for corresponding group.
+* `formats`: [formats](http://codeception.com/docs/07-AdvancedUsage#Formats) with the list of extra test format classes.
* `coverage`: pre suite [CodeCoverage](http://codeception.com/docs/11-Codecoverage#Configuration) settings.
* `gherkin`: per suite [BDD Gherkin](http://codeception.com/docs/07-BDD#Configuration) settings.
* `error_level`: [error level](http://codeception.com/docs/04-FunctionalTests#Error-Reporting) for runner in current suite. Should be specified for unit, integration, functional tests. Passes value to `error_reporting` function.
diff --git a/src/Codeception/Configuration.php b/src/Codeception/Configuration.php
index 8914191403..2732d82cf7 100644
--- a/src/Codeception/Configuration.php
+++ b/src/Codeception/Configuration.php
@@ -113,6 +113,7 @@ class Configuration
'extends' => null,
'namespace' => null,
'groups' => [],
+ 'formats' => [],
'shuffle' => false,
'extensions' => [ // suite extensions
'enabled' => [],
diff --git a/src/Codeception/Test/Loader.php b/src/Codeception/Test/Loader.php
index 0cdd72a7d5..bb12cc9995 100644
--- a/src/Codeception/Test/Loader.php
+++ b/src/Codeception/Test/Loader.php
@@ -53,6 +53,11 @@ public function __construct(array $suiteSettings)
new UnitLoader(),
new GherkinLoader($suiteSettings)
];
+ if (isset($suiteSettings['formats'])) {
+ foreach ($suiteSettings['formats'] as $format) {
+ $this->formats[] = new $format($suiteSettings);
+ }
+ }
}
public function getTests()
From d8aaf00515d0cd5f2c8df4721bc956c2007c5f1a Mon Sep 17 00:00:00 2001
From: Johannes Schobel
Date: Wed, 20 Jun 2018 22:05:07 +0200
Subject: [PATCH 061/395] adding new assert methods (#5029)
---
src/Codeception/Module/Asserts.php | 22 +++++++++++++++++++
src/Codeception/Util/Shared/Asserts.php | 22 +++++++++++++++++++
tests/unit/Codeception/Module/AssertsTest.php | 6 +++++
3 files changed, 50 insertions(+)
diff --git a/src/Codeception/Module/Asserts.php b/src/Codeception/Module/Asserts.php
index 6bb7927ebc..314d284d4c 100644
--- a/src/Codeception/Module/Asserts.php
+++ b/src/Codeception/Module/Asserts.php
@@ -263,6 +263,17 @@ public function assertTrue($condition, $message = '')
parent::assertTrue($condition, $message);
}
+ /**
+ * Checks that the condition is NOT true (everything but true)
+ *
+ * @param $condition
+ * @param string $message
+ */
+ public function assertNotTrue($condition, $message = '')
+ {
+ parent::assertNotTrue($condition, $message);
+ }
+
/**
* Checks that condition is negative.
*
@@ -274,6 +285,17 @@ public function assertFalse($condition, $message = '')
parent::assertFalse($condition, $message);
}
+ /**
+ * Checks that the condition is NOT false (everything but false)
+ *
+ * @param $condition
+ * @param string $message
+ */
+ public function assertNotFalse($condition, $message = '')
+ {
+ parent::assertNotFalse($condition, $message);
+ }
+
/**
* Checks if file exists
*
diff --git a/src/Codeception/Util/Shared/Asserts.php b/src/Codeception/Util/Shared/Asserts.php
index 2c4958bed7..c50211ce19 100644
--- a/src/Codeception/Util/Shared/Asserts.php
+++ b/src/Codeception/Util/Shared/Asserts.php
@@ -267,6 +267,17 @@ protected function assertTrue($condition, $message = '')
\PHPUnit\Framework\Assert::assertTrue($condition, $message);
}
+ /**
+ * Checks that the condition is NOT true (everything but true)
+ *
+ * @param $condition
+ * @param string $message
+ */
+ protected function assertNotTrue($condition, $message = '')
+ {
+ \PHPUnit\Framework\Assert::assertNotTrue($condition, $message);
+ }
+
/**
* Checks that condition is negative.
*
@@ -278,6 +289,17 @@ protected function assertFalse($condition, $message = '')
\PHPUnit\Framework\Assert::assertFalse($condition, $message);
}
+ /**
+ * Checks that the condition is NOT false (everything but false)
+ *
+ * @param $condition
+ * @param string $message
+ */
+ protected function assertNotFalse($condition, $message = '')
+ {
+ \PHPUnit\Framework\Assert::assertNotFalse($condition, $message);
+ }
+
/**
*
* @param $haystack
diff --git a/tests/unit/Codeception/Module/AssertsTest.php b/tests/unit/Codeception/Module/AssertsTest.php
index 5d71f3b152..e237175049 100644
--- a/tests/unit/Codeception/Module/AssertsTest.php
+++ b/tests/unit/Codeception/Module/AssertsTest.php
@@ -19,7 +19,13 @@ public function testAsserts()
$module->assertNotNull(false);
$module->assertNotNull(0);
$module->assertTrue(true);
+ $module->assertNotTrue(false);
+ $module->assertNotTrue(null);
+ $module->assertNotTrue('foo');
$module->assertFalse(false);
+ $module->assertNotFalse(true);
+ $module->assertNotFalse(null);
+ $module->assertNotFalse('foo');
$module->assertFileExists(__FILE__);
$module->assertFileNotExists(__FILE__ . '.notExist');
$module->assertInstanceOf('Exception', new Exception());
From 3174f5fa5ab22f39ec0a49391cef3b02b8c1f370 Mon Sep 17 00:00:00 2001
From: Mike Harrison
Date: Wed, 20 Jun 2018 17:06:52 -0400
Subject: [PATCH 062/395] Issue #5023 (#5024)
* Created failing test RunCest::runJsonReport
* PSR2 Formatting
* Removed double parentheses
---
tests/cli.suite.yml | 3 ++-
tests/cli/RunCest.php | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/tests/cli.suite.yml b/tests/cli.suite.yml
index 8176cf742a..9824f57c17 100644
--- a/tests/cli.suite.yml
+++ b/tests/cli.suite.yml
@@ -4,4 +4,5 @@ modules:
- Filesystem
- Cli
- CliHelper
- - CodeHelper
\ No newline at end of file
+ - CodeHelper
+ - Asserts
\ No newline at end of file
diff --git a/tests/cli/RunCest.php b/tests/cli/RunCest.php
index 1e01d040dc..ddab45ea0c 100644
--- a/tests/cli/RunCest.php
+++ b/tests/cli/RunCest.php
@@ -47,6 +47,7 @@ public function runJsonReport(\CliGuy $I)
$I->seeFileFound('report.json', 'tests/_output');
$I->seeInThisFile('"suite":');
$I->seeInThisFile('"dummy"');
+ $I->assertNotNull(json_decode(file_get_contents('tests/_output/report.json')));
}
/**
@@ -292,7 +293,7 @@ public function runTestWithSubSteps(\CliGuy $I, $scenario)
$scenario->skip("Xdebug not loaded");
}
- $file = "codeception".DIRECTORY_SEPARATOR."c3";
+ $file = "codeception" . DIRECTORY_SEPARATOR . "c3";
$I->executeCommand('run scenario SubStepsCept --steps');
$I->seeInShellOutput(<<
Date: Thu, 21 Jun 2018 14:15:29 +0200
Subject: [PATCH 063/395] new REST / InnerBrowser Asserts (#5030)
* new assertions to assert "ranges" of status-codes (e.g., if it is a client-error --> 4xx)
* add missing test
---
src/Codeception/Lib/InnerBrowser.php | 50 +++++++++++++++++++
src/Codeception/Module/REST.php | 33 ++++++++++++
.../Codeception/Module/PhpBrowserTest.php | 36 +++++++++++++
3 files changed, 119 insertions(+)
diff --git a/src/Codeception/Lib/InnerBrowser.php b/src/Codeception/Lib/InnerBrowser.php
index 1aefbc4399..fa41755b04 100644
--- a/src/Codeception/Lib/InnerBrowser.php
+++ b/src/Codeception/Lib/InnerBrowser.php
@@ -1576,6 +1576,24 @@ public function seeResponseCodeIs($code)
$this->assertEquals($code, $this->getResponseStatusCode(), $failureMessage);
}
+ /**
+ * Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+ *
+ * @param $from
+ * @param $to
+ */
+ public function seeResponseCodeIsBetween($from, $to)
+ {
+ $failureMessage = sprintf(
+ 'Expected HTTP Status Code between %s and %s. Actual Status Code: %s',
+ HttpCode::getDescription($from),
+ HttpCode::getDescription($to),
+ HttpCode::getDescription($this->getResponseStatusCode())
+ );
+ $this->assertGreaterThanOrEqual($from, $this->getResponseStatusCode(), $failureMessage);
+ $this->assertLessThanOrEqual($to, $this->getResponseStatusCode(), $failureMessage);
+ }
+
/**
* Checks that response code is equal to value provided.
*
@@ -1597,6 +1615,38 @@ public function dontSeeResponseCodeIs($code)
$this->assertNotEquals($code, $this->getResponseStatusCode(), $failureMessage);
}
+ /**
+ * Checks that the response code 2xx
+ */
+ public function seeResponseCodeIsSuccessful()
+ {
+ $this->seeResponseCodeIsBetween(200, 299);
+ }
+
+ /**
+ * Checks that the response code 3xx
+ */
+ public function seeResponseCodeIsRedirection()
+ {
+ $this->seeResponseCodeIsBetween(300, 399);
+ }
+
+ /**
+ * Checks that the response code is 4xx
+ */
+ public function seeResponseCodeIsClientError()
+ {
+ $this->seeResponseCodeIsBetween(400, 499);
+ }
+
+ /**
+ * Checks that the response code is 5xx
+ */
+ public function seeResponseCodeIsServerError()
+ {
+ $this->seeResponseCodeIsBetween(500, 599);
+ }
+
public function seeInTitle($title)
{
$nodes = $this->getCrawler()->filter('title');
diff --git a/src/Codeception/Module/REST.php b/src/Codeception/Module/REST.php
index 3f1db8c6b5..dd3b808b2b 100644
--- a/src/Codeception/Module/REST.php
+++ b/src/Codeception/Module/REST.php
@@ -1161,6 +1161,39 @@ public function dontSeeResponseCodeIs($code)
$this->connectionModule->dontSeeResponseCodeIs($code);
}
+ /**
+ * Checks that the response code is 2xx
+ */
+ public function seeResponseCodeIsSuccessful()
+ {
+ $this->connectionModule->seeResponseCodeIsSuccessful();
+ }
+
+ /**
+ * Checks that the response code 3xx
+ */
+ public function seeResponseCodeIsRedirection()
+ {
+ $this->connectionModule->seeResponseCodeIsRedirection();
+ }
+
+ /**
+ * Checks that the response code is 4xx
+ */
+ public function seeResponseCodeIsClientError()
+ {
+ $this->connectionModule->seeResponseCodeIsClientError();
+ }
+
+ /**
+ * Checks that the response code is 5xx
+ */
+ public function seeResponseCodeIsServerError()
+ {
+ $this->connectionModule->seeResponseCodeIsServerError();
+ }
+
+
/**
* Checks whether last response was valid XML.
* This is done with libxml_get_last_error function.
diff --git a/tests/unit/Codeception/Module/PhpBrowserTest.php b/tests/unit/Codeception/Module/PhpBrowserTest.php
index 9c911f4414..86a92de7d4 100644
--- a/tests/unit/Codeception/Module/PhpBrowserTest.php
+++ b/tests/unit/Codeception/Module/PhpBrowserTest.php
@@ -691,4 +691,40 @@ public function testSetUserAgentUsingConfig()
$response = $this->module->grabPageSource();
$this->assertEquals('Codeception User Agent Test 1.0', $response, 'Incorrect user agent');
}
+
+ public function testIfStatusCodeIsWithin2xxRange()
+ {
+ $this->module->amOnPage('https://httpstat.us/200');
+ $this->module->seeResponseCodeIsSuccessful();
+
+ $this->module->amOnPage('https://httpstat.us/299');
+ $this->module->seeResponseCodeIsSuccessful();
+ }
+
+ public function testIfStatusCodeIsWithin3xxRange()
+ {
+ $this->module->amOnPage('https://httpstat.us/300');
+ $this->module->seeResponseCodeIsRedirection();
+
+ $this->module->amOnPage('https://httpstat.us/399');
+ $this->module->seeResponseCodeIsRedirection();
+ }
+
+ public function testIfStatusCodeIsWithin4xxRange()
+ {
+ $this->module->amOnPage('https://httpstat.us/400');
+ $this->module->seeResponseCodeIsClientError();
+
+ $this->module->amOnPage('https://httpstat.us/499');
+ $this->module->seeResponseCodeIsClientError();
+ }
+
+ public function testIfStatusCodeIsWithin5xxRange()
+ {
+ $this->module->amOnPage('https://httpstat.us/500');
+ $this->module->seeResponseCodeIsServerError();
+
+ $this->module->amOnPage('https://httpstat.us/599');
+ $this->module->seeResponseCodeIsServerError();
+ }
}
From 01973880f3c3aa7fcc534aa16a51d4352bf7518a Mon Sep 17 00:00:00 2001
From: Johannes Schobel
Date: Thu, 21 Jun 2018 23:13:41 +0200
Subject: [PATCH 064/395] minor doc updates (#5035)
---
docs/03-AcceptanceTests.md | 2 +-
docs/06-ModulesAndHelpers.md | 4 ++++
docs/06-ReusingTestCode.md | 4 ++--
docs/07-AdvancedUsage.md | 6 +++---
docs/12-ParallelExecution.md | 2 +-
docs/modules/AMQP.md | 8 ++++----
docs/modules/AngularJS.md | 4 ++--
docs/modules/REST.md | 1 +
docs/modules/WebDriver.md | 4 ++--
docs/reference/Locator.md | 24 ++++++++++++------------
docs/reference/Mock.md | 4 ++--
docs/reference/XmlBuilder.md | 2 +-
12 files changed, 35 insertions(+), 30 deletions(-)
diff --git a/docs/03-AcceptanceTests.md b/docs/03-AcceptanceTests.md
index a091298d02..fb7d600a34 100644
--- a/docs/03-AcceptanceTests.md
+++ b/docs/03-AcceptanceTests.md
@@ -295,7 +295,7 @@ and you want to check that the user can log into the site using this password:
```php
fillField('email', 'miles@davis.com')
+$I->fillField('email', 'miles@davis.com');
$I->click('Generate Password');
$password = $I->grabTextFrom('#password');
$I->click('Login');
diff --git a/docs/06-ModulesAndHelpers.md b/docs/06-ModulesAndHelpers.md
index 052a244034..2c8c2bd9a0 100644
--- a/docs/06-ModulesAndHelpers.md
+++ b/docs/06-ModulesAndHelpers.md
@@ -357,6 +357,8 @@ Here is how it is done in the Db module:
class Db extends \Codeception\Module
{
protected $requiredFields = ['dsn', 'user', 'password'];
+ // ...
+}
```
The next time you start the suite without setting one of these values, an exception will be thrown.
@@ -370,6 +372,8 @@ class WebDriver extends \Codeception\Module
{
protected $requiredFields = ['browser', 'url'];
protected $config = ['host' => '127.0.0.1', 'port' => '4444'];
+ // ...
+}
```
The host and port parameter can be redefined in the suite configuration.
diff --git a/docs/06-ReusingTestCode.md b/docs/06-ReusingTestCode.md
index 5ac61a6398..9d921d6697 100644
--- a/docs/06-ReusingTestCode.md
+++ b/docs/06-ReusingTestCode.md
@@ -106,7 +106,7 @@ breaking the [Single Responsibility Principle](http://en.wikipedia.org/wiki/Sing
### Session Snapshot
-If you need to authorize a user for each test, you can do so by submiting the login form at the beginning of every test.
+If you need to authorize a user for each test, you can do so by submitting the login form at the beginning of every test.
Running those steps takes time, and in the case of Selenium tests (which are slow by themselves)
that time loss can become significant.
@@ -237,7 +237,7 @@ the [PageObject pattern](http://docs.seleniumhq.org/docs/06_test_design_consider
which is widely used by test automation engineers. The PageObject pattern represents a web page as a class
and the DOM elements on that page as its properties, and some basic interactions as its methods.
PageObjects are very important when you are developing a flexible architecture of your tests.
-Do not hardcode complex CSS or XPath locators in your tests but rather move them into PageObject classes.
+Do not hard-code complex CSS or XPath locators in your tests but rather move them into PageObject classes.
Codeception can generate a PageObject class for you with command:
diff --git a/docs/07-AdvancedUsage.md b/docs/07-AdvancedUsage.md
index 616c706168..df4fc85e92 100644
--- a/docs/07-AdvancedUsage.md
+++ b/docs/07-AdvancedUsage.md
@@ -497,7 +497,7 @@ public function myTest(\AcceptanceTester $I, \Codeception\Scenario $scenario)
}
```
-`Codeception\Scenario` is also availble in Actor classes and StepObjects. You can access it with `$this->getScenario()`.
+`Codeception\Scenario` is also available in Actor classes and StepObjects. You can access it with `$this->getScenario()`.
### Dependencies
@@ -705,9 +705,9 @@ class MyFormat implements \Codeception\Test\Loader\LoaderInterface
}
```
-## Shell autocompletion
+## Shell auto-completion
-For bash and zsh shells, you can use autocompletion for your Codeception projects by executing the following in your shell (or add it to your .bashrc/.zshrc):
+For bash and zsh shells, you can use auto-completion for your Codeception projects by executing the following in your shell (or add it to your .bashrc/.zshrc):
```bash
# BASH ~4.x, ZSH
source <([codecept location] _completion --generate-hook --program codecept --use-vendor-bin)
diff --git a/docs/12-ParallelExecution.md b/docs/12-ParallelExecution.md
index a7c18e0549..9ca83e8607 100644
--- a/docs/12-ParallelExecution.md
+++ b/docs/12-ParallelExecution.md
@@ -138,7 +138,7 @@ $ composer require codeception/codeception
### Preparing Robo
-Intitalizes basic RoboFile in the root of your project
+Initializes basic RoboFile in the root of your project
```bash
$ robo init
diff --git a/docs/modules/AMQP.md b/docs/modules/AMQP.md
index 737054dfb1..3b01152a42 100644
--- a/docs/modules/AMQP.md
+++ b/docs/modules/AMQP.md
@@ -49,7 +49,7 @@ $I->bindQueueToExchange(
'nameOfMyQueueToBind', // name of the queue
'transactionTracking.transaction', // exchange name to bind to
'your.routing.key' // Optionally, provide a binding key
-)
+);
```
* `param string` $queue
@@ -72,7 +72,7 @@ This is an alias of method `exchange_declare` of `PhpAmqpLib\Channel\AMQPChannel
$I->declareExchange(
'nameOfMyExchange', // exchange name
'topic' // exchange type
-)
+);
```
* `param string` $exchange
@@ -96,8 +96,8 @@ This is an alias of method `queue_declare` of `PhpAmqpLib\Channel\AMQPChannel`.
```php
declareQueue(
- 'nameOfMyQueue', // exchange name
-)
+ 'nameOfMyQueue' // exchange name
+);
```
* `param string` $queue
diff --git a/docs/modules/AngularJS.md b/docs/modules/AngularJS.md
index e929cc721e..51270a1ca2 100644
--- a/docs/modules/AngularJS.md
+++ b/docs/modules/AngularJS.md
@@ -752,9 +752,9 @@ A callback should be executed by JavaScript to exit from a script.
Callback is passed as a last element in `arguments` array.
Additional arguments can be passed as array in second parameter.
-```js
+``` php
// wait for 1200 milliseconds my running `setTimeout`
-* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
+$I->executeAsyncJS('setTimeout(arguments[0], 1200)');
$seconds = 1200; // or seconds are passed as argument
$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
diff --git a/docs/modules/REST.md b/docs/modules/REST.md
index 6798cf5831..c9eaf2221f 100644
--- a/docs/modules/REST.md
+++ b/docs/modules/REST.md
@@ -661,6 +661,7 @@ $I->seeResponseMatchesJsonType([
// {'user_id': '1'}
$I->seeResponseMatchesJsonType([
'user_id' => 'string:>0', // works with strings as well
+ ]);
}
?>
```
diff --git a/docs/modules/WebDriver.md b/docs/modules/WebDriver.md
index 7faf738973..3cc1cd8279 100644
--- a/docs/modules/WebDriver.md
+++ b/docs/modules/WebDriver.md
@@ -936,9 +936,9 @@ A callback should be executed by JavaScript to exit from a script.
Callback is passed as a last element in `arguments` array.
Additional arguments can be passed as array in second parameter.
-```js
+``` php
// wait for 1200 milliseconds my running `setTimeout`
-* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
+$I->executeAsyncJS('setTimeout(arguments[0], 1200)');
$seconds = 1200; // or seconds are passed as argument
$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
diff --git a/docs/reference/Locator.md b/docs/reference/Locator.md
index ae78463fa6..239dc8697a 100644
--- a/docs/reference/Locator.md
+++ b/docs/reference/Locator.md
@@ -165,9 +165,9 @@ Checks that provided string is CSS selector
```php
true
-Locator::isCSS('body') => true
-Locator::isCSS('//body/p/user') => false
+Locator::isCSS('#user .hello'); // => true
+Locator::isCSS('body'); // => true
+Locator::isCSS('//body/p/user'); // => false
```
* `param` $selector
@@ -183,9 +183,9 @@ Checks that a string is valid CSS class
```php
true
-Locator::isClass('body') => false
-Locator::isClass('//body/p/user') => false
+Locator::isClass('.hello'); // => true
+Locator::isClass('body'); // => false
+Locator::isClass('//body/p/user'); // => false
```
* `param` $class
@@ -201,9 +201,9 @@ Checks that a string is valid CSS ID
```php
true
-Locator::isID('body') => false
-Locator::isID('//body/p/user') => false
+Locator::isID('#user'); // => true
+Locator::isID('body'); // => false
+Locator::isID('//body/p/user'); // => false
```
* `param` $id
@@ -228,9 +228,9 @@ Checks that locator is an XPath
```php
false
-Locator::isXPath('body') => false
-Locator::isXPath('//body/p/user') => true
+Locator::isXPath('#user .hello'); // => false
+Locator::isXPath('body'); // => false
+Locator::isXPath('//body/p/user'); // => true
```
* `param` $locator
diff --git a/docs/reference/Mock.md b/docs/reference/Mock.md
index 2d53316572..8066190e98 100644
--- a/docs/reference/Mock.md
+++ b/docs/reference/Mock.md
@@ -301,7 +301,7 @@ use \Codeception\Stub\Expected;
$user = $this->make(
'User',
- array(
+ array (
'getName' => Expected::atLeastOnce('Davert')),
'someMethod' => function() {}
)
@@ -353,7 +353,7 @@ Alternatively, a function can be passed as parameter:
```php
users
->attr('empty','false')
->items
->item
- ->val('useful item');
+ ->val('useful item')
->parents('user')
->active
->val(1);
From 9aa56242cb107c79b5a2960ad9231f739bb6623e Mon Sep 17 00:00:00 2001
From: Johannes Schobel
Date: Tue, 26 Jun 2018 03:14:39 +0200
Subject: [PATCH 065/395] bump changelog (#5041)
---
CHANGELOG-2.4.md | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 02a7f56ce2..eec398b49e 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -1,9 +1,17 @@
+#### 2.4.3
+
+* Fixed a bug in order to use multiple Kernels; by @alefcastelo
+* Added feature to specify your own test formats (e.g., Cept, Cest, ...); by @mlambley
+* [Asserts] Added new methods `assertNotTrue` and `assertNotFalse` methods; by @johannesschobel
+* [REST / InnerBrowser] Added new methods to check for `Http Status Ranges` with nice "wrappers" (e.g., `seeHttpStatusCodeIsSuccessful()` checks the code between 200 and 299); by @johannesschobel
+* [REST / InnerBrowser] Added new method to load a stub file from the `data` folder of the suite and replace placeholder with real values; by @johannesschobel
+* Improved the docs; by community
+
#### 2.4.2
* Added support for `extends` in the `codeception.yml` and `*.suite.yml` files; by @johannesschobel.
Allows to inherit current config from a provided file. See example for `functional.suite.yml`:
-
```yml
actor: FunctionalTester
extends: shared.functional.suite.yml
From 13b2db0d54068afaabf3ca8ac8b6591d69018f46 Mon Sep 17 00:00:00 2001
From: Davert
Date: Tue, 26 Jun 2018 17:09:28 +0300
Subject: [PATCH 066/395] updated changelog, updated docs
---
CHANGELOG-2.4.md | 7 ++---
docs/modules/AMQP.md | 8 ++---
docs/modules/AngularJS.md | 49 ++++++++++++++++++++++++++---
docs/modules/Asserts.md | 16 ++++++++++
docs/modules/Db.md | 16 +++-------
docs/modules/Laravel5.md | 28 +++++++++++++++++
docs/modules/Lumen.md | 28 +++++++++++++++++
docs/modules/Phalcon.md | 28 +++++++++++++++++
docs/modules/PhpBrowser.md | 28 +++++++++++++++++
docs/modules/REST.md | 21 ++++++++++++-
docs/modules/Silex.md | 28 +++++++++++++++++
docs/modules/Symfony.md | 31 ++++++++++++++++++
docs/modules/WebDriver.md | 49 ++++++++++++++++++++++++++---
docs/modules/Yii1.md | 28 +++++++++++++++++
docs/modules/Yii2.md | 46 +++++++++++++++++++++++++--
docs/modules/ZF1.md | 28 +++++++++++++++++
docs/modules/ZF2.md | 28 +++++++++++++++++
docs/modules/ZendExpressive.md | 28 +++++++++++++++++
docs/reference/Locator.md | 24 +++++++-------
docs/reference/Mock.md | 8 ++---
docs/reference/Module.md | 54 ++++++++++++++++++++++----------
docs/reference/XmlBuilder.md | 2 +-
src/Codeception/Codecept.php | 2 +-
tests/data/claypit/composer.lock | 8 ++---
24 files changed, 521 insertions(+), 72 deletions(-)
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index eec398b49e..cde1c9fe25 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -1,10 +1,9 @@
#### 2.4.3
-* Fixed a bug in order to use multiple Kernels; by @alefcastelo
-* Added feature to specify your own test formats (e.g., Cept, Cest, ...); by @mlambley
+* [Create your own test formats](https://codeception.com/docs/07-AdvancedUsage#Formats) (e.g., Cept, Cest, ...); by @mlambley
+* [Symfony] Fixed a bug in order to use multiple Kernels; by @alefcastelo
* [Asserts] Added new methods `assertNotTrue` and `assertNotFalse` methods; by @johannesschobel
-* [REST / InnerBrowser] Added new methods to check for `Http Status Ranges` with nice "wrappers" (e.g., `seeHttpStatusCodeIsSuccessful()` checks the code between 200 and 299); by @johannesschobel
-* [REST / InnerBrowser] Added new method to load a stub file from the `data` folder of the suite and replace placeholder with real values; by @johannesschobel
+* [REST][PhpBrowser][Frameworks] Added new methods to check for `Http Status Ranges` with nice "wrappers" (e.g., `seeHttpStatusCodeIsSuccessful()` checks the code between 200 and 299); by @johannesschobel
* Improved the docs; by community
#### 2.4.2
diff --git a/docs/modules/AMQP.md b/docs/modules/AMQP.md
index 3b01152a42..737054dfb1 100644
--- a/docs/modules/AMQP.md
+++ b/docs/modules/AMQP.md
@@ -49,7 +49,7 @@ $I->bindQueueToExchange(
'nameOfMyQueueToBind', // name of the queue
'transactionTracking.transaction', // exchange name to bind to
'your.routing.key' // Optionally, provide a binding key
-);
+)
```
* `param string` $queue
@@ -72,7 +72,7 @@ This is an alias of method `exchange_declare` of `PhpAmqpLib\Channel\AMQPChannel
$I->declareExchange(
'nameOfMyExchange', // exchange name
'topic' // exchange type
-);
+)
```
* `param string` $exchange
@@ -96,8 +96,8 @@ This is an alias of method `queue_declare` of `PhpAmqpLib\Channel\AMQPChannel`.
```php
declareQueue(
- 'nameOfMyQueue' // exchange name
-);
+ 'nameOfMyQueue', // exchange name
+)
```
* `param string` $queue
diff --git a/docs/modules/AngularJS.md b/docs/modules/AngularJS.md
index 51270a1ca2..5fa69b66a5 100644
--- a/docs/modules/AngularJS.md
+++ b/docs/modules/AngularJS.md
@@ -468,6 +468,15 @@ Print out latest Selenium Logs in debug mode
* `param TestInterface` $test
+### deleteSessionSnapshot
+
+Deletes session snapshot.
+
+See [saveSessionSnapshot](#saveSessionSnapshot)
+
+ * `param` $name
+
+
### dontSee
Checks that the current page doesn't contain the text specified (case insensitive).
@@ -752,9 +761,9 @@ A callback should be executed by JavaScript to exit from a script.
Callback is passed as a last element in `arguments` array.
Additional arguments can be passed as array in second parameter.
-``` php
+```js
// wait for 1200 milliseconds my running `setTimeout`
-$I->executeAsyncJS('setTimeout(arguments[0], 1200)');
+* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
$seconds = 1200; // or seconds are passed as argument
$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
@@ -932,8 +941,12 @@ $name = $I->grabValueFrom(['name' => 'username']);
### loadSessionSnapshot
- * `param string` $name
- * `return` bool
+Loads cookies from a saved snapshot.
+Allows to reuse same session across tests without additional login.
+
+See [saveSessionSnapshot](#saveSessionSnapshot)
+
+ * `param` $name
### makeScreenshot
@@ -1113,7 +1126,33 @@ $I->resizeWindow(800, 600);
### saveSessionSnapshot
- * `param string` $name
+Saves current cookies into named snapshot in order to restore them in other tests
+This is useful to save session state between tests.
+For example, if user needs log in to site for each test this scenario can be executed once
+while other tests can just restore saved cookies.
+
+``` php
+loadSessionSnapshot('login')) return;
+
+ // logging in
+ $I->amOnPage('/login');
+ $I->fillField('name', 'jon');
+ $I->fillField('password', '123345');
+ $I->click('Login');
+
+ // saving snapshot
+ $I->saveSessionSnapshot('login');
+}
+?>
+```
+
+ * `param` $name
### scrollTo
diff --git a/docs/modules/Asserts.md b/docs/modules/Asserts.md
index 924852ebf3..7ae38dc8ab 100644
--- a/docs/modules/Asserts.md
+++ b/docs/modules/Asserts.md
@@ -212,6 +212,14 @@ $I->assertNotEquals($calculator->add(0.1, 0.2), 0.4, 'Calculator should add the
* `param float` $delta
+### assertNotFalse
+
+Checks that the condition is NOT false (everything but false)
+
+ * `param` $condition
+ * `param string` $message
+
+
### assertNotInstanceOf
* `param` $class
@@ -245,6 +253,14 @@ Checks that two variables are not same
* `param string` $message
+### assertNotTrue
+
+Checks that the condition is NOT true (everything but true)
+
+ * `param` $condition
+ * `param string` $message
+
+
### assertNull
Checks that variable is NULL
diff --git a/docs/modules/Db.md b/docs/modules/Db.md
index 38015e04c4..73d9356274 100644
--- a/docs/modules/Db.md
+++ b/docs/modules/Db.md
@@ -219,27 +219,19 @@ $mails = $I->grabColumnFromDatabase('users', 'email', array('name' => 'RebOOter'
### grabFromDatabase
-Fetches a single column value from a database.
+Fetches all values from the column in database.
Provide table name, desired column and criteria.
``` php
grabFromDatabase('users', 'email', array('name' => 'Davert'));
-```
-Comparison expressions can be used as well:
-
-```php
-grabFromDatabase('posts', ['num_comments >=' => 100]);
-$user = $I->grabFromDatabase('users', ['email like' => 'miles%']);
+$mails = $I->grabFromDatabase('users', 'email', array('name' => 'RebOOter'));
```
-Supported operators: `<`, `>`, `>=`, `<=`, `!=`, `like`.
-
* `param string` $table
* `param string` $column
- * `param array` $criteria
+ * `param array` $criteria
+ * `return` array
### grabNumRecords
diff --git a/docs/modules/Laravel5.md b/docs/modules/Laravel5.md
index b30b0b2907..78547ccb4d 100644
--- a/docs/modules/Laravel5.md
+++ b/docs/modules/Laravel5.md
@@ -1567,6 +1567,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### seeSessionHasValues
Assert that the session has a given list of values.
diff --git a/docs/modules/Lumen.md b/docs/modules/Lumen.md
index 9b463ec1aa..e6a49f9f54 100644
--- a/docs/modules/Lumen.md
+++ b/docs/modules/Lumen.md
@@ -1243,6 +1243,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/Phalcon.md b/docs/modules/Phalcon.md
index 7106ebf920..b454e2c911 100644
--- a/docs/modules/Phalcon.md
+++ b/docs/modules/Phalcon.md
@@ -1174,6 +1174,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### seeSessionHasValues
Assert that the session has a given list of values.
diff --git a/docs/modules/PhpBrowser.md b/docs/modules/PhpBrowser.md
index fad0a6a363..b0b658fae4 100644
--- a/docs/modules/PhpBrowser.md
+++ b/docs/modules/PhpBrowser.md
@@ -1052,6 +1052,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/REST.md b/docs/modules/REST.md
index c9eaf2221f..c5f6cb42a6 100644
--- a/docs/modules/REST.md
+++ b/docs/modules/REST.md
@@ -442,6 +442,26 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code is 2xx
+
+
### seeResponseContains
Checks whether the last response contains text.
@@ -661,7 +681,6 @@ $I->seeResponseMatchesJsonType([
// {'user_id': '1'}
$I->seeResponseMatchesJsonType([
'user_id' => 'string:>0', // works with strings as well
- ]);
}
?>
```
diff --git a/docs/modules/Silex.md b/docs/modules/Silex.md
index 55684b8796..1e1b7f7e1f 100644
--- a/docs/modules/Silex.md
+++ b/docs/modules/Silex.md
@@ -1000,6 +1000,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/Symfony.md b/docs/modules/Symfony.md
index 607fe2677b..50645edbf5 100644
--- a/docs/modules/Symfony.md
+++ b/docs/modules/Symfony.md
@@ -13,6 +13,7 @@ This module uses Symfony Crawler and HttpKernel to emulate requests and test res
* app_path: 'src' - in Symfony 4 Kernel is located inside `src`
* environment: 'local' - environment used for load kernel
+* kernel_class: 'App\Kernel' - kernel class name
* em_service: 'doctrine.orm.entity_manager' - use the stated EntityManager to pair with Doctrine Module.
* debug: true - turn on/off debug mode
* cache_router: 'false' - enable router caching between tests in order to [increase performance](http://lakion.com/blog/how-did-we-speed-up-sylius-behat-suite-with-blackfire)
@@ -32,6 +33,7 @@ This module uses Symfony Crawler and HttpKernel to emulate requests and test res
* app_path: 'app' - specify custom path to your app dir, where the kernel interface is located.
* var_path: 'var' - specify custom path to your var dir, where bootstrap cache is located.
* environment: 'local' - environment used for load kernel
+* kernel_class: 'AppKernel' - kernel class name
* em_service: 'doctrine.orm.entity_manager' - use the stated EntityManager to pair with Doctrine Module.
* debug: true - turn on/off debug mode
* cache_router: 'false' - enable router caching between tests in order to [increase performance](http://lakion.com/blog/how-did-we-speed-up-sylius-behat-suite-with-blackfire)
@@ -51,6 +53,7 @@ This module uses Symfony Crawler and HttpKernel to emulate requests and test res
* app_path: 'app' - specify custom path to your app dir, where bootstrap cache and kernel interface is located.
* environment: 'local' - environment used for load kernel
+* kernel_class: 'AppKernel' - kernel class name
* debug: true - turn on/off debug mode
* em_service: 'doctrine.orm.entity_manager' - use the stated EntityManager to pair with Doctrine Module.
* cache_router: 'false' - enable router caching between tests in order to [increase performance](http://lakion.com/blog/how-did-we-speed-up-sylius-behat-suite-with-blackfire)
@@ -1140,6 +1143,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/WebDriver.md b/docs/modules/WebDriver.md
index 3cc1cd8279..de64f181df 100644
--- a/docs/modules/WebDriver.md
+++ b/docs/modules/WebDriver.md
@@ -652,6 +652,15 @@ Print out latest Selenium Logs in debug mode
* `param TestInterface` $test
+### deleteSessionSnapshot
+
+Deletes session snapshot.
+
+See [saveSessionSnapshot](#saveSessionSnapshot)
+
+ * `param` $name
+
+
### dontSee
Checks that the current page doesn't contain the text specified (case insensitive).
@@ -936,9 +945,9 @@ A callback should be executed by JavaScript to exit from a script.
Callback is passed as a last element in `arguments` array.
Additional arguments can be passed as array in second parameter.
-``` php
+```js
// wait for 1200 milliseconds my running `setTimeout`
-$I->executeAsyncJS('setTimeout(arguments[0], 1200)');
+* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
$seconds = 1200; // or seconds are passed as argument
$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
@@ -1116,8 +1125,12 @@ $name = $I->grabValueFrom(['name' => 'username']);
### loadSessionSnapshot
- * `param string` $name
- * `return` bool
+Loads cookies from a saved snapshot.
+Allows to reuse same session across tests without additional login.
+
+See [saveSessionSnapshot](#saveSessionSnapshot)
+
+ * `param` $name
### makeScreenshot
@@ -1297,7 +1310,33 @@ $I->resizeWindow(800, 600);
### saveSessionSnapshot
- * `param string` $name
+Saves current cookies into named snapshot in order to restore them in other tests
+This is useful to save session state between tests.
+For example, if user needs log in to site for each test this scenario can be executed once
+while other tests can just restore saved cookies.
+
+``` php
+loadSessionSnapshot('login')) return;
+
+ // logging in
+ $I->amOnPage('/login');
+ $I->fillField('name', 'jon');
+ $I->fillField('password', '123345');
+ $I->click('Login');
+
+ // saving snapshot
+ $I->saveSessionSnapshot('login');
+}
+?>
+```
+
+ * `param` $name
### scrollTo
diff --git a/docs/modules/Yii1.md b/docs/modules/Yii1.md
index dae9e37d11..3112f39876 100644
--- a/docs/modules/Yii1.md
+++ b/docs/modules/Yii1.md
@@ -1048,6 +1048,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/Yii2.md b/docs/modules/Yii2.md
index e95817f354..de4a150a18 100644
--- a/docs/modules/Yii2.md
+++ b/docs/modules/Yii2.md
@@ -6,6 +6,7 @@ It initializes Yii framework in test environment and provides actions for functi
## Application state during testing
This section details what you can expect when using this module.
* You will get a fresh application in `\Yii::$app` at the start of each test (available in the test and in `_before()`).
+* Inside your test you may change application state; however these changes will be lost when doing a request if you have enabled `recreateApplication`.
* When executing a request via one of the request functions the `request` and `response` component are both recreated.
* After a request the whole application is available for inspection / interaction.
* You may use multiple database connections, each will use a separate transaction; to prevent accidental mistakes we
@@ -20,15 +21,22 @@ will warn you if you try to connect to the same database twice but we cannot reu
* `cleanup` - (default: true) cleanup fixtures after the test
* `ignoreCollidingDSN` - (default: false) When 2 database connections use the same DSN but different settings an exception will be thrown, set this to true to disable this behavior.
* `fixturesMethod` - (default: _fixtures) Name of the method used for creating fixtures.
-
+* `responseCleanMethod` - (default: clear) Method for cleaning the response object. Note that this is only for multiple requests inside a single test case.
+Between test casesthe whole application is always recreated
+* `requestCleanMethod` - (default: recreate) Method for cleaning the request object. Note that this is only for multiple requests inside a single test case.
+Between test cases the whole application is always recreated
+* `recreateComponents` - (default: []) Some components change their state making them unsuitable for processing multiple requests. In production this is usually
+not a problem since web apps tend to die and start over after each request. This allows you to list application components that need to be recreated before each request.
+As a consequence, any components specified here should not be changed inside a test since those changes will get regarded.
+You can use this module by setting params in your functional.suite.yml:
+* `recreateApplication` - (default: false) whether to recreate the whole application before each request
You can use this module by setting params in your functional.suite.yml:
-
```yaml
actor: FunctionalTester
modules:
enabled:
- Yii2:
- configFile: '/path/to/config.php'
+ configFile: 'path/to/config.php'
```
### Parts
@@ -353,6 +361,10 @@ $I->click(['link' => 'Login']);
* `param` $context
+### connectionOpenHandler
+__not documented__
+
+
### createAndSetCsrfCookie
This function creates the CSRF Cookie.
@@ -1287,6 +1299,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/ZF1.md b/docs/modules/ZF1.md
index 6a901dfabd..cefb62e2df 100644
--- a/docs/modules/ZF1.md
+++ b/docs/modules/ZF1.md
@@ -1020,6 +1020,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/ZF2.md b/docs/modules/ZF2.md
index 263c422a75..edc01c6a4b 100644
--- a/docs/modules/ZF2.md
+++ b/docs/modules/ZF2.md
@@ -1029,6 +1029,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/modules/ZendExpressive.md b/docs/modules/ZendExpressive.md
index f0e265a9a8..04b032af71 100644
--- a/docs/modules/ZendExpressive.md
+++ b/docs/modules/ZendExpressive.md
@@ -955,6 +955,34 @@ $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
* `param` $code
+### seeResponseCodeIsBetween
+
+Checks that response code is between a certain range. Between actually means [from <= CODE <= to]
+
+ * `param` $from
+ * `param` $to
+
+
+### seeResponseCodeIsClientError
+
+Checks that the response code is 4xx
+
+
+### seeResponseCodeIsRedirection
+
+Checks that the response code 3xx
+
+
+### seeResponseCodeIsServerError
+
+Checks that the response code is 5xx
+
+
+### seeResponseCodeIsSuccessful
+
+Checks that the response code 2xx
+
+
### selectOption
Selects an option in a select tag or in radio button group.
diff --git a/docs/reference/Locator.md b/docs/reference/Locator.md
index 239dc8697a..ae78463fa6 100644
--- a/docs/reference/Locator.md
+++ b/docs/reference/Locator.md
@@ -165,9 +165,9 @@ Checks that provided string is CSS selector
```php
true
-Locator::isCSS('body'); // => true
-Locator::isCSS('//body/p/user'); // => false
+Locator::isCSS('#user .hello') => true
+Locator::isCSS('body') => true
+Locator::isCSS('//body/p/user') => false
```
* `param` $selector
@@ -183,9 +183,9 @@ Checks that a string is valid CSS class
```php
true
-Locator::isClass('body'); // => false
-Locator::isClass('//body/p/user'); // => false
+Locator::isClass('.hello') => true
+Locator::isClass('body') => false
+Locator::isClass('//body/p/user') => false
```
* `param` $class
@@ -201,9 +201,9 @@ Checks that a string is valid CSS ID
```php
true
-Locator::isID('body'); // => false
-Locator::isID('//body/p/user'); // => false
+Locator::isID('#user') => true
+Locator::isID('body') => false
+Locator::isID('//body/p/user') => false
```
* `param` $id
@@ -228,9 +228,9 @@ Checks that locator is an XPath
```php
false
-Locator::isXPath('body'); // => false
-Locator::isXPath('//body/p/user'); // => true
+Locator::isXPath('#user .hello') => false
+Locator::isXPath('body') => false
+Locator::isXPath('//body/p/user') => true
```
* `param` $locator
diff --git a/docs/reference/Mock.md b/docs/reference/Mock.md
index 8066190e98..20b859e31f 100644
--- a/docs/reference/Mock.md
+++ b/docs/reference/Mock.md
@@ -24,8 +24,8 @@ $this->make(new User, ['name' => 'davert']);
?>
```
-To replace method provide its name as a key in second parameter
-and its return value or callback function as parameter
+To replace method provide it's name as a key in second parameter
+and it's return value or callback function as parameter
``` php
make(
'User',
- array (
+ array(
'getName' => Expected::atLeastOnce('Davert')),
'someMethod' => function() {}
)
@@ -353,7 +353,7 @@ Alternatively, a function can be passed as parameter:
```php
users
->attr('empty','false')
->items
->item
- ->val('useful item')
+ ->val('useful item');
->parents('user')
->active
->val(1);
diff --git a/src/Codeception/Codecept.php b/src/Codeception/Codecept.php
index c144ddb1de..158096ed0b 100644
--- a/src/Codeception/Codecept.php
+++ b/src/Codeception/Codecept.php
@@ -7,7 +7,7 @@
class Codecept
{
- const VERSION = "2.4.2";
+ const VERSION = "2.4.3";
/**
* @var \Codeception\PHPUnit\Runner
diff --git a/tests/data/claypit/composer.lock b/tests/data/claypit/composer.lock
index 8d03452074..c1bef1de0a 100644
--- a/tests/data/claypit/composer.lock
+++ b/tests/data/claypit/composer.lock
@@ -14,12 +14,12 @@
"source": {
"type": "git",
"url": "https://github.com/Codeception/c3.git",
- "reference": "c7348bbc82da82834fe237c5fb754003ac0fe782"
+ "reference": "f7e31fce8a9abf1021990b4e31a7ed01689f4295"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Codeception/c3/zipball/c7348bbc82da82834fe237c5fb754003ac0fe782",
- "reference": "c7348bbc82da82834fe237c5fb754003ac0fe782",
+ "url": "https://api.github.com/repos/Codeception/c3/zipball/f7e31fce8a9abf1021990b4e31a7ed01689f4295",
+ "reference": "f7e31fce8a9abf1021990b4e31a7ed01689f4295",
"shasum": ""
},
"require": {
@@ -56,7 +56,7 @@
"code coverage",
"codecoverage"
],
- "time": "2018-02-19 11:27:45"
+ "time": "2018-05-26 21:53:33"
}
],
"aliases": [],
From c04934dff6ffdf718a1bebe3345c3170cbe1b841 Mon Sep 17 00:00:00 2001
From: Sam
Date: Thu, 28 Jun 2018 17:04:49 +0200
Subject: [PATCH 067/395] =?UTF-8?q?Unbind=20specific=20event=20handler=20i?=
=?UTF-8?q?nstead=20of=20all=20class=20level=20events=20when=20=E2=80=A6?=
=?UTF-8?q?=20(#5045)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Unbind specific event handler instead of all class level events when loading fixtures
* Refactored connecition / transaction watching to separate classes.
* Fixed Nitpick-CI
* Use the connection watcher for closing fixture connections as well.
* Prevent crash in case database connection for a transaction is closed
---
.../Lib/Connector/Yii2/ConnectionWatcher.php | 67 ++++++++++
.../Lib/Connector/Yii2/TransactionForcer.php | 97 +++++++++++++++
src/Codeception/Module/Yii2.php | 116 ++++--------------
3 files changed, 191 insertions(+), 89 deletions(-)
create mode 100644 src/Codeception/Lib/Connector/Yii2/ConnectionWatcher.php
create mode 100644 src/Codeception/Lib/Connector/Yii2/TransactionForcer.php
diff --git a/src/Codeception/Lib/Connector/Yii2/ConnectionWatcher.php b/src/Codeception/Lib/Connector/Yii2/ConnectionWatcher.php
new file mode 100644
index 0000000000..eae5382bc1
--- /dev/null
+++ b/src/Codeception/Lib/Connector/Yii2/ConnectionWatcher.php
@@ -0,0 +1,67 @@
+handler = function (Event $event) {
+ if ($event->sender instanceof Connection) {
+ $this->connectionOpened($event->sender);
+ }
+ };
+ }
+
+ protected function connectionOpened(Connection $connection)
+ {
+ $this->debug('Connection opened!');
+ if ($connection instanceof Connection) {
+ $this->connections[] = $connection;
+ }
+ }
+
+ public function start()
+ {
+ Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, $this->handler);
+ $this->debug('watching new connections');
+ }
+
+ public function stop()
+ {
+ Event::off(Connection::class, Connection::EVENT_AFTER_OPEN, $this->handler);
+ $this->debug('no longer watching new connections');
+ }
+
+ public function closeAll()
+ {
+ $count = count($this->connections);
+ $this->debug("closing all ($count) connections");
+ foreach ($this->connections as $connection) {
+ $connection->close();
+ }
+ }
+
+ protected function debug($message)
+ {
+ $title = (new \ReflectionClass($this))->getShortName();
+ if (is_array($message) or is_object($message)) {
+ $message = stripslashes(json_encode($message));
+ }
+ codecept_debug("[$title] $message");
+ }
+}
diff --git a/src/Codeception/Lib/Connector/Yii2/TransactionForcer.php b/src/Codeception/Lib/Connector/Yii2/TransactionForcer.php
new file mode 100644
index 0000000000..060b8a13f2
--- /dev/null
+++ b/src/Codeception/Lib/Connector/Yii2/TransactionForcer.php
@@ -0,0 +1,97 @@
+ignoreCollidingDSN = $ignoreCollidingDSN;
+ }
+
+
+ protected function connectionOpened(Connection $connection)
+ {
+ parent::connectionOpened($connection);
+ /**
+ * We should check if the known PDO objects are the same, in which case we should reuse the PDO
+ * object so only 1 transaction is started and multiple connections to the same database see the
+ * same data (due to writes inside a transaction not being visible from the outside).
+ *
+ */
+ $key = md5(json_encode([
+ 'dsn' => $connection->dsn,
+ 'user' => $connection->username,
+ 'pass' => $connection->password,
+ 'attributes' => $connection->attributes,
+ 'emulatePrepare' => $connection->emulatePrepare,
+ 'charset' => $connection->charset
+ ]));
+
+ /*
+ * If keys match we assume connections are "similar enough".
+ */
+ if (isset($this->pdoCache[$key])) {
+ $connection->pdo = $this->pdoCache[$key];
+ } else {
+ $this->pdoCache[$key] = $connection->pdo;
+ }
+
+ if (isset($this->dsnCache[$connection->dsn])
+ && $this->dsnCache[$connection->dsn] !== $key
+ && !$this->ignoreCollidingDSN
+ ) {
+ $this->debug(<<dsn}) with different configuration.
+These connections will not see the same database state since we cannot share a transaction between different PDO
+instances.
+You can remove this message by adding 'ignoreCollidingDSN = true' in the module configuration.
+TEXT
+ );
+ Debug::pause();
+ }
+
+ if (isset($this->transactions[$key])) {
+ $this->debug('Reusing PDO, so no need for a new transaction');
+ return;
+ }
+
+ $this->debug('Transaction started for: ' . $connection->dsn);
+ $this->transactions[$key] = $connection->beginTransaction();
+ }
+
+ public function rollbackAll()
+ {
+ /** @var Transaction $transaction */
+ foreach ($this->transactions as $transaction) {
+ if ($transaction->db->isActive) {
+ $transaction->rollBack();
+ $this->debug('Transaction cancelled; all changes reverted.');
+ }
+ }
+
+ $this->transactions = [];
+ $this->pdoCache = [];
+ $this->dsnCache = [];
+ }
+}
diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php
index 213e2b8983..b4826cc435 100644
--- a/src/Codeception/Module/Yii2.php
+++ b/src/Codeception/Module/Yii2.php
@@ -167,22 +167,21 @@ class Yii2 extends Framework implements ActiveRecord, PartedModule
protected $requiredFields = ['configFile'];
/**
- * @var array Array of Transaction objects indexed by a string key
- */
- private $transactions = [];
- /**
- * @var \PDO[] Array of PDO objects indexed by a string key
+ * @var Yii2Connector\FixturesStore[]
*/
- private $pdoCache = [];
+ public $loadedFixtures = [];
+
/**
- * @var string[] Array of cache keys indexes by their DSN
+ * Helper to manage database connections
+ * @var Yii2Connector\ConnectionWatcher
*/
- private $dsnCache = [];
+ private $connectionWatcher;
/**
- * @var Yii2Connector\FixturesStore[]
+ * Helper to force database transaction
+ * @var Yii2Connector\TransactionForcer
*/
- public $loadedFixtures = [];
+ private $transactionForcer;
/**
* @var array The contents of $_SERVER upon initialization of this object.
@@ -299,6 +298,9 @@ public function _before(TestInterface $test)
$this->recreateClient();
$this->client->startApp();
+ $this->connectionWatcher = new Yii2Connector\ConnectionWatcher();
+ $this->connectionWatcher->start();
+
// load fixtures before db transaction
if ($test instanceof \Codeception\Test\Cest) {
$this->loadFixtures($test->getTestClass());
@@ -306,6 +308,7 @@ public function _before(TestInterface $test)
$this->loadFixtures($test);
}
+
$this->startTransactions();
}
@@ -317,24 +320,14 @@ public function _before(TestInterface $test)
private function loadFixtures($test)
{
$this->debugSection('Fixtures', 'Loading fixtures');
- /** @var Connection[] $connections */
- $connections = [];
- // Register event handler.
- Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, function (Event $event) use (&$connections) {
- $this->debugSection('Fixtures', 'Opened database connection: ' . $event->sender->dsn);
- $connections[] = $event->sender;
- });
if (empty($this->loadedFixtures)
&& method_exists($test, $this->_getConfig('fixturesMethod'))
) {
+ $connectionWatcher = new Yii2Connector\ConnectionWatcher();
+ $connectionWatcher->start();
$this->haveFixtures(call_user_func([$test, $this->_getConfig('fixturesMethod')]));
- }
-
- Event::offAll();
- // Close all connections so they get properly reopened after the transaction handler has been attached.
- foreach ($connections as $connection) {
- $this->debugSection('Fixtures', 'Closing database connection: ' . $connection->dsn);
- $connection->close();
+ $connectionWatcher->stop();
+ $connectionWatcher->closeAll();
}
$this->debugSection('Fixtures', 'Done');
}
@@ -350,6 +343,10 @@ public function _after(TestInterface $test)
$this->rollbackTransactions();
+ $this->connectionWatcher->stop();
+ $this->connectionWatcher->closeAll();
+ unset($this->connectionWatcher);
+
if ($this->config['cleanup']) {
foreach ($this->loadedFixtures as $fixture) {
$fixture->unloadFixtures();
@@ -365,80 +362,21 @@ public function _after(TestInterface $test)
parent::_after($test);
}
- public function connectionOpenHandler(Event $event)
- {
- if ($event->sender instanceof Connection) {
- $connection = $event->sender;
- /*
- * We should check if the known PDO objects are the same, in which case we should reuse the PDO
- * object so only 1 transaction is started and multiple connections to the same database see the
- * same data (due to writes inside a transaction not being visible from the outside).
- *
- */
- $key = md5(json_encode([
- 'dsn' => $connection->dsn,
- 'user' => $connection->username,
- 'pass' => $connection->password,
- 'attributes' => $connection->attributes,
- 'emulatePrepare' => $connection->emulatePrepare,
- 'charset' => $connection->charset
- ]));
-
- /*
- * If keys match we assume connections are "similar enough".
- */
- if (isset($this->pdoCache[$key])) {
- $connection->pdo = $this->pdoCache[$key];
- } else {
- $this->pdoCache[$key] = $connection->pdo;
- }
-
- if (isset($this->dsnCache[$connection->dsn])
- && $this->dsnCache[$connection->dsn] !== $key
- && !$this->config['ignoreCollidingDSN']
- ) {
- $this->debugSection('WARNING', <<dsn}) with different configuration.
-These connections will not see the same database state since we cannot share a transaction between different PDO
-instances.
-You can remove this message by adding 'ignoreCollidingDSN = true' in the module configuration.
-TEXT
- );
- Debug::pause();
- }
-
- if (isset($this->transactions[$key])) {
- $this->debugSection('Database', 'Reusing PDO, so no need for a new transaction');
- return;
- }
-
- $this->debugSection('Database', 'Transaction started for: ' . $connection->dsn);
- $this->transactions[$key] = $connection->beginTransaction();
- }
-
- }
-
protected function startTransactions()
{
if ($this->config['transaction']) {
- // This should register handlers that start a transaction whenever a connection opens and add it to the transactions array.
- $this->debug('Transaction', 'Registering connection event handler');
- Event::on(Connection::class, Connection::EVENT_AFTER_OPEN, [$this, 'connectionOpenHandler']);
+ $this->transactionForcer = new Yii2Connector\TransactionForcer($this->config['ignoreCollidingDSN']);
+ $this->transactionForcer->start();
}
}
protected function rollbackTransactions()
{
- $this->debugSection('Transaction', 'Rolling back ' . count($this->transactions) . ' transactions');
- Event::off(Connection::class, Connection::EVENT_AFTER_OPEN, [$this, 'connectionOpenHandler']);
- /** @var Transaction $transaction */
- foreach ($this->transactions as $transaction) {
- $transaction->rollBack();
- $this->debugSection('Database', 'Transaction cancelled; all changes reverted.');
+ if (isset($this->transactionForcer)) {
+ $this->transactionForcer->rollbackAll();
+ $this->transactionForcer->stop();
+ unset($this->transactionForcer);
}
- $this->transactions = [];
- $this->pdoCache = [];
- $this->dsnCache = [];
}
public function _parts()
From 7b9d40c3b5c4197dd64db451f7bf8dcb17db8e2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=CE=9Erw=E1=B4=A7n=20Rich=E1=B4=A7rd?=
Date: Mon, 2 Jul 2018 11:44:08 +0000
Subject: [PATCH 068/395] Fix typo (#5052)
---
src/Codeception/Module/Doctrine2.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Codeception/Module/Doctrine2.php b/src/Codeception/Module/Doctrine2.php
index b60293d13e..479ba625e8 100644
--- a/src/Codeception/Module/Doctrine2.php
+++ b/src/Codeception/Module/Doctrine2.php
@@ -305,7 +305,7 @@ public function haveFakeRepository($classname, $methods = [])
/**
* Persists record into repository.
- * This method crates an entity, and sets its properties directly (via reflection).
+ * This method creates an entity, and sets its properties directly (via reflection).
* Setters of entity won't be executed, but you can create almost any entity and save it to database.
* Returns id using `getId` of newly created entity.
*
From ce7d225b2df3569d312a7cd248dbefedd99c9003 Mon Sep 17 00:00:00 2001
From: Aleksandr
Date: Thu, 5 Jul 2018 11:19:26 +0300
Subject: [PATCH 069/395] Typo fix (#5057) [skip ci]
---
docs/02-GettingStarted.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/02-GettingStarted.md b/docs/02-GettingStarted.md
index bc3fb3174e..e007d484f7 100644
--- a/docs/02-GettingStarted.md
+++ b/docs/02-GettingStarted.md
@@ -14,16 +14,16 @@ Codeception follows simple naming rules to make it easy to remember (as well as
click('Login');
$I->fillField('#input-username', 'John Dough');
- $i->pressKey('#input-remarks', 'foo');
+ $I->pressKey('#input-remarks', 'foo');
```
* **Assertions** always start with "see" or "dontSee". Examples:
```php
see('Welcome');
$I->seeInTitle('My Company');
- $i->seeElement('nav');
- $i->dontSeeElement('#error-message');
- $i->dontSeeInPageSource('');
+ $I->seeElement('nav');
+ $I->dontSeeElement('#error-message');
+ $I->dontSeeInPageSource('');
```
* **Grabbers** just *read* something from the page, but don't process it. The return value of those are meant to be saved as variables and used later. Example:
```php
From f942fc6ce0f6516e97f80023db76cbbe0053659c Mon Sep 17 00:00:00 2001
From: Aleksandr
Date: Fri, 6 Jul 2018 01:44:46 +0300
Subject: [PATCH 070/395] Typo fix in phpdoc (#5060)
---
ext/Recorder.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ext/Recorder.php b/ext/Recorder.php
index e02945e853..6059bdf630 100644
--- a/ext/Recorder.php
+++ b/ext/Recorder.php
@@ -39,7 +39,7 @@
* ``` yaml
* extensions:
* enabled:
- * Codeception\Extension\Recorder:
+ * - Codeception\Extension\Recorder:
* module: AngularJS # enable for Angular
* delete_successful: false # keep screenshots of successful tests
* ```
From 85342fd574660c649ece8a7a54aadfe38d01c880 Mon Sep 17 00:00:00 2001
From: Martin Bohal
Date: Fri, 6 Jul 2018 00:50:18 +0200
Subject: [PATCH 071/395] Symfony test email count (#5059)
* Improve testing sent emails in Symfony
* fixup! Improve testing sent emails in Symfony
* fixup! fixup! Improve testing sent emails in Symfony
---
src/Codeception/Module/Symfony.php | 46 +++++++++++++++++++++++++++---
1 file changed, 42 insertions(+), 4 deletions(-)
diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php
index d9674fbee7..6de5947c73 100644
--- a/src/Codeception/Module/Symfony.php
+++ b/src/Codeception/Module/Symfony.php
@@ -445,11 +445,18 @@ public function seeInCurrentRoute($routeName)
}
/**
- * Checks if any email were sent by last request
+ * Checks if the desired number of emails was sent.
+ * If no argument is provided then at least one email must be sent to satisfy the check.
*
- * @throws \LogicException
+ * ``` php
+ * seeEmailIsSent(2);
+ * ?>
+ * ```
+ *
+ * @param null|int $expectedCount
*/
- public function seeEmailIsSent()
+ public function seeEmailIsSent($expectedCount = null)
{
$profile = $this->getProfile();
if (!$profile) {
@@ -459,7 +466,38 @@ public function seeEmailIsSent()
$this->fail('Emails can\'t be tested without SwiftMailer connector');
}
- $this->assertGreaterThan(0, $profile->getCollector('swiftmailer')->getMessageCount());
+ if (!is_int($expectedCount) && !is_null($expectedCount)) {
+ $this->fail(sprintf(
+ 'The required number of emails must be either an integer or null. "%s" was provided.',
+ print_r($expectedCount, true)
+ ));
+ }
+
+ $realCount = $profile->getCollector('swiftmailer')->getMessageCount();
+ if ($expectedCount === null) {
+ $this->assertGreaterThan(0, $realCount);
+ } else {
+ $this->assertEquals(
+ $expectedCount,
+ $realCount,
+ sprintf(
+ 'Expected number of sent emails was %d, but in reality %d %s sent.',
+ $expectedCount,
+ $realCount,
+ $realCount === 2 ? 'was' : 'were'
+ )
+ );
+ }
+ }
+
+ /**
+ * Checks that no email was sent. This is an alias for seeEmailIsSent(0).
+ *
+ * @part email
+ */
+ public function dontSeeEmailIsSent()
+ {
+ $this->seeEmailIsSent(0);
}
/**
From 21fb2ffd1148cd0f761ecd3fe53ad80c361a8999 Mon Sep 17 00:00:00 2001
From: Dmytro Naumenko
Date: Tue, 10 Jul 2018 13:20:10 +0300
Subject: [PATCH 072/395] Allow absolute paths in `extends` property of configs
(#5061)
* Updated Configuration::loadSuiteConfig() to respect absolute paths in `extends` parameter
* Allow abspath for `extends` property in Configuration::config()
* Added unit tests to confirm config extending works
* Updated CHANGELOG
* Removed excess changes ConfigurationTest
* Fixed comments to PR
* minor
---
CHANGELOG-2.4.md | 5 ++++
autoload.php | 20 +++++++++++++-
src/Codeception/Configuration.php | 7 +++--
tests/cli/ConfigExtendsCest.php | 17 ++++++++++++
.../config_extends/codeception.common.yml | 13 ++++++++++
tests/data/config_extends/codeception.yml | 2 ++
.../config_extends/tests/_output/.gitignore | 2 ++
.../tests/_support/UnitTester.php | 26 +++++++++++++++++++
.../tests/_support/_generated/.gitignore | 2 ++
.../tests/unit.suite.common.yml | 3 +++
.../data/config_extends/tests/unit.suite.yml | 6 +++++
.../config_extends/tests/unit/UnitCest.php | 9 +++++++
tests/unit/Codeception/ConfigurationTest.php | 3 +++
13 files changed, 112 insertions(+), 3 deletions(-)
create mode 100644 tests/cli/ConfigExtendsCest.php
create mode 100644 tests/data/config_extends/codeception.common.yml
create mode 100644 tests/data/config_extends/codeception.yml
create mode 100644 tests/data/config_extends/tests/_output/.gitignore
create mode 100644 tests/data/config_extends/tests/_support/UnitTester.php
create mode 100644 tests/data/config_extends/tests/_support/_generated/.gitignore
create mode 100644 tests/data/config_extends/tests/unit.suite.common.yml
create mode 100644 tests/data/config_extends/tests/unit.suite.yml
create mode 100644 tests/data/config_extends/tests/unit/UnitCest.php
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index cde1c9fe25..60e71a711f 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -1,3 +1,8 @@
+#### 2.4.4
+
+* Recently added `extends` property in the `codeception.yml` and `*.suite.yml` files now support absolute paths; by @silverfire
+* Fixed absolute paths handling on Windows in ParamLoader; by @silverfire
+
#### 2.4.3
* [Create your own test formats](https://codeception.com/docs/07-AdvancedUsage#Formats) (e.g., Cept, Cest, ...); by @mlambley
diff --git a/autoload.php b/autoload.php
index ee043a39b6..e15b1413c0 100644
--- a/autoload.php
+++ b/autoload.php
@@ -113,6 +113,24 @@ function codecept_relative_path($path)
*/
function codecept_absolute_path($path)
{
- return mb_substr($path, 0, 1) === DIRECTORY_SEPARATOR ? $path : codecept_root_dir($path);
+ return codecept_is_path_absolute($path) ? $path : codecept_root_dir($path);
+ }
+}
+
+if (!function_exists('codecept_is_path_absolute')) {
+ /**
+ * Check whether the given $path is absolute.
+ *
+ * @param string $path
+ * @return bool
+ * @since 2.4.4
+ */
+ function codecept_is_path_absolute($path)
+ {
+ if (DIRECTORY_SEPARATOR === '/') {
+ return mb_substr($path, 0, 1) === DIRECTORY_SEPARATOR;
+ }
+
+ return preg_match('#^[A-Z]:(?![^/\\])#i', $path) === 1;
}
}
diff --git a/src/Codeception/Configuration.php b/src/Codeception/Configuration.php
index 2732d82cf7..92e8061490 100644
--- a/src/Codeception/Configuration.php
+++ b/src/Codeception/Configuration.php
@@ -186,7 +186,7 @@ public static function config($configFile = null)
// we check for the "extends" key in the yml file
if (isset($config['extends'])) {
// and now we search for the file
- $presetFilePath = realpath(self::$dir . DIRECTORY_SEPARATOR . $config['extends']);
+ $presetFilePath = codecept_absolute_path($config['extends']);
if (file_exists($presetFilePath)) {
// and merge it with our configuration file
$config = self::mergeConfigs(self::getConfFromFile($presetFilePath), $config);
@@ -690,7 +690,10 @@ protected static function loadSuiteConfig($suite, $path, $settings)
// now we check the suite config file, if a extends key is defined
if (isset($suiteConf['extends'])) {
- $presetFilePath = realpath($suiteDir . DIRECTORY_SEPARATOR . $suiteConf['extends']);
+ $presetFilePath = codecept_is_path_absolute($suiteConf['extends'])
+ ? $suiteConf['extends'] // If path is absolute – use it
+ : realpath($suiteDir . DIRECTORY_SEPARATOR . $suiteConf['extends']); // Otherwise try to locate it in the suite dir
+
if (file_exists($presetFilePath)) {
$settings = self::mergeConfigs(self::getConfFromFile($presetFilePath), $settings);
}
diff --git a/tests/cli/ConfigExtendsCest.php b/tests/cli/ConfigExtendsCest.php
new file mode 100644
index 0000000000..eef07ce7c3
--- /dev/null
+++ b/tests/cli/ConfigExtendsCest.php
@@ -0,0 +1,17 @@
+amInPath('tests/data/config_extends');
+ $I->executeCommand('run');
+
+ $I->seeInShellOutput('UnitCest');
+ $I->seeInShellOutput('OK (1 test, 1 assertion)');
+ $I->dontSeeInShellOutput('Exception');
+ }
+}
diff --git a/tests/data/config_extends/codeception.common.yml b/tests/data/config_extends/codeception.common.yml
new file mode 100644
index 0000000000..018c7db57e
--- /dev/null
+++ b/tests/data/config_extends/codeception.common.yml
@@ -0,0 +1,13 @@
+paths:
+ tests: tests
+ log: tests/_output
+ data: tests/_data
+ support: tests/_support
+ envs: tests/_envs
+settings:
+ bootstrap: _bootstrap.php
+ colors: true
+ memory_limit: 2048M
+extensions:
+ enabled:
+ - Codeception\Extension\RunFailed
diff --git a/tests/data/config_extends/codeception.yml b/tests/data/config_extends/codeception.yml
new file mode 100644
index 0000000000..073df879c5
--- /dev/null
+++ b/tests/data/config_extends/codeception.yml
@@ -0,0 +1,2 @@
+actor: Tester
+extends: codeception.common.yml
diff --git a/tests/data/config_extends/tests/_output/.gitignore b/tests/data/config_extends/tests/_output/.gitignore
new file mode 100644
index 0000000000..c96a04f008
--- /dev/null
+++ b/tests/data/config_extends/tests/_output/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/tests/data/config_extends/tests/_support/UnitTester.php b/tests/data/config_extends/tests/_support/UnitTester.php
new file mode 100644
index 0000000000..28353572c1
--- /dev/null
+++ b/tests/data/config_extends/tests/_support/UnitTester.php
@@ -0,0 +1,26 @@
+assertTrue(true);
+ }
+}
diff --git a/tests/unit/Codeception/ConfigurationTest.php b/tests/unit/Codeception/ConfigurationTest.php
index 45422539a2..a263b6bca1 100644
--- a/tests/unit/Codeception/ConfigurationTest.php
+++ b/tests/unit/Codeception/ConfigurationTest.php
@@ -65,5 +65,8 @@ public function testDefaultCustomCommandConfig()
$commandsConfig = $defaultConfig['extensions'];
$this->assertArrayHasKey('commands', $commandsConfig);
+
+ $this->assertArrayHasKey('extends', $defaultConfig);
+ $this->assertNull($defaultConfig['extends']);
}
}
From 37fb9c6a6a2215f2826933f92bd9b42d7c7f0ac8 Mon Sep 17 00:00:00 2001
From: Johannes Schobel
Date: Tue, 10 Jul 2018 14:02:20 +0200
Subject: [PATCH 073/395] [WIP] Start using assert() and not fail() (#5063)
* start using assert() and not fail()
* style
---
src/Codeception/Module/Laravel5.php | 55 +++++++++++++++--------------
1 file changed, 28 insertions(+), 27 deletions(-)
diff --git a/src/Codeception/Module/Laravel5.php b/src/Codeception/Module/Laravel5.php
index 54357d3cb8..ab3663a6c1 100644
--- a/src/Codeception/Module/Laravel5.php
+++ b/src/Codeception/Module/Laravel5.php
@@ -247,7 +247,7 @@ protected function checkBootstrapFileExists()
throw new ModuleConfigException(
$this,
"Laravel bootstrap file not found in $bootstrapFile.\n"
- . "Please provide a valid path to it using 'bootstrap' config param. "
+ . "Please provide a valid path by using the 'bootstrap' config param. "
);
}
}
@@ -442,7 +442,6 @@ public function callArtisan($command, $parameters = [], OutputInterface $output
}
$console->call($command, $parameters, $output);
-
}
/**
@@ -659,14 +658,13 @@ public function seeSessionHasValues(array $bindings)
* ?>
* ```
*
- * @return bool
+ * @return void
*/
public function seeFormHasErrors()
{
$viewErrorBag = $this->app->make('view')->shared('errors');
- if (count($viewErrorBag) == 0) {
- $this->fail("There are no form errors");
- }
+
+ $this->assertGreaterThan(0, count($viewErrorBag), 'Expecting that the form has errors, but there were none!');
}
/**
@@ -678,14 +676,13 @@ public function seeFormHasErrors()
* ?>
* ```
*
- * @return bool
+ * @return void
*/
public function dontSeeFormErrors()
{
$viewErrorBag = $this->app->make('view')->shared('errors');
- if (count($viewErrorBag) > 0) {
- $this->fail("Found the following form errors: \n\n" . $viewErrorBag->toJson(JSON_PRETTY_PRINT));
- }
+
+ $this->assertEquals(0, count($viewErrorBag), 'Expecting that the form does not have errors, but there were!');
}
/**
@@ -778,9 +775,7 @@ public function amLoggedAs($user, $driver = null)
return;
}
- if (! $guard->attempt($user)) {
- $this->fail("Failed to login with credentials " . json_encode($user));
- }
+ $this->assertTrue($guard->attempt($user), 'Failed to login with credentials ' . json_encode($user));
}
/**
@@ -804,9 +799,7 @@ public function seeAuthentication($guard = null)
$auth = $auth->guard($guard);
}
- if (! $auth->check()) {
- $this->fail("There is no authenticated user");
- }
+ $this->assertTrue($auth->check(), 'There is no authenticated user');
}
/**
@@ -822,9 +815,7 @@ public function dontSeeAuthentication($guard = null)
$auth = $auth->guard($guard);
}
- if ($auth->check()) {
- $this->fail("There is an authenticated user");
- }
+ $this->assertNotTrue($auth->check(), 'There is an user authenticated');
}
/**
@@ -868,8 +859,9 @@ public function grabService($class)
* ```
*
* @param string $table
- * @param array $attributes
- * @return integer|EloquentModel
+ * @param array $attributes
+ * @return EloquentModel|int
+ * @throws \RuntimeException
* @part orm
*/
public function haveRecord($table, $attributes = [])
@@ -917,6 +909,8 @@ public function seeRecord($table, $attributes = [])
} elseif (! $this->findRecord($table, $attributes)) {
$this->fail("Could not find matching record in table '$table'");
}
+
+ $this->assertTrue(true);
}
/**
@@ -943,6 +937,8 @@ public function dontSeeRecord($table, $attributes = [])
} elseif ($this->findRecord($table, $attributes)) {
$this->fail("Unexpectedly found matching record in table '$table'");
}
+
+ $this->assertTrue(true);
}
/**
@@ -999,14 +995,18 @@ public function seeNumRecords($expectedNum, $table, $attributes = [])
{
if (class_exists($table)) {
$currentNum = $this->countModels($table, $attributes);
- if ($currentNum != $expectedNum) {
- $this->fail("The number of found $table ($currentNum) does not match expected number $expectedNum with " . json_encode($attributes));
- }
+ $this->assertEquals(
+ $expectedNum,
+ $currentNum,
+ "The number of found {$table} ({$currentNum}) does not match expected number {$expectedNum} with " . json_encode($attributes)
+ );
} else {
$currentNum = $this->countRecords($table, $attributes);
- if ($currentNum != $expectedNum) {
- $this->fail("The number of found records ($currentNum) does not match expected number $expectedNum in table $table with " . json_encode($attributes));
- }
+ $this->assertEquals(
+ $expectedNum,
+ $currentNum,
+ "The number of found records in table {$table} ({$currentNum}) does not match expected number $expectedNum with " . json_encode($attributes)
+ );
}
}
@@ -1096,6 +1096,7 @@ protected function countRecords($table, $attributes = [])
* @param string $modelClass
*
* @return EloquentModel
+ * @throws \RuntimeException
*/
protected function getQueryBuilderFromModel($modelClass)
{
From 51b8cba4be0589e632aaf3ea01d7e1e9a4594858 Mon Sep 17 00:00:00 2001
From: Patrik Foldes
Date: Tue, 10 Jul 2018 15:02:53 +0300
Subject: [PATCH 074/395] Added new option to Recorder extension to disable
recording of specified steps (#5015)
* Added new option to Recorder extension to disable recording of specified steps
* Added wildcard support to ignore_steps configuration option of the Recorder extension
---
ext/Recorder.php | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/ext/Recorder.php b/ext/Recorder.php
index 6059bdf630..e87f81a942 100644
--- a/ext/Recorder.php
+++ b/ext/Recorder.php
@@ -7,6 +7,7 @@
use Codeception\Exception\ExtensionException;
use Codeception\Lib\Interfaces\ScreenshotSaver;
use Codeception\Module\WebDriver;
+use Codeception\Step;
use Codeception\Step\Comment as CommentStep;
use Codeception\Test\Descriptor;
use Codeception\Util\FileSystem;
@@ -32,6 +33,7 @@
*
* * `delete_successful` (default: true) - delete screenshots for successfully passed tests (i.e. log only failed and errored tests).
* * `module` (default: WebDriver) - which module for screenshots to use. Set `AngularJS` if you want to use it with AngularJS module. Generally, the module should implement `Codeception\Lib\Interfaces\ScreenshotSaver` interface.
+ * * `ignore_steps` (default: []) - array of step names that should not be recorded, * wildcards supported
*
*
* #### Examples:
@@ -42,6 +44,7 @@
* - Codeception\Extension\Recorder:
* module: AngularJS # enable for Angular
* delete_successful: false # keep screenshots of successful tests
+ * ignore_steps: [have, grab*]
* ```
*
*/
@@ -51,7 +54,8 @@ class Recorder extends \Codeception\Extension
'delete_successful' => true,
'module' => 'WebDriver',
'template' => null,
- 'animate_slides' => true
+ 'animate_slides' => true,
+ 'ignore_steps' => []
];
protected $template = <<getStep() instanceof CommentStep) {
return;
}
+ if ($this->isStepIgnored($e->getStep())) {
+ return;
+ }
$filename = str_pad($this->stepNum, 3, "0", STR_PAD_LEFT) . '.png';
$this->webDriverModule->_saveScreenshot($this->dir . DIRECTORY_SEPARATOR . $filename);
$this->stepNum++;
$this->slides[$filename] = $e->getStep();
}
+
+ /**
+ * @param Step $step
+ * @return bool
+ */
+ protected function isStepIgnored($step)
+ {
+ foreach ($this->config['ignore_steps'] as $stepPattern) {
+ $stepRegexp = '/^' . str_replace('*', '.*?', $stepPattern) . '$/i';
+ if (preg_match($stepRegexp, $step->getAction())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
From 392b7e4528a805ca4591bd98936b311527c495f2 Mon Sep 17 00:00:00 2001
From: Michael Bodnarchuk
Date: Wed, 11 Jul 2018 17:49:10 +0300
Subject: [PATCH 075/395] Fixed "No Session Timeout" fatal error in WebDriver
(#5070)
---
src/Codeception/Module/WebDriver.php | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index 0848e1755e..0bb4274899 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -507,7 +507,12 @@ public function _after(TestInterface $test)
return;
}
if ($this->config['clear_cookies'] && isset($this->webDriver)) {
- $this->webDriver->manage()->deleteAllCookies();
+ try {
+ $this->webDriver->manage()->deleteAllCookies();
+ } catch (\Exception $e) {
+ // may cause fatal errors when not handled
+ $this->debug("Error, can't clean cookies after a test: " . $e->getMessage());
+ }
}
}
From 888b6a6d6ef37a4433849a1e60bc70efcfc1cd74 Mon Sep 17 00:00:00 2001
From: Chuck Burgess
Date: Wed, 11 Jul 2018 09:49:29 -0500
Subject: [PATCH 076/395] add config option for session lock wait setting (and
Oracle implementation); (#5069)
---
docs/modules/Db.md | 2 ++
src/Codeception/Lib/Driver/Db.php | 11 ++++++++++-
src/Codeception/Lib/Driver/Oci.php | 4 ++++
src/Codeception/Module/Db.php | 18 +++++++++++++-----
4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/docs/modules/Db.md b/docs/modules/Db.md
index 73d9356274..611f920a77 100644
--- a/docs/modules/Db.md
+++ b/docs/modules/Db.md
@@ -35,6 +35,7 @@ if you run into problems loading dumps and cleaning databases.
* populate: false - whether the the dump should be loaded before the test suite is started
* cleanup: false - whether the dump should be reloaded before each test
* reconnect: false - whether the module should reconnect to the database before each test
+* waitlock: 0 - wait lock (in seconds) that the database session should use for DDL statements
* ssl_key - path to the SSL key (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-key)
* ssl_cert - path to the SSL certificate (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-ssl-cert)
* ssl_ca - path to the SSL certificate authority (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-ssl-ca)
@@ -51,6 +52,7 @@ if you run into problems loading dumps and cleaning databases.
populate: true
cleanup: true
reconnect: true
+ waitlock: 10
ssl_key: '/path/to/client-key.pem'
ssl_cert: '/path/to/client-cert.pem'
ssl_ca: '/path/to/ca-cert.pem'
diff --git a/src/Codeception/Lib/Driver/Db.php b/src/Codeception/Lib/Driver/Db.php
index 601b81bbf1..2c3fd1a2ab 100755
--- a/src/Codeception/Lib/Driver/Db.php
+++ b/src/Codeception/Lib/Driver/Db.php
@@ -121,6 +121,15 @@ public function cleanup()
{
}
+ /**
+ * Set the lock waiting interval for the database session
+ * @param int $seconds
+ * @return void
+ */
+ public function setWaitLock($seconds)
+ {
+ }
+
public function load($sql)
{
$query = '';
@@ -224,7 +233,7 @@ protected function generateWhereClause(array &$criteria)
return 'WHERE ' . implode('AND ', $params);
}
-
+
/**
* @deprecated use deleteQueryByCriteria instead
*/
diff --git a/src/Codeception/Lib/Driver/Oci.php b/src/Codeception/Lib/Driver/Oci.php
index 07b638e943..d75f8d497c 100644
--- a/src/Codeception/Lib/Driver/Oci.php
+++ b/src/Codeception/Lib/Driver/Oci.php
@@ -3,6 +3,10 @@
class Oci extends Db
{
+ public function setWaitLock($seconds)
+ {
+ $this->dbh->exec('ALTER SESSION SET ddl_lock_timeout = ' . (int) $seconds);
+ }
public function cleanup()
{
diff --git a/src/Codeception/Module/Db.php b/src/Codeception/Module/Db.php
index 2e372a8f44..3f7150e61a 100644
--- a/src/Codeception/Module/Db.php
+++ b/src/Codeception/Module/Db.php
@@ -45,6 +45,7 @@
* * populate: false - whether the the dump should be loaded before the test suite is started
* * cleanup: false - whether the dump should be reloaded before each test
* * reconnect: false - whether the module should reconnect to the database before each test
+ * * waitlock: 0 - wait lock (in seconds) that the database session should use for DDL statements
* * ssl_key - path to the SSL key (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-key)
* * ssl_cert - path to the SSL certificate (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-ssl-cert)
* * ssl_ca - path to the SSL certificate authority (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-ssl-ca)
@@ -61,6 +62,7 @@
* populate: true
* cleanup: true
* reconnect: true
+ * waitlock: 10
* ssl_key: '/path/to/client-key.pem'
* ssl_cert: '/path/to/client-cert.pem'
* ssl_ca: '/path/to/ca-cert.pem'
@@ -201,6 +203,7 @@ class Db extends CodeceptionModule implements DbInterface
'populate' => false,
'cleanup' => false,
'reconnect' => false,
+ 'waitlock' => 0,
'dump' => null,
'populator' => null,
];
@@ -279,7 +282,7 @@ private function readSql()
private function connect()
{
$options = [];
-
+
/**
* @see http://php.net/manual/en/pdo.construct.php
* @see http://php.net/manual/de/ref.pdo-mysql.php#pdo-mysql.constants
@@ -287,11 +290,11 @@ private function connect()
if (array_key_exists('ssl_key', $this->config) && !empty($this->config['ssl_key'])) {
$options[\PDO::MYSQL_ATTR_SSL_KEY] = $this->config['ssl_key'];
}
-
+
if (array_key_exists('ssl_cert', $this->config) && !empty($this->config['ssl_cert'])) {
$options[\PDO::MYSQL_ATTR_SSL_CERT] = $this->config['ssl_cert'];
}
-
+
if (array_key_exists('ssl_ca', $this->config) && !empty($this->config['ssl_ca'])) {
$options[\PDO::MYSQL_ATTR_SSL_CA] = $this->config['ssl_ca'];
}
@@ -307,6 +310,11 @@ private function connect()
throw new ModuleException(__CLASS__, $message . ' while creating PDO connection');
}
+
+ if ($this->config['waitlock']) {
+ $this->driver->setWaitLock($this->config['waitlock']);
+ }
+
$this->debugSection('Db', 'Connected to ' . $this->driver->getDb());
$this->dbh = $this->driver->getDbh();
}
@@ -425,7 +433,7 @@ public function haveInDatabase($table, array $data)
return $lastInsertId;
}
-
+
public function _insertInDatabase($table, array $data)
{
$query = $this->driver->insert($table, $data);
@@ -579,7 +587,7 @@ public function grabColumnFromDatabase($table, $column, array $criteria = [])
$this->debugSection('Query', $query);
$this->debugSection('Parameters', $parameters);
$sth = $this->driver->executeQuery($query, $parameters);
-
+
return $sth->fetchAll(\PDO::FETCH_COLUMN, 0);
}
From 88d572c2a44c28085df8fe2221cf3d66b0966060 Mon Sep 17 00:00:00 2001
From: Gordon Franke
Date: Thu, 12 Jul 2018 11:17:06 +0200
Subject: [PATCH 077/395] match title in input fields (#5065)
---
src/Codeception/Module/WebDriver.php | 4 ++--
tests/data/app/view/form/anchor.php | 2 +-
tests/web/WebDriverTest.php | 7 +++++++
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index 0bb4274899..16b4663629 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -994,7 +994,7 @@ public function click($link, $context = null)
*
* ```
* @api
- * @param $page WebDriver instance or an element to search within
+ * @param RemoteWebDriver $page WebDriver instance or an element to search within
* @param $link a link text or locator to click
* @return WebDriverElement
*/
@@ -1030,7 +1030,7 @@ public function _findClickable($page, $link)
".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][contains(./@value, $locator)]",
".//input[./@type = 'image'][contains(./@alt, $locator)]",
".//button[contains(normalize-space(string(.)), $locator)]",
- ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][./@name = $locator]",
+ ".//input[./@type = 'submit' or ./@type = 'image' or ./@type = 'button'][./@name = $locator or ./@title = $locator]",
".//button[./@name = $locator or ./@title = $locator]"
);
diff --git a/tests/data/app/view/form/anchor.php b/tests/data/app/view/form/anchor.php
index de1bf9ee99..d213041793 100644
--- a/tests/data/app/view/form/anchor.php
+++ b/tests/data/app/view/form/anchor.php
@@ -6,7 +6,7 @@
diff --git a/tests/web/WebDriverTest.php b/tests/web/WebDriverTest.php
index f220463a2e..6ada29c2b7 100644
--- a/tests/web/WebDriverTest.php
+++ b/tests/web/WebDriverTest.php
@@ -857,6 +857,13 @@ public function testSubmitHashForm()
$this->module->seeCurrentUrlEquals('/form/anchor#a');
}
+ public function testSubmitHashFormTitle()
+ {
+ $this->module->amOnPage('/form/anchor');
+ $this->module->click('Hash Form Title');
+ $this->module->seeCurrentUrlEquals('/form/anchor#a');
+ }
+
public function testSubmitHashButtonForm()
{
$this->module->amOnPage('/form/anchor');
From e03f4049bc878acaad0b6b01793ff711d762bdf4 Mon Sep 17 00:00:00 2001
From: Lee Robert
Date: Sat, 14 Jul 2018 18:28:54 -0400
Subject: [PATCH 078/395] Fixes a missing _ for _getResponseContent() in
seeXmlResponseEquals (#5074)
* Fixes a missing _ for _getResponseContent() in seeXmlResponseEquals
* Added test
---
src/Codeception/Module/REST.php | 2 +-
tests/unit/Codeception/Module/RestTest.php | 7 +++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/Codeception/Module/REST.php b/src/Codeception/Module/REST.php
index dd3b808b2b..759c98a3b5 100644
--- a/src/Codeception/Module/REST.php
+++ b/src/Codeception/Module/REST.php
@@ -1295,7 +1295,7 @@ public function grabAttributeFromXmlElement($cssOrXPath, $attribute)
*/
public function seeXmlResponseEquals($xml)
{
- \PHPUnit\Framework\Assert::assertXmlStringEqualsXmlString($this->connectionModule->getResponseContent(), $xml);
+ \PHPUnit\Framework\Assert::assertXmlStringEqualsXmlString($this->connectionModule->_getResponseContent(), $xml);
}
diff --git a/tests/unit/Codeception/Module/RestTest.php b/tests/unit/Codeception/Module/RestTest.php
index a823e5c13f..3af75d9b77 100644
--- a/tests/unit/Codeception/Module/RestTest.php
+++ b/tests/unit/Codeception/Module/RestTest.php
@@ -122,6 +122,13 @@ public function testValidXml()
$this->module->seeResponseEquals('John');
}
+ public function testXmlResponseEquals()
+ {
+ $this->setStubResponse('');
+ $this->module->seeResponseIsXml();
+ $this->module->seeXmlResponseEquals('');
+ }
+
public function testInvalidXml()
{
$this->setExpectedException('PHPUnit\Framework\ExpectationFailedException');
From 2060fc1fe8ac2823ff3b8ece04616fc12aca968a Mon Sep 17 00:00:00 2001
From: Michael Bodnarchuk
Date: Mon, 16 Jul 2018 11:14:50 +0300
Subject: [PATCH 079/395] Version bump and changelog (#5077)
---
CHANGELOG-2.4.md | 9 +++++++++
src/Codeception/Codecept.php | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG-2.4.md b/CHANGELOG-2.4.md
index 60e71a711f..b85b698018 100644
--- a/CHANGELOG-2.4.md
+++ b/CHANGELOG-2.4.md
@@ -2,6 +2,15 @@
* Recently added `extends` property in the `codeception.yml` and `*.suite.yml` files now support absolute paths; by @silverfire
* Fixed absolute paths handling on Windows in ParamLoader; by @silverfire
+* [Yii2] Refactored database connection handling by @SamMousa. Database connections should now always be closed after tests no matter how you have opened them or who is holding references to them. See #5045
+* [Symfony] Email handling improved by @mbohal. Fixes #5058.
+ * Added optional argument `$expectedCount` to `seeEmailIsSent`
+ * Added `dontSeeEmailIsSent`
+* [Recorder Extension] Added `ignore_steps` option to disable recording of specific steps. By @sspat.
+* [WebDriver] Fixed "No Session Timeout" fatal error by @davertmik.
+* [WebDriver] Added ability to locate clickable element by its title. See #5065 by @gimler
+* [Db] Add `waitlock` config option for the database session to wait for lock in Oracle. By @ashnazg. See #5069
+* [REST] Fixed `seeXmlResponseEquals` by @Voziv
#### 2.4.3
diff --git a/src/Codeception/Codecept.php b/src/Codeception/Codecept.php
index 158096ed0b..831944a7b0 100644
--- a/src/Codeception/Codecept.php
+++ b/src/Codeception/Codecept.php
@@ -7,7 +7,7 @@
class Codecept
{
- const VERSION = "2.4.3";
+ const VERSION = "2.4.4";
/**
* @var \Codeception\PHPUnit\Runner
From 6ca7696e00f0d18bfad549f7c0ba9dee1427ce57 Mon Sep 17 00:00:00 2001
From: jonny7
Date: Tue, 17 Jul 2018 09:43:52 -0300
Subject: [PATCH 080/395] Update autoload.php
Fixes Compilation error:
>Warning: preg_match(): Compilation failed: missing terminating ] for character class at offset 16 in C:\xampp-7\htdocs\www\vendor\codeception\codeception\autoload.php on line 134
---
autoload.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/autoload.php b/autoload.php
index e15b1413c0..132c109e4f 100644
--- a/autoload.php
+++ b/autoload.php
@@ -131,6 +131,6 @@ function codecept_is_path_absolute($path)
return mb_substr($path, 0, 1) === DIRECTORY_SEPARATOR;
}
- return preg_match('#^[A-Z]:(?![^/\\])#i', $path) === 1;
+ return preg_match('#^[A-Z]:(?![^/\\\])#i', $path) === 1;
}
}
From 5960d64ded678561b4bda4af37ed09f4c775ff4d Mon Sep 17 00:00:00 2001
From: Chuck Burgess
Date: Sat, 21 Jul 2018 04:00:17 -0500
Subject: [PATCH 081/395] update stale github/tree URLs in docs; (#5084)
---
docs/08-Customization.md | 2 +-
docs/modules/Db.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/08-Customization.md b/docs/08-Customization.md
index 2abd32b29a..e9bc2e57cd 100644
--- a/docs/08-Customization.md
+++ b/docs/08-Customization.md
@@ -366,7 +366,7 @@ Learn from the examples above to build a custom Installation Template. Here are
* Use methods like `say`, `saySuccess`, `sayWarning`, `sayError`, `ask`, to interact with a user.
* Use `createDirectoryFor`, `createEmptyDirectory` methods to create directories
* Use `createHelper`, `createActor` methods to create helpers and actors.
-* Use [Codeception generators](https://github.com/Codeception/Codeception/tree/2.3/src/Codeception/Lib/Generator) to create other support classes.
+* Use [Codeception generators](https://github.com/Codeception/Codeception/tree/2.4/src/Codeception/Lib/Generator) to create other support classes.
## Conclusion
diff --git a/docs/modules/Db.md b/docs/modules/Db.md
index 611f920a77..0b843c2486 100644
--- a/docs/modules/Db.md
+++ b/docs/modules/Db.md
@@ -23,7 +23,7 @@ Also available:
* Oracle
Connection is done by database Drivers, which are stored in the `Codeception\Lib\Driver` namespace.
-[Check out the drivers](https://github.com/Codeception/Codeception/tree/2.3/src/Codeception/Lib/Driver)
+[Check out the drivers](https://github.com/Codeception/Codeception/tree/2.4/src/Codeception/Lib/Driver)
if you run into problems loading dumps and cleaning databases.
## Config
From 26cdd4913ca54c67ddb6e8469599f5438a8dfae4 Mon Sep 17 00:00:00 2001
From: Gintautas Miselis
Date: Sun, 29 Jul 2018 13:49:00 +0300
Subject: [PATCH 082/395] [Docs] updated PHP requirements for 2..4 version
(#5098)
---
RoboFile.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/RoboFile.php b/RoboFile.php
index 8e8e913a62..71c4e48543 100644
--- a/RoboFile.php
+++ b/RoboFile.php
@@ -519,8 +519,10 @@ public function publishPhar()
$releaseFile->line("\n## $branch");
if ($major < 2) {
$releaseFile->line("*Requires: PHP 5.3 and higher + CURL*\n");
- } else {
+ } elseif ($major == 2 && $minor < 4) {
$releaseFile->line("*Requires: PHP 5.4 and higher + CURL*\n");
+ } else {
+ $releaseFile->line("*Requires: PHP 5.6 and higher + CURL*\n");
}
$releaseFile->line("* **[Download Latest $branch Release]($downloadUrl)**");
}
From 8a4bb3d12e4aed2755f0d063fea9fd94bc603eb8 Mon Sep 17 00:00:00 2001
From: bangertz
Date: Sun, 29 Jul 2018 22:46:20 +0200
Subject: [PATCH 083/395] [DB][Mysql] Two new options: "ssl_cipher" and
"ssl_verify_server_cert" (#5095)
* Two new options: "ssl_cipher" and "ssl_verify_server_cert"
Added two options: "ssl_cipher" (list of one or more permissible ciphers to use for SSL encryption) and "ssl_verify_server_cert" (disables certificate CN verification)
* Spaces removed
---
src/Codeception/Module/Db.php | 38 +++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/src/Codeception/Module/Db.php b/src/Codeception/Module/Db.php
index 3f7150e61a..ac674a8576 100644
--- a/src/Codeception/Module/Db.php
+++ b/src/Codeception/Module/Db.php
@@ -49,6 +49,8 @@
* * ssl_key - path to the SSL key (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-key)
* * ssl_cert - path to the SSL certificate (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-ssl-cert)
* * ssl_ca - path to the SSL certificate authority (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-ssl-ca)
+ * * ssl_verify_server_cert - disables certificate CN verification (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php)
+ * * ssl_cipher - list of one or more permissible ciphers to use for SSL encryption (MySQL specific, @see http://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-cipher)
*
* ## Example
*
@@ -66,6 +68,8 @@
* ssl_key: '/path/to/client-key.pem'
* ssl_cert: '/path/to/client-cert.pem'
* ssl_ca: '/path/to/ca-cert.pem'
+ * ssl_verify_server_cert: false
+ * ssl_cipher: 'AES256-SHA'
*
* ## SQL data dump
*
@@ -287,16 +291,38 @@ private function connect()
* @see http://php.net/manual/en/pdo.construct.php
* @see http://php.net/manual/de/ref.pdo-mysql.php#pdo-mysql.constants
*/
- if (array_key_exists('ssl_key', $this->config) && !empty($this->config['ssl_key'])) {
- $options[\PDO::MYSQL_ATTR_SSL_KEY] = $this->config['ssl_key'];
+ if (array_key_exists('ssl_key', $this->config)
+ && !empty($this->config['ssl_key'])
+ && defined('\PDO::MYSQL_ATTR_SSL_KEY')
+ ) {
+ $options[\PDO::MYSQL_ATTR_SSL_KEY] = (string) $this->config['ssl_key'];
}
- if (array_key_exists('ssl_cert', $this->config) && !empty($this->config['ssl_cert'])) {
- $options[\PDO::MYSQL_ATTR_SSL_CERT] = $this->config['ssl_cert'];
+ if (array_key_exists('ssl_cert', $this->config)
+ && !empty($this->config['ssl_cert'])
+ && defined('\PDO::MYSQL_ATTR_SSL_CERT')
+ ) {
+ $options[\PDO::MYSQL_ATTR_SSL_CERT] = (string) $this->config['ssl_cert'];
+ }
+
+ if (array_key_exists('ssl_ca', $this->config)
+ && !empty($this->config['ssl_ca'])
+ && defined('\PDO::MYSQL_ATTR_SSL_CA')
+ ) {
+ $options[\PDO::MYSQL_ATTR_SSL_CA] = (string) $this->config['ssl_ca'];
}
- if (array_key_exists('ssl_ca', $this->config) && !empty($this->config['ssl_ca'])) {
- $options[\PDO::MYSQL_ATTR_SSL_CA] = $this->config['ssl_ca'];
+ if (array_key_exists('ssl_cipher', $this->config)
+ && !empty($this->config['ssl_cipher'])
+ && defined('\PDO::MYSQL_ATTR_SSL_CIPHER')
+ ) {
+ $options[\PDO::MYSQL_ATTR_SSL_CIPHER] = (string) $this->config['ssl_cipher'];
+ }
+
+ if (array_key_exists('ssl_verify_server_cert', $this->config)
+ && defined('\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT')
+ ) {
+ $options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (boolean) $this->config[ 'ssl_verify_server_cert' ];
}
try {
From e864e787b7374376057a01cefd1788b709841830 Mon Sep 17 00:00:00 2001
From: Michael Bodnarchuk
Date: Wed, 1 Aug 2018 00:29:14 +0300
Subject: [PATCH 084/395] fixed compat with phpunit 7.2 (#5104)
---
src/Codeception/Codecept.php | 2 +-
src/Codeception/Subscriber/Dependencies.php | 2 +-
src/Codeception/Suite.php | 2 +-
src/Codeception/Test/Cept.php | 2 +-
src/Codeception/Test/Cest.php | 2 +-
src/Codeception/Test/Interfaces/Dependent.php | 2 +-
src/Codeception/Test/Unit.php | 4 ++--
tests/data/claypit/composer.lock | 8 ++++----
8 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/Codeception/Codecept.php b/src/Codeception/Codecept.php
index 831944a7b0..7ab393de3e 100644
--- a/src/Codeception/Codecept.php
+++ b/src/Codeception/Codecept.php
@@ -7,7 +7,7 @@
class Codecept
{
- const VERSION = "2.4.4";
+ const VERSION = "2.4.5";
/**
* @var \Codeception\PHPUnit\Runner
diff --git a/src/Codeception/Subscriber/Dependencies.php b/src/Codeception/Subscriber/Dependencies.php
index ca97490b1d..1e52feb532 100644
--- a/src/Codeception/Subscriber/Dependencies.php
+++ b/src/Codeception/Subscriber/Dependencies.php
@@ -26,7 +26,7 @@ public function testStart(TestEvent $event)
return;
}
- $testSignatures = $test->getDependencies();
+ $testSignatures = $test->fetchDependencies();
foreach ($testSignatures as $signature) {
if (!in_array($signature, $this->successfulTests)) {
$test->getMetadata()->setSkip("This test depends on $signature to pass");
diff --git a/src/Codeception/Suite.php b/src/Codeception/Suite.php
index 509e66627c..53c19415d5 100644
--- a/src/Codeception/Suite.php
+++ b/src/Codeception/Suite.php
@@ -34,7 +34,7 @@ protected function getDependencies($test)
return [$test];
}
$tests = [];
- foreach ($test->getDependencies() as $requiredTestName) {
+ foreach ($test->fetchDependencies() as $requiredTestName) {
$required = $this->findMatchedTest($requiredTestName);
if (!$required) {
continue;
diff --git a/src/Codeception/Test/Cept.php b/src/Codeception/Test/Cept.php
index bdbcefea49..c82a936926 100644
--- a/src/Codeception/Test/Cept.php
+++ b/src/Codeception/Test/Cept.php
@@ -77,7 +77,7 @@ protected function getParser()
return $this->parser;
}
- public function getDependencies()
+ public function fetchDependencies()
{
return $this->getMetadata()->getDependencies();
}
diff --git a/src/Codeception/Test/Cest.php b/src/Codeception/Test/Cest.php
index 20f51f5ffd..c644ed2ea5 100644
--- a/src/Codeception/Test/Cest.php
+++ b/src/Codeception/Test/Cest.php
@@ -188,7 +188,7 @@ protected function getParser()
return $this->parser;
}
- public function getDependencies()
+ public function fetchDependencies()
{
$names = [];
foreach ($this->getMetadata()->getDependencies() as $required) {
diff --git a/src/Codeception/Test/Interfaces/Dependent.php b/src/Codeception/Test/Interfaces/Dependent.php
index 245d3bb153..c32e00d9b0 100644
--- a/src/Codeception/Test/Interfaces/Dependent.php
+++ b/src/Codeception/Test/Interfaces/Dependent.php
@@ -3,5 +3,5 @@
interface Dependent
{
- public function getDependencies();
+ public function fetchDependencies();
}
diff --git a/src/Codeception/Test/Unit.php b/src/Codeception/Test/Unit.php
index c85acbfa8c..061072f526 100644
--- a/src/Codeception/Test/Unit.php
+++ b/src/Codeception/Test/Unit.php
@@ -130,7 +130,7 @@ public function getReportFields()
];
}
- public function getDependencies()
+ public function fetchDependencies()
{
$names = [];
foreach ($this->getMetadata()->getDependencies() as $required) {
@@ -148,7 +148,7 @@ public function getDependencies()
*/
public function handleDependencies()
{
- $dependencies = $this->getDependencies();
+ $dependencies = $this->fetchDependencies();
if (empty($dependencies)) {
return true;
}
diff --git a/tests/data/claypit/composer.lock b/tests/data/claypit/composer.lock
index c1bef1de0a..128b162bff 100644
--- a/tests/data/claypit/composer.lock
+++ b/tests/data/claypit/composer.lock
@@ -14,12 +14,12 @@
"source": {
"type": "git",
"url": "https://github.com/Codeception/c3.git",
- "reference": "f7e31fce8a9abf1021990b4e31a7ed01689f4295"
+ "reference": "d841be32a6785e2f565b9f88f5ff36c905931a9a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Codeception/c3/zipball/f7e31fce8a9abf1021990b4e31a7ed01689f4295",
- "reference": "f7e31fce8a9abf1021990b4e31a7ed01689f4295",
+ "url": "https://api.github.com/repos/Codeception/c3/zipball/d841be32a6785e2f565b9f88f5ff36c905931a9a",
+ "reference": "d841be32a6785e2f565b9f88f5ff36c905931a9a",
"shasum": ""
},
"require": {
@@ -56,7 +56,7 @@
"code coverage",
"codecoverage"
],
- "time": "2018-05-26 21:53:33"
+ "time": "2018-05-26 22:34:28"
}
],
"aliases": [],
From 11d32cf5387ca355464d45c1bb4515739f5dbb58 Mon Sep 17 00:00:00 2001
From: OneEyedSpaceFish
Date: Tue, 31 Jul 2018 22:59:19 +0100
Subject: [PATCH 085/395] Fixing edge-case issues with the recording extension
(#5101)
Fixes #5093
---
ext/Recorder.php | 135 +++++++++++++++++++++++++++++++++++------------
1 file changed, 101 insertions(+), 34 deletions(-)
diff --git a/ext/Recorder.php b/ext/Recorder.php
index e87f81a942..67a63d23ad 100644
--- a/ext/Recorder.php
+++ b/ext/Recorder.php
@@ -1,4 +1,5 @@
'WebDriver',
'template' => null,
'animate_slides' => true,
- 'ignore_steps' => []
+ 'ignore_steps' => [],
];
protected $template = <<recordedTests as $link => $url) {
- $links .= "