forked from EVOgeek/Vmeda.Online
		
	MOBILE-4069 behat: Make it easier to find text in modals, popover, ...
This commit is contained in:
		
							parent
							
								
									2c80555c1b
								
							
						
					
					
						commit
						11ca2bd7fc
					
				| @ -247,7 +247,7 @@ Feature: Test basic usage of forum activity in app | |||||||
|     And I switch offline mode to "true" |     And I switch offline mode to "true" | ||||||
|     And I press "None" near "test2" in the app |     And I press "None" near "test2" in the app | ||||||
|     And I press "0" near "Cancel" in the app |     And I press "0" near "Cancel" in the app | ||||||
|     Then I should find "Data stored in the device because it couldn't be sent. It will be sent automatically later." inside the toast in the app |     Then I should find "Data stored in the device because it couldn't be sent. It will be sent automatically later." in the app | ||||||
|     And I should find "Average of ratings: -" in the app |     And I should find "Average of ratings: -" in the app | ||||||
|     And I should find "Average of ratings: 1" in the app |     And I should find "Average of ratings: 1" in the app | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,6 +17,9 @@ import { NgZone } from '@singletons'; | |||||||
| import { TestsBehatBlocking } from './behat-blocking'; | import { TestsBehatBlocking } from './behat-blocking'; | ||||||
| import { TestBehatElementLocator } from './behat-runtime'; | import { TestBehatElementLocator } from './behat-runtime'; | ||||||
| 
 | 
 | ||||||
|  | // Containers that block containers behind them.
 | ||||||
|  | const blockingContainers = ['ION-ALERT', 'ION-POPOVER', 'ION-ACTION-SHEET', 'CORE-USER-TOURS-USER-TOUR', 'ION-PAGE']; | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Behat Dom Utils helper functions. |  * Behat Dom Utils helper functions. | ||||||
|  */ |  */ | ||||||
| @ -251,71 +254,68 @@ export class TestsBehatDomUtils { | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Function to find top container element. |      * Function to find top container elements. | ||||||
|      * |      * | ||||||
|      * @param containerName Whether to search inside the a container name. |      * @param containerName Whether to search inside the a container name. | ||||||
|      * @return Found top container element. |      * @return Found top container elements. | ||||||
|      */ |      */ | ||||||
|     protected static getCurrentTopContainerElement(containerName: string): HTMLElement | null { |     protected static getCurrentTopContainerElements(containerName: string): HTMLElement[] { | ||||||
|         let topContainer: HTMLElement | null = null; |         const topContainers: HTMLElement[] = []; | ||||||
|         let containers: HTMLElement[] = []; |         let containers = Array.from(document.querySelectorAll<HTMLElement>([ | ||||||
|         const nonImplementedSelectors = |             'ion-alert.hydrated', | ||||||
|             'ion-alert, ion-popover, ion-action-sheet, ion-modal, core-user-tours-user-tour.is-active, page-core-mainmenu, ion-app'; |             'ion-popover.hydrated', | ||||||
|  |             'ion-action-sheet.hydrated', | ||||||
|  |             'ion-modal.hydrated', | ||||||
|  |             'core-user-tours-user-tour.is-active', | ||||||
|  |             'ion-toast.hydrated', | ||||||
|  |             'page-core-mainmenu', | ||||||
|  |             'ion-app', | ||||||
|  |         ].join(', '))); | ||||||
| 
 | 
 | ||||||
|         switch (containerName) { |         containers = containers | ||||||
|             case 'html': |             .filter(container => { | ||||||
|                 containers = Array.from(document.querySelectorAll<HTMLElement>('html')); |                 if (container.tagName === 'ION-ALERT') { | ||||||
|                 break; |                     // For some reason, in Behat sometimes alerts aren't removed from DOM, the close animation doesn't finish.
 | ||||||
|             case 'toast': |                     // Filter alerts with pointer-events none since that style is set before the close animation starts.
 | ||||||
|                 containers = Array.from(document.querySelectorAll('ion-app ion-toast.hydrated')); |                     return container.style.pointerEvents !== 'none'; | ||||||
|                 containers = containers.map(container => container?.shadowRoot?.querySelector('.toast-container') || container); |                 } | ||||||
|                 break; | 
 | ||||||
|             case 'alert': |                 // Ignore pages that are inside other visible pages.
 | ||||||
|                 containers = Array.from(document.querySelectorAll('ion-app ion-alert.hydrated')); |                 return container.tagName !== 'ION-PAGE' || !container.closest('.ion-page.ion-page-hidden'); | ||||||
|                 break; |             }) | ||||||
|             case 'action-sheet': |             // Sort them by z-index.
 | ||||||
|                 containers = Array.from(document.querySelectorAll('ion-app ion-action-sheet.hydrated')); |             .sort((a, b) =>  Number(getComputedStyle(b).zIndex) - Number(getComputedStyle(a).zIndex)); | ||||||
|                 break; | 
 | ||||||
|             case 'modal': |         if (containerName === 'split-view content') { | ||||||
|                 containers = Array.from(document.querySelectorAll('ion-app ion-modal.hydrated')); |             // Find non hidden pages inside the containers.
 | ||||||
|                 break; |             containers.some(container => { | ||||||
|             case 'popover': |                 if (!container.classList.contains('ion-page')) { | ||||||
|                 containers = Array.from(document.querySelectorAll('ion-app ion-popover.hydrated')); |                     return false; | ||||||
|                 break; |                 } | ||||||
|             case 'user-tour': | 
 | ||||||
|                 containers = Array.from(document.querySelectorAll('core-user-tours-user-tour.is-active')); |                 const pageContainers = Array.from(container.querySelectorAll<HTMLElement>('.ion-page:not(.ion-page-hidden)')); | ||||||
|                 break; |                 let topContainer = pageContainers.find((page) => !page.closest('.ion-page.ion-page-hidden')) ?? null; | ||||||
|             default: | 
 | ||||||
|                 // Other containerName or not implemented.
 |                 topContainer = (topContainer || container).querySelector<HTMLElement>('core-split-view ion-router-outlet'); | ||||||
|                 containers = Array.from(document.querySelectorAll<HTMLElement>(nonImplementedSelectors)); |                 topContainer && topContainers.push(topContainer); | ||||||
|  | 
 | ||||||
|  |                 return !!topContainer; | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             return topContainers; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (containers.length > 0) { |         // Get containers until one blocks other views.
 | ||||||
|             // Get the one with more zIndex.
 |         containers.find(container => { | ||||||
|             topContainer = |             if (container.tagName === 'ION-TOAST') { | ||||||
|                 containers.reduce((a, b) => getComputedStyle(a).zIndex > getComputedStyle(b).zIndex ? a : b, containers[0]); |                 container = container.shadowRoot?.querySelector('.toast-container') || container; | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!topContainer) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (containerName == 'page' || containerName == 'split-view content') { |  | ||||||
|             // Find non hidden pages inside the container.
 |  | ||||||
|             let pageContainers = Array.from(topContainer.querySelectorAll<HTMLElement>('.ion-page:not(.ion-page-hidden)')); |  | ||||||
|             pageContainers = pageContainers.filter((page) => !page.closest('.ion-page.ion-page-hidden')); |  | ||||||
| 
 |  | ||||||
|             if (pageContainers.length > 0) { |  | ||||||
|                 // Get the more general one to avoid failing.
 |  | ||||||
|                 topContainer = pageContainers[0]; |  | ||||||
|             } |             } | ||||||
|  |             topContainers.push(container); | ||||||
| 
 | 
 | ||||||
|             if (containerName == 'split-view content') { |             return blockingContainers.includes(container.tagName); | ||||||
|                 topContainer = topContainer.querySelector<HTMLElement>('core-split-view ion-router-outlet'); |         }); | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         return topContainer; |         return topContainers; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -337,9 +337,24 @@ export class TestsBehatDomUtils { | |||||||
|      * @return Found elements |      * @return Found elements | ||||||
|      */ |      */ | ||||||
|     protected static findElementsBasedOnText(locator: TestBehatElementLocator, containerName = ''): HTMLElement[] { |     protected static findElementsBasedOnText(locator: TestBehatElementLocator, containerName = ''): HTMLElement[] { | ||||||
|         let topContainer = this.getCurrentTopContainerElement(containerName); |         const topContainers = this.getCurrentTopContainerElements(containerName); | ||||||
| 
 | 
 | ||||||
|         let container = topContainer; |         return topContainers.reduce((elements, container) => | ||||||
|  |             elements.concat(this.findElementsBasedOnTextInContainer(locator, container)), <HTMLElement[]> []); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Function to find elements based on their text or Aria label. | ||||||
|  |      * | ||||||
|  |      * @param locator Element locator. | ||||||
|  |      * @param container Container to search in. | ||||||
|  |      * @return Found elements | ||||||
|  |      */ | ||||||
|  |     protected static findElementsBasedOnTextInContainer( | ||||||
|  |         locator: TestBehatElementLocator, | ||||||
|  |         topContainer: HTMLElement, | ||||||
|  |     ): HTMLElement[] { | ||||||
|  |         let container: HTMLElement | null = topContainer; | ||||||
| 
 | 
 | ||||||
|         if (locator.within) { |         if (locator.within) { | ||||||
|             const withinElements = this.findElementsBasedOnText(locator.within); |             const withinElements = this.findElementsBasedOnText(locator.within); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user