MOBILE-4061 behat: Always use the runtime to communicate with the app
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…
Reference in New Issue