MOBILE-3926 behat: Implement load items step

main
Noel De Martin 2021-12-01 14:12:15 +01:00
parent 89488bd71a
commit 771b4039e6
2 changed files with 103 additions and 0 deletions

View File

@ -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,

View File

@ -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;
}
}