| Current Path : /var/www/html/dyna-project/vendor/codeception/base/src/Codeception/Module/ |
| Current File : /var/www/html/dyna-project/vendor/codeception/base/src/Codeception/Module/AngularJS.php |
<?php
namespace Codeception\Module;
use Codeception\Step;
use Codeception\TestInterface;
use Facebook\WebDriver\WebDriverBy;
/**
* 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**.
* Uses Angular's and Protractor internals methods to synchronize with the page.
*
* ## Configuration
*
* The same as for [WebDriver](http://codeception.com/docs/modules/WebDriver#Configuration), but few new options added:
*
* * `el` - element where Angular application is defined (default: `body`)
* * `script_timeout` - for how long in seconds to wait for angular operations to finish (default: 5)
*
* ### Example (`acceptance.suite.yml`)
*
* modules:
* enabled:
* - AngularJS:
* url: 'http://localhost/'
* 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.
*
* Example:
*
* ```php
* $I->selectOption(['model' => 'customerId'], '3');
* ```
*/
class AngularJS extends WebDriver
{
protected $insideApplication = true;
protected $defaultAngularConfig = [
'script_timeout' => 5,
'el' => 'body',
];
protected $waitForAngular = <<<EOF
var rootSelector = arguments[0];
var callback = arguments[1];
var el = document.querySelector(rootSelector);
try {
if (window.getAngularTestability) {
window.getAngularTestability(el).whenStable(callback);
return;
}
if (!window.angular) {
throw new Error('window.angular is undefined. This could be either ' +
'because this is a non-angular page or because your test involves ' +
'client-side navigation, which can interfere with Protractor\'s ' +
'bootstrapping. See http://git.io/v4gXM for details');
}
if (angular.getTestability) {
angular.getTestability(el).whenStable(callback);
} else {
if (!angular.element(el).injector()) {
throw new Error('root element (' + rootSelector + ') has no injector.' +
' this may mean it is not inside ng-app.');
}
angular.element(el).injector().get('\$browser').
notifyWhenNoOutstandingRequests(callback);
}
} catch (err) {
callback(err.message);
}
EOF;
public function _setConfig($config)
{
parent::_setConfig(array_merge($this->defaultAngularConfig, $config));
}
public function _before(TestInterface $test)
{
parent::_before($test);
$this->webDriver->manage()->timeouts()->setScriptTimeout($this->config['script_timeout']);
}
/**
* Enables Angular mode (enabled by default).
* Waits for Angular to finish rendering after each action.
*/
public function amInsideAngularApp()
{
$this->insideApplication = true;
}
/**
* Disabled Angular mode.
*
* Falls back to original WebDriver, in case web page does not contain Angular app.
*/
public function amOutsideAngularApp()
{
$this->insideApplication = false;
}
public function _afterStep(Step $step)
{
if (!$this->insideApplication) {
return;
}
$actions = [
'amOnPage',
'click',
'fillField',
'selectOption',
'checkOption',
'uncheckOption',
'unselectOption',
'doubleClick',
'appendField',
'clickWithRightButton',
'dragAndDrop'
];
if (in_array($step->getAction(), $actions)) {
$this->webDriver->executeAsyncScript($this->waitForAngular, [$this->config['el']]);
}
}
protected function getStrictLocator(array $by)
{
$type = key($by);
$value = $by[$type];
if ($type === 'model') {
return WebDriverBy::cssSelector(sprintf('[ng-model="%s"]', $value));
}
return parent::getStrictLocator($by);
}
}