From 0ef35242638afb9bd1f3e0a3a593076d804b84fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 4 Sep 2024 16:43:49 +0200 Subject: [PATCH] MOBILE-4616 behat: Block navigation on behat steps --- src/testing/services/behat-blocking.ts | 62 +++++++++++++++++++++++++- src/testing/services/behat-runtime.ts | 4 ++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/testing/services/behat-blocking.ts b/src/testing/services/behat-blocking.ts index b56159ea4..e82a66509 100644 --- a/src/testing/services/behat-blocking.ts +++ b/src/testing/services/behat-blocking.ts @@ -14,8 +14,18 @@ import { Injectable } from '@angular/core'; import { CoreWait } from '@singletons/wait'; -import { makeSingleton, NgZone } from '@singletons'; +import { makeSingleton, NgZone, Router } from '@singletons'; import { BehatTestsWindow, TestingBehatRuntime } from './behat-runtime'; +import { + GuardsCheckEnd, + GuardsCheckStart, + NavigationCancel, + NavigationEnd, + NavigationError, + NavigationStart, +} from '@angular/router'; +import { Subscription, filter } from 'rxjs'; +import { CoreNavigator } from '@services/navigator'; /** * Behat block JS manager. @@ -24,10 +34,12 @@ import { BehatTestsWindow, TestingBehatRuntime } from './behat-runtime'; export class TestingBehatBlockingService { protected waitingBlocked = false; + protected waitingGuardEnd = false; protected recentMutation = false; protected lastMutation = 0; protected initialized = false; protected keyIndex = 0; + protected navSubscription?: Subscription; /** * Listen to mutations and override XML Requests. @@ -48,6 +60,47 @@ export class TestingBehatBlockingService { win.M.util = win.M.util ?? {}; win.M.util.pending_js = win.M.util.pending_js ?? []; + this.navSubscription = Router.events + .pipe(filter(event => + event instanceof NavigationStart || + event instanceof NavigationEnd || + event instanceof NavigationError || + event instanceof NavigationCancel || + event instanceof GuardsCheckStart || + event instanceof GuardsCheckEnd)) + .subscribe(async (event) => { + if (!('id' in event)) { + return; + } + + const blockName = `navigation-${event.id}`; + if (event instanceof NavigationStart) { + this.block(blockName); + } else if (event instanceof GuardsCheckStart) { + // This event is triggered before the guards are checked, so we need to wait for the end. + this.waitingGuardEnd = CoreNavigator.currentRouteCanBlockLeave(); + + // No deactivation needed. + if (!this.waitingGuardEnd) { + return; + } + + await CoreWait.wait(500); + + if (this.waitingGuardEnd) { + // The guard is still running (this case can unexpetedly unblock the tests) + // or a user confirmation is shown. Unblock. + this.waitingGuardEnd = false; + this.unblock(blockName); + } + } else if (event instanceof GuardsCheckEnd) { + // Guards check ended. + this.waitingGuardEnd = false; + } else { + this.unblock(blockName); + } + }); + TestingBehatRuntime.log('Initialized!'); } @@ -282,6 +335,13 @@ export class TestingBehatBlockingService { }; } + /** + * Wait for pending list to be empty. + */ + async waitForPending(): Promise { + await CoreWait.waitFor(() => this.pendingList.length === 0); + } + } export const TestingBehatBlocking = makeSingleton(TestingBehatBlockingService); diff --git a/src/testing/services/behat-runtime.ts b/src/testing/services/behat-runtime.ts index 17edcdcdb..65371cf45 100644 --- a/src/testing/services/behat-runtime.ts +++ b/src/testing/services/behat-runtime.ts @@ -269,6 +269,8 @@ export class TestingBehatRuntimeService { do { success = await this.goBack(); + + await TestingBehatBlocking.waitForPending(); } while (success); return 'OK'; @@ -289,6 +291,8 @@ export class TestingBehatRuntimeService { if (!success) { return 'ERROR: Back button not found'; } + + await TestingBehatBlocking.waitForPending(); } return 'OK';