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 @@ ...@@ -28,10 +28,11 @@
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
use Behat\Mink\Exception\DriverException, use Behat\Mink\Exception\DriverException;
Behat\Mink\Exception\ExpectationException as ExpectationException, use Behat\Mink\Exception\ExpectationException;
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException, use Behat\Mink\Exception\ElementNotFoundException;
Behat\Mink\Element\NodeElement as NodeElement; use Behat\Mink\Element\NodeElement;
use Behat\Mink\Session;
/** /**
* Steps definitions base class. * Steps definitions base class.
...@@ -709,23 +710,30 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext { ...@@ -709,23 +710,30 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
/** /**
* Waits for all the JS to be loaded. * Waits for all the JS to be loaded.
* *
* @throws \Exception * @return bool Whether any JS is still pending completion.
* @throws NoSuchWindow
* @throws UnknownError
* @return bool True or false depending whether all the JS is loaded or not.
*/ */
public function wait_for_pending_js() { public function wait_for_pending_js() {
// Waiting for JS is only valid for JS scenarios.
if (!$this->running_javascript()) { 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 // 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. // if the page & JSs don't finish loading properly.
for ($i = 0; $i < self::EXTENDED_TIMEOUT * 10; $i++) { for ($i = 0; $i < self::EXTENDED_TIMEOUT * 10; $i++) {
$pending = ''; $pending = '';
try { try {
$jscode = ' $jscode = trim(preg_replace('/\s+/', ' ', '
return (function() { return (function() {
if (typeof M === "undefined") { if (typeof M === "undefined") {
if (document.readyState === "complete") { if (document.readyState === "complete") {
...@@ -740,8 +748,8 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext { ...@@ -740,8 +748,8 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
} else { } else {
return "incomplete" return "incomplete"
} }
}());'; }());'));
$pending = $this->getSession()->evaluateScript($jscode); $pending = $session->evaluateScript($jscode);
} catch (NoSuchWindow $nsw) { } catch (NoSuchWindow $nsw) {
// We catch an exception here, in case we just closed the window we were interacting with. // 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? // No javascript is running if there is no window right?
...@@ -762,7 +770,7 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext { ...@@ -762,7 +770,7 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
usleep(100000); 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 // 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 // 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. // 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 { ...@@ -172,6 +172,20 @@ class behat_form_field {
return get_class($this->session->getDriver()) !== 'Behat\Mink\Driver\GoutteDriver'; 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. * 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