MOBILE-4304 behat: Fix core file tests

main
Noel De Martin 2024-02-07 12:55:12 +01:00
parent 060256c0ea
commit 0c42071511
4 changed files with 97 additions and 12 deletions

View File

@ -936,6 +936,38 @@ class behat_app extends behat_app_helper {
}); });
} }
/**
* Check that the app opened a url.
*
* @Then /^the app should( not)? have opened url "([^"]+)"(?: with contents "([^"]+)")?(?: (once|\d+ times))?$/
* @param bool $not Whether to check if the app did not open the url
* @param string $urlpattern Url pattern
* @param string $contents Url contents
* @param string $times How many times the url should have been opened
*/
public function the_app_should_have_opened_url(bool $not, string $urlpattern, ?string $contents = null, ?string $times = null) {
if (is_null($times) || $times === 'once') {
$times = 1;
} else {
$times = intval(substr($times, 0, strlen($times) - 6));
}
$this->spin(function() use ($not, $urlpattern, $contents, $times) {
$result = $this->runtime_js("hasOpenedUrl('$urlpattern', '$contents', $times)");
// TODO process times
if ($not && $result === 'OK') {
throw new DriverException('Error, an url was opened that should not have');
}
if (!$not && $result !== 'OK') {
throw new DriverException('Error asserting that url was opened - ' . $result);
}
return true;
});
}
/** /**
* Switches to a newly-opened browser tab. * Switches to a newly-opened browser tab.
* *

View File

@ -35,25 +35,20 @@ Feature: It opens files properly.
Then I should find "This file may not work as expected on this device" in the app Then I should find "This file may not work as expected on this device" in the app
When I press "Open file" in the app When I press "Open file" in the app
Then the app should have opened a browser tab with url "^blob:" Then the app should have opened url "^blob:" with contents "Test resource A rtf.rtf file" once
When I switch to the browser tab opened by the app When I press "Open" in the app
Then I should see "Test resource A rtf.rtf file"
When I close the browser tab opened by the app
And I press "Open" in the app
Then I should find "This file may not work as expected on this device" in the app Then I should find "This file may not work as expected on this device" in the app
When I select "Don't show again." in the app When I select "Don't show again." in the app
And I press "Open file" in the app And I press "Open file" in the app
Then the app should have opened a browser tab with url "^blob:" Then the app should have opened url "^blob:" with contents "Test resource A rtf.rtf file" 2 times
When I close the browser tab opened by the app When I press "Open" in the app
And I press "Open" in the app Then I should not find "This file may not work as expected on this device" in the app
Then the app should have opened a browser tab with url "^blob:" And the app should have opened url "^blob:" with contents "Test resource A rtf.rtf file" 3 times
When I close the browser tab opened by the app When I press the back button in the app
And I press the back button in the app
And I press "Test DOC" in the app And I press "Test DOC" in the app
And I press "Open" in the app And I press "Open" in the app
Then I should find "This file may not work as expected on this device" in the app Then I should find "This file may not work as expected on this device" in the app

View File

@ -23,6 +23,12 @@ export type Constructor<T> = { new(...args: any[]): T };
*/ */
export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false; export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
/**
* Helper to get closure args.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type GetClosureArgs<T> = T extends (...args: infer TArgs) => any ? TArgs : never;
/** /**
* Helper type to flatten complex types. * Helper type to flatten complex types.
*/ */

View File

@ -31,6 +31,7 @@ import { CoreNavigator, CoreNavigatorService } from '@services/navigator';
import { CoreSwipeNavigationDirective } from '@directives/swipe-navigation'; import { CoreSwipeNavigationDirective } from '@directives/swipe-navigation';
import { Swiper } from 'swiper'; import { Swiper } from 'swiper';
import { LocalNotificationsMock } from '@features/emulator/services/local-notifications'; import { LocalNotificationsMock } from '@features/emulator/services/local-notifications';
import { GetClosureArgs } from '@/core/utils/types';
/** /**
* Behat runtime servive with public API. * Behat runtime servive with public API.
@ -39,6 +40,10 @@ import { LocalNotificationsMock } from '@features/emulator/services/local-notifi
export class TestingBehatRuntimeService { export class TestingBehatRuntimeService {
protected initialized = false; protected initialized = false;
protected openedUrls: {
args: GetClosureArgs<Window['open']>;
contents?: string;
}[] = [];
get cronDelegate(): CoreCronDelegateService { get cronDelegate(): CoreCronDelegateService {
return CoreCronDelegate.instance; return CoreCronDelegate.instance;
@ -90,6 +95,14 @@ export class TestingBehatRuntimeService {
document.cookie = 'MoodleAppConfig=' + JSON.stringify(options.configOverrides); document.cookie = 'MoodleAppConfig=' + JSON.stringify(options.configOverrides);
CoreConfig.patchEnvironment(options.configOverrides, { patchDefault: true }); CoreConfig.patchEnvironment(options.configOverrides, { patchDefault: true });
} }
// Spy on window.open.
const originalOpen = window.open.bind(window);
window.open = (...args) => {
this.openedUrls.push({ args });
return originalOpen(...args);
};
} }
/** /**
@ -274,6 +287,45 @@ export class TestingBehatRuntimeService {
} }
} }
/**
* Check whether the given url has been opened in the app.
*
* @param urlPattern Url pattern.
* @param contents Url contents.
* @param times How many times it should have been opened.
* @returns OK if successful, or ERROR: followed by message
*/
async hasOpenedUrl(urlPattern: string, contents: string, times: number): Promise<string> {
const urlRegExp = new RegExp(urlPattern);
const urlMatches = await Promise.all(this.openedUrls.map(async (openedUrl) => {
const renderedUrl = openedUrl.args[0]?.toString() ?? '';
if (!urlRegExp.test(renderedUrl)) {
return false;
}
if (contents && !('contents' in openedUrl)) {
const response = await fetch(renderedUrl);
openedUrl.contents = await response.text();
}
if (contents && contents !== openedUrl.contents) {
return false;
}
return true;
}));
if (urlMatches.filter(matches => !!matches).length === times) {
return 'OK';
}
return times === 1
? `ERROR: Url matching '${urlPattern}' with '${contents}' contents has not been opened once`
: `ERROR: Url matching '${urlPattern}' with '${contents}' contents has not been opened ${times} times`;
}
/** /**
* Load more items form an active list with infinite loader. * Load more items form an active list with infinite loader.
* *