selectOption(['model' => 'customerId'], '3'); * ``` */ class AngularJS extends WebDriver { protected $insideApplication = true; protected $defaultAngularConfig = [ 'script_timeout' => 5, 'el' => 'body', ]; protected $waitForAngular = <<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); } }