From 771b4039e691451e491f9030c603abf3a1af8149 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 1 Dec 2021 14:12:15 +0100 Subject: [PATCH] MOBILE-3926 behat: Implement load items step --- tests/behat/app_behat_runtime.js | 47 +++++++++++++++++++++++++++ tests/behat/behat_app.php | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 937142cec..a9c3df3cf 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -553,6 +553,52 @@ } } + /** + * Load more items form an active list with infinite loader. + * + * @return {string} OK if successful, or ERROR: followed by message + */ + const behatLoadMoreItems = async function() { + log('Action - loadMoreItems'); + + try { + const infiniteLoading = Array + .from(document.querySelectorAll('core-infinite-loading')) + .find(element => !element.closest('.ion-page-hidden')); + + if (!infiniteLoading) { + return 'ERROR: There isn\'t an infinite loader in the current page'; + } + + const initialOffset = infiniteLoading.offsetTop; + const isLoading = () => !!infiniteLoading.querySelector('ion-spinner[aria-label]'); + const isCompleted = () => !isLoading() && !infiniteLoading.querySelector('ion-button'); + const hasMoved = () => infiniteLoading.offsetTop !== initialOffset; + + if (isCompleted()) { + return 'ERROR: All items are already loaded'; + } + + infiniteLoading.scrollIntoView(); + + // Wait 100ms + await new Promise(resolve => setTimeout(resolve, 100)); + + if (isLoading() || isCompleted() || hasMoved()) { + return 'OK'; + } + + infiniteLoading.querySelector('ion-button').click(); + + // Wait 100ms + await new Promise(resolve => setTimeout(resolve, 100)); + + return (isLoading() || isCompleted() || hasMoved()) ? 'OK' : 'ERROR: Couldn\'t load more items'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + /** * Check whether an item is selected or not. * @@ -706,6 +752,7 @@ closePopup : behatClosePopup, find : behatFind, scrollTo : behatScrollTo, + loadMoreItems: behatLoadMoreItems, isSelected : behatIsSelected, press : behatPress, setField : behatSetField, diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 67d5ab2ef..c7f8b193d 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -204,6 +204,30 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Load more items in a list with an infinite loader. + * + * @When /^I (should not be able to )?load more items in the app$/ + * @param bool $not + */ + public function i_load_more_items_in_the_app(bool $not = false) { + $this->spin(function() use ($not) { + $result = $this->evaluate_async_script('return window.behat.loadMoreItems();'); + + if ($not && $result !== 'ERROR: All items are already loaded') { + throw new DriverException('It should not have been possible to load more items'); + } + + if (!$not && $result !== 'OK') { + throw new DriverException('Error loading more items - ' . $result); + } + + return true; + }); + + $this->wait_for_pending_js(); + } + /** * Trigger swipe gesture. * @@ -1067,4 +1091,36 @@ class behat_app extends behat_base { } } + /** + * Evaludate a script that returns a Promise. + * + * @param string $script + * @return mixed Resolved promise result. + */ + private function evaluate_async_script(string $script) { + $script = preg_replace('/^return\s+/', '', $script); + $script = preg_replace('/;$/', '', $script); + $start = microtime(true); + $promisevariable = 'PROMISE_RESULT_' . time(); + $timeout = self::get_timeout(); + + $this->evaluate_script("Promise.resolve($script) + .then(result => window.$promisevariable = result) + .catch(error => window.$promisevariable = 'Async code rejected: ' + error?.message);"); + + do { + if (microtime(true) - $start > $timeout) { + throw new DriverException("Async script not resolved after $timeout seconds"); + } + + usleep(100000); + } while (!$this->evaluate_script("return '$promisevariable' in window;")); + + $result = $this->evaluate_script("return window.$promisevariable;"); + + $this->evaluate_script("delete window.$promisevariable;"); + + return $result; + } + }