Commit 7bfb575f authored by Andrew Nicols's avatar Andrew Nicols
Browse files

MDL-62514 behat: Add a wait_for_pending_js to form field

parent 0e1e1e55
......@@ -28,10 +28,11 @@
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
use Behat\Mink\Exception\DriverException,
Behat\Mink\Exception\ExpectationException as ExpectationException,
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException,
Behat\Mink\Element\NodeElement as NodeElement;
use Behat\Mink\Exception\DriverException;
use Behat\Mink\Exception\ExpectationException;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Element\NodeElement;
use Behat\Mink\Session;
/**
* Steps definitions base class.
......@@ -709,23 +710,30 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
/**
* Waits for all the JS to be loaded.
*
* @throws \Exception
* @throws NoSuchWindow
* @throws UnknownError
* @return bool True or false depending whether all the JS is loaded or not.
* @return bool Whether any JS is still pending completion.
*/
public function wait_for_pending_js() {
// Waiting for JS is only valid for JS scenarios.
if (!$this->running_javascript()) {
return;
// JS is not available therefore there is nothing to wait for.
return false;
}
return static::wait_for_pending_js_in_session($this->getSession());
}
/**
* Waits for all the JS to be loaded.
*
* @param Session $session The Mink Session where JS can be run
* @return bool Whether any JS is still pending completion.
*/
public static function wait_for_pending_js_in_session(Session $session) {
// We don't use behat_base::spin() here as we don't want to end up with an exception
// if the page & JSs don't finish loading properly.
for ($i = 0; $i < self::EXTENDED_TIMEOUT * 10; $i++) {
$pending = '';
try {
$jscode = '
$jscode = trim(preg_replace('/\s+/', ' ', '
return (function() {
if (typeof M === "undefined") {
if (document.readyState === "complete") {
......@@ -740,8 +748,8 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
} else {
return "incomplete"
}
}());';
$pending = $this->getSession()->evaluateScript($jscode);
}());'));
$pending = $session->evaluateScript($jscode);
} catch (NoSuchWindow $nsw) {
// We catch an exception here, in case we just closed the window we were interacting with.
// No javascript is running if there is no window right?
......@@ -762,7 +770,7 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
usleep(100000);
}
// Timeout waiting for JS to complete. It will be catched and forwarded to behat_hooks::i_look_for_exceptions().
// Timeout waiting for JS to complete. It will be caught and forwarded to behat_hooks::i_look_for_exceptions().
// It is unlikely that Javascript code of a page or an AJAX request needs more than self::EXTENDED_TIMEOUT seconds
// to be loaded, although when pages contains Javascript errors M.util.js_complete() can not be executed, so the
// number of JS pending code and JS completed code will not match and we will reach this point.
......
......@@ -172,6 +172,20 @@ class behat_form_field {
return get_class($this->session->getDriver()) !== 'Behat\Mink\Driver\GoutteDriver';
}
/**
* Waits for all the JS activity to be completed.
*
* @return bool Whether any JS is still pending completion.
*/
protected function wait_for_pending_js() {
if (!$this->running_javascript()) {
// JS is not available therefore there is nothing to wait for.
return false;
}
return behat_base::wait_for_pending_js_in_session($this->session);
}
/**
* Gets the field internal id used by selenium wire protocol.
*
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment