MOBILE-4061 behat: Always use the runtime to communicate with the app
This commit is contained in:
		
							parent
							
								
									f69e7971be
								
							
						
					
					
						commit
						ef574e7e63
					
				@ -408,7 +408,7 @@ class behat_app extends behat_app_helper {
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->evaluate_script("return window.pushNotifications.notificationClicked($notification)");
 | 
					        $this->evaluate_script("window.behat.notificationClicked($notification)");
 | 
				
			||||||
        $this->wait_for_pending_js();
 | 
					        $this->wait_for_pending_js();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -717,25 +717,8 @@ class behat_app extends behat_app_helper {
 | 
				
			|||||||
     * @When I run cron tasks in the app
 | 
					     * @When I run cron tasks in the app
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function i_run_cron_tasks_in_the_app() {
 | 
					    public function i_run_cron_tasks_in_the_app() {
 | 
				
			||||||
        $session = $this->getSession();
 | 
					        $this->evaluate_script('window.behat.forceSyncExecution()');
 | 
				
			||||||
 | 
					        $this->wait_for_pending_js();
 | 
				
			||||||
        // Force cron tasks execution and wait until they are completed.
 | 
					 | 
				
			||||||
        $operationid = random_string();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $session->executeScript(
 | 
					 | 
				
			||||||
            "cronProvider.forceSyncExecution().then(() => { window['behat_{$operationid}_completed'] = true; });"
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        $this->spin(
 | 
					 | 
				
			||||||
            function() use ($session, $operationid) {
 | 
					 | 
				
			||||||
                return $session->evaluateScript("window['behat_{$operationid}_completed'] || false");
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            false,
 | 
					 | 
				
			||||||
            60,
 | 
					 | 
				
			||||||
            new ExpectationException('Forced cron tasks in the app took too long to complete', $session)
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Trigger Angular change detection.
 | 
					 | 
				
			||||||
        $this->trigger_angular_change_detection();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -744,28 +727,8 @@ class behat_app extends behat_app_helper {
 | 
				
			|||||||
     * @When I wait loading to finish in the app
 | 
					     * @When I wait loading to finish in the app
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function i_wait_loading_to_finish_in_the_app() {
 | 
					    public function i_wait_loading_to_finish_in_the_app() {
 | 
				
			||||||
        $session = $this->getSession();
 | 
					        $this->evaluate_script('window.behat.waitLoadingToFinish()');
 | 
				
			||||||
 | 
					        $this->wait_for_pending_js();
 | 
				
			||||||
        $this->spin(
 | 
					 | 
				
			||||||
            function() use ($session) {
 | 
					 | 
				
			||||||
                $this->trigger_angular_change_detection();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                $nodes = $this->find_all('css', 'core-loading ion-spinner');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                foreach ($nodes as $node) {
 | 
					 | 
				
			||||||
                    if (!$node->isVisible()) {
 | 
					 | 
				
			||||||
                        continue;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            false,
 | 
					 | 
				
			||||||
            60,
 | 
					 | 
				
			||||||
            new ExpectationException('"Loading took too long to complete', $session)
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -786,7 +749,7 @@ class behat_app extends behat_app_helper {
 | 
				
			|||||||
            $this->getSession()->switchToWindow($names[1]);
 | 
					            $this->getSession()->switchToWindow($names[1]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->execute_script('window.close();');
 | 
					        $this->evaluate_script('window.close();');
 | 
				
			||||||
        $this->getSession()->switchToWindow($names[0]);
 | 
					        $this->getSession()->switchToWindow($names[0]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -798,7 +761,7 @@ class behat_app extends behat_app_helper {
 | 
				
			|||||||
     * @throws DriverException If the navigator.online mode is not available
 | 
					     * @throws DriverException If the navigator.online mode is not available
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function i_switch_offline_mode(string $offline) {
 | 
					    public function i_switch_offline_mode(string $offline) {
 | 
				
			||||||
        $this->execute_script("appProvider.setForceOffline($offline);");
 | 
					        $this->evaluate_script("window.behat.network.setForceOffline($offline);");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -318,7 +318,7 @@ class behat_app_helper extends behat_base {
 | 
				
			|||||||
            $initOptions->skipOnBoarding = $options['skiponboarding'] ?? true;
 | 
					            $initOptions->skipOnBoarding = $options['skiponboarding'] ?? true;
 | 
				
			||||||
            $initOptions->configOverrides = $this->appconfig;
 | 
					            $initOptions->configOverrides = $this->appconfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $this->execute_script('window.behatInit(' . json_encode($initOptions) . ');');
 | 
					            $this->evaluate_script('window.behatInit(' . json_encode($initOptions) . ');');
 | 
				
			||||||
        } catch (Exception $error) {
 | 
					        } catch (Exception $error) {
 | 
				
			||||||
            throw new DriverException('Moodle App not running or not running on Automated mode.');
 | 
					            throw new DriverException('Moodle App not running or not running on Automated mode.');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -433,14 +433,6 @@ class behat_app_helper extends behat_base {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Trigger Angular change detection.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected function trigger_angular_change_detection() {
 | 
					 | 
				
			||||||
        $this->getSession()->executeScript('ngZone.run(() => {});');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Evaluate a script that returns a Promise.
 | 
					     * Evaluate a script that returns a Promise.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -431,7 +431,7 @@ export class CorePushNotificationsProvider {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Function called when a push notification is clicked. Redirect the user to the right state.
 | 
					     * Function called when a push notification is clicked. Redirect the user to the right state.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param notification Notification.
 | 
					     * @param data Notification data.
 | 
				
			||||||
     * @return Promise resolved when done.
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    async notificationClicked(data: CorePushNotificationsNotificationBasicData): Promise<void> {
 | 
					    async notificationClicked(data: CorePushNotificationsNotificationBasicData): Promise<void> {
 | 
				
			||||||
 | 
				
			|||||||
@ -12,35 +12,15 @@
 | 
				
			|||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ApplicationRef, NgZone as NgZoneService } from '@angular/core';
 | 
					import { CoreAppProvider } from '@services/app';
 | 
				
			||||||
import { CorePushNotifications, CorePushNotificationsProvider } from '@features/pushnotifications/services/pushnotifications';
 | 
					 | 
				
			||||||
import { CoreApp, CoreAppProvider } from '@services/app';
 | 
					 | 
				
			||||||
import { CoreConfig, CoreConfigProvider } from '@services/config';
 | 
					 | 
				
			||||||
import { CoreCronDelegate, CoreCronDelegateService } from '@services/cron';
 | 
					 | 
				
			||||||
import { CoreDB, CoreDbProvider } from '@services/db';
 | 
					import { CoreDB, CoreDbProvider } from '@services/db';
 | 
				
			||||||
import { CoreCustomURLSchemes, CoreCustomURLSchemesProvider } from '@services/urlschemes';
 | 
					 | 
				
			||||||
import { Application, NgZone } from '@singletons';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AutomatedTestsWindow = Window & {
 | 
					type AutomatedTestsWindow = Window & {
 | 
				
			||||||
    appRef?: ApplicationRef;
 | 
					 | 
				
			||||||
    appProvider?: CoreAppProvider;
 | 
					 | 
				
			||||||
    dbProvider?: CoreDbProvider;
 | 
					    dbProvider?: CoreDbProvider;
 | 
				
			||||||
    configProvider?: CoreConfigProvider;
 | 
					 | 
				
			||||||
    cronProvider?: CoreCronDelegateService;
 | 
					 | 
				
			||||||
    ngZone?: NgZoneService;
 | 
					 | 
				
			||||||
    pushNotifications?: CorePushNotificationsProvider;
 | 
					 | 
				
			||||||
    urlSchemes?: CoreCustomURLSchemesProvider;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function initializeAutomatedTestsWindow(window: AutomatedTestsWindow) {
 | 
					function initializeAutomatedTestsWindow(window: AutomatedTestsWindow) {
 | 
				
			||||||
    window.appRef = Application.instance;
 | 
					 | 
				
			||||||
    window.appProvider = CoreApp.instance;
 | 
					 | 
				
			||||||
    window.dbProvider = CoreDB.instance;
 | 
					    window.dbProvider = CoreDB.instance;
 | 
				
			||||||
    window.configProvider = CoreConfig.instance;
 | 
					 | 
				
			||||||
    window.cronProvider = CoreCronDelegate.instance;
 | 
					 | 
				
			||||||
    window.ngZone = NgZone.instance;
 | 
					 | 
				
			||||||
    window.pushNotifications = CorePushNotifications.instance;
 | 
					 | 
				
			||||||
    window.urlSchemes = CoreCustomURLSchemes.instance;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function(): void {
 | 
					export default function(): void {
 | 
				
			||||||
 | 
				
			|||||||
@ -468,7 +468,7 @@ export class TestsBehatDomUtils {
 | 
				
			|||||||
     * @param element Element to press.
 | 
					     * @param element Element to press.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    static async pressElement(element: HTMLElement): Promise<void> {
 | 
					    static async pressElement(element: HTMLElement): Promise<void> {
 | 
				
			||||||
        NgZone.run(async () => {
 | 
					        await NgZone.run(async () => {
 | 
				
			||||||
            const blockKey = TestsBehatBlocking.block();
 | 
					            const blockKey = TestsBehatBlocking.block();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Events don't bubble up across Shadow DOM boundaries, and some buttons
 | 
					            // Events don't bubble up across Shadow DOM boundaries, and some buttons
 | 
				
			||||||
@ -511,7 +511,7 @@ export class TestsBehatDomUtils {
 | 
				
			|||||||
     * @param value Value to be set.
 | 
					     * @param value Value to be set.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    static async setElementValue(element: HTMLElement, value: string): Promise<void> {
 | 
					    static async setElementValue(element: HTMLElement, value: string): Promise<void> {
 | 
				
			||||||
        NgZone.run(async () => {
 | 
					        await NgZone.run(async () => {
 | 
				
			||||||
            const blockKey = TestsBehatBlocking.block();
 | 
					            const blockKey = TestsBehatBlocking.block();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Functions to get/set value depending on field type.
 | 
					            // Functions to get/set value depending on field type.
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,15 @@ import { CoreLoginHelperProvider } from '@features/login/services/login-helper';
 | 
				
			|||||||
import { CoreConfig } from '@services/config';
 | 
					import { CoreConfig } from '@services/config';
 | 
				
			||||||
import { EnvironmentConfig } from '@/types/config';
 | 
					import { EnvironmentConfig } from '@/types/config';
 | 
				
			||||||
import { NgZone } from '@singletons';
 | 
					import { NgZone } from '@singletons';
 | 
				
			||||||
 | 
					import { CoreNetwork } from '@services/network';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    CorePushNotifications,
 | 
				
			||||||
 | 
					    CorePushNotificationsNotificationBasicData,
 | 
				
			||||||
 | 
					} from '@features/pushnotifications/services/pushnotifications';
 | 
				
			||||||
 | 
					import { CoreCronDelegate } from '@services/cron';
 | 
				
			||||||
 | 
					import { CoreLoadingComponent } from '@components/loading/loading';
 | 
				
			||||||
 | 
					import { CoreComponentsRegistry } from '@singletons/components-registry';
 | 
				
			||||||
 | 
					import { CoreDom } from '@singletons/dom';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Behat runtime servive with public API.
 | 
					 * Behat runtime servive with public API.
 | 
				
			||||||
@ -46,6 +55,10 @@ export class TestsBehatRuntime {
 | 
				
			|||||||
            scrollTo: TestsBehatRuntime.scrollTo,
 | 
					            scrollTo: TestsBehatRuntime.scrollTo,
 | 
				
			||||||
            setField: TestsBehatRuntime.setField,
 | 
					            setField: TestsBehatRuntime.setField,
 | 
				
			||||||
            handleCustomURL: TestsBehatRuntime.handleCustomURL,
 | 
					            handleCustomURL: TestsBehatRuntime.handleCustomURL,
 | 
				
			||||||
 | 
					            notificationClicked: TestsBehatRuntime.notificationClicked,
 | 
				
			||||||
 | 
					            forceSyncExecution: TestsBehatRuntime.forceSyncExecution,
 | 
				
			||||||
 | 
					            waitLoadingToFinish: TestsBehatRuntime.waitLoadingToFinish,
 | 
				
			||||||
 | 
					            network: CoreNetwork.instance,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!options) {
 | 
					        if (!options) {
 | 
				
			||||||
@ -85,6 +98,64 @@ export class TestsBehatRuntime {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Function called when a push notification is clicked. Redirect the user to the right state.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data Notification data.
 | 
				
			||||||
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static async notificationClicked(data: CorePushNotificationsNotificationBasicData): Promise<void> {
 | 
				
			||||||
 | 
					        const blockKey = TestsBehatBlocking.block();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            await NgZone.run(async () => {
 | 
				
			||||||
 | 
					                await CorePushNotifications.notificationClicked(data);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            TestsBehatBlocking.unblock(blockKey);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Force execution of synchronization cron tasks without waiting for the scheduled time.
 | 
				
			||||||
 | 
					     * Please notice that some tasks may not be executed depending on the network connection and sync settings.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Promise resolved if all handlers are executed successfully, rejected otherwise.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static async forceSyncExecution(): Promise<void> {
 | 
				
			||||||
 | 
					        const blockKey = TestsBehatBlocking.block();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            await NgZone.run(async () => {
 | 
				
			||||||
 | 
					                await CoreCronDelegate.forceSyncExecution();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            TestsBehatBlocking.unblock(blockKey);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Wait all controlled components to be rendered.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Promise resolved when all components have been rendered.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static async waitLoadingToFinish(): Promise<void> {
 | 
				
			||||||
 | 
					        const blockKey = TestsBehatBlocking.block();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await NgZone.run(async () => {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                const elements = Array.from(document.body.querySelectorAll<HTMLElement>('core-loading'))
 | 
				
			||||||
 | 
					                    .filter((element) => CoreDom.isElementVisible(element));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                await Promise.all(elements.map(element =>
 | 
				
			||||||
 | 
					                    CoreComponentsRegistry.waitComponentReady(element, CoreLoadingComponent)));
 | 
				
			||||||
 | 
					            } finally {
 | 
				
			||||||
 | 
					                TestsBehatBlocking.unblock(blockKey);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Function to find and click an app standard button.
 | 
					     * Function to find and click an app standard button.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user