MDL-41030 Behat: Add support for waiting for javascript
This is so that phantomjs (which runs faster than selenium) can pass the tests.
This commit is contained in:
committed by
David Monllao
parent
5d2b67228c
commit
6e2c417c1f
@@ -60,6 +60,30 @@ class behat_forms extends behat_base {
|
||||
$buttonnode->press();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try a few times to set a field value as it may not be visible yet (TinyMCE).
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
*/
|
||||
public function set_field_value($field, $value) {
|
||||
$lastexception = null;
|
||||
// Spin on this - certain fields, e.g. text editors (I'm looking at you TinyMCE) load slowly and randomly.
|
||||
$retries = 5;
|
||||
while ($retries > 0) {
|
||||
try {
|
||||
$field->set_value($value);
|
||||
return;
|
||||
} catch (Exception $e) {
|
||||
usleep(100000);
|
||||
$retries--;
|
||||
$lastexception = $e;
|
||||
}
|
||||
}
|
||||
// If we timeout - throw the last exception.
|
||||
throw $lastexception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a moodle form with field/value data.
|
||||
*
|
||||
@@ -84,7 +108,7 @@ class behat_forms extends behat_base {
|
||||
$field = behat_field_manager::get_form_field($fieldnode, $this->getSession());
|
||||
|
||||
// Delegates to the field class.
|
||||
$field->set_value($value);
|
||||
$this->set_field_value($field, $value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,42 +222,32 @@ class behat_hooks extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that all DOM is ready.
|
||||
* Wait for JS to comlete.
|
||||
*
|
||||
* Executed only when running against a real browser.
|
||||
*
|
||||
* @AfterStep @javascript
|
||||
* @BeforeStep @javascript
|
||||
*/
|
||||
public function after_step_javascript($event) {
|
||||
|
||||
// If it doesn't have definition or it fails there is no need to check it.
|
||||
if ($event->getResult() != StepEvent::PASSED ||
|
||||
!$event->hasDefinition()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait until the page is ready.
|
||||
// We are already checking that we use a JS browser, this could
|
||||
// change in case we use another JS driver.
|
||||
try {
|
||||
|
||||
// Safari and Internet Explorer requires time between steps,
|
||||
// otherwise Selenium tries to click in the previous page's DOM.
|
||||
if ($this->getSession()->getDriver()->getBrowserName() == 'safari' ||
|
||||
$this->getSession()->getDriver()->getBrowserName() == 'internet explorer') {
|
||||
$this->getSession()->wait(self::TIMEOUT * 1000, false);
|
||||
|
||||
} else {
|
||||
// With other browsers we just wait for the DOM ready.
|
||||
$this->getSession()->wait(self::TIMEOUT * 1000, '(document.readyState === "complete")');
|
||||
public function before_step_javascript($event) {
|
||||
$lastpending = '';
|
||||
// Wait for all pending JS to complete (max 10 seconds).
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$pending = '';
|
||||
try {
|
||||
$pending = ($this->getSession()->evaluateScript('return (M && M.util && M.util.pending_js) ? M.util.pending_js.join(":") : "not loaded";'));
|
||||
} catch (NoSuchWindow $nsw) {
|
||||
// No javascript is running if there is no window right?
|
||||
$pending = '';
|
||||
}
|
||||
|
||||
} catch (NoSuchWindow $e) {
|
||||
// If we were interacting with a popup window it will not exists after closing it.
|
||||
} catch (UnknownError $e) {
|
||||
// Custom exception to provide more feedback about possible solutions.
|
||||
$this->throw_unknown_exception($e);
|
||||
if ($pending === '') {
|
||||
return;
|
||||
}
|
||||
$lastpending = $pending;
|
||||
// 0.1 seconds.
|
||||
usleep(100000);
|
||||
}
|
||||
// Timeout waiting for JS to complete.
|
||||
// We could throw an exception here - as this is a likely indicator of slow JS or JS errors.
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user