MOBILE-3926 behat: Implement load items step
This commit is contained in:
		
							parent
							
								
									89488bd71a
								
							
						
					
					
						commit
						771b4039e6
					
				| @ -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, | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user