diff --git a/local_moodleappbehat/tests/behat/behat_app_helper.php b/local_moodleappbehat/tests/behat/behat_app_helper.php index 45dc62741..7427a8937 100644 --- a/local_moodleappbehat/tests/behat/behat_app_helper.php +++ b/local_moodleappbehat/tests/behat/behat_app_helper.php @@ -738,25 +738,36 @@ EOF; * This function is similar to the arg_time_to_string transformation, but it allows the time to be a sub-text of the string. * * @param string $text - * @return string Transformed text. + * @return string|string[] Transformed text. */ - protected function transform_time_to_string(string $text): string { + protected function transform_time_to_string(string $text): string|array { if (!preg_match('/##(.*)##/', $text, $matches)) { // No time found, return the original text. return $text; } $timepassed = explode('##', $matches[1]); + $basetime = time(); // If not a valid time string, then just return what was passed. - if ((($timestamp = strtotime($timepassed[0])) === false)) { + if ((($timestamp = strtotime($timepassed[0], $basetime)) === false)) { return $text; } $count = count($timepassed); if ($count === 2) { // If timestamp with specified strftime format, then return formatted date string. - return str_replace($matches[0], userdate($timestamp, $timepassed[1]), $text); + $result = [str_replace($matches[0], userdate($timestamp, $timepassed[1]), $text)]; + + // If it's a relative date, allow a difference of 1 minute for the base time used to calculate the timestampt. + if ($timestamp !== strtotime($timepassed[0], 0)) { + $timestamp = strtotime($timepassed[0], $basetime - 60); + $result[] = str_replace($matches[0], userdate($timestamp, $timepassed[1]), $text); + } + + $result = array_unique($result); + + return count($result) == 1 ? $result[0] : $result; } else if ($count === 1) { return str_replace($matches[0], $timestamp, $text); } else { diff --git a/src/testing/services/behat-dom.ts b/src/testing/services/behat-dom.ts index d053e331e..94fa3e803 100644 --- a/src/testing/services/behat-dom.ts +++ b/src/testing/services/behat-dom.ts @@ -124,9 +124,13 @@ export class TestingBehatDomUtilsService { */ protected findElementsBasedOnTextWithinWithExact( container: HTMLElement, - text: string, + text: string | string[], options: TestingBehatFindOptions, ): ElementsWithExact[] { + if (Array.isArray(text)) { + return text.map((text) => this.findElementsBasedOnTextWithinWithExact(container, text, options)).flat(); + } + // Escape double quotes to prevent breaking the query selector. const escapedText = text.replace(/"/g, '\\"'); const attributesSelector = `[aria-label*="${escapedText}"], a[title*="${escapedText}"], ` + @@ -266,7 +270,7 @@ export class TestingBehatDomUtilsService { */ protected findElementsBasedOnTextWithin( container: HTMLElement, - text: string, + text: string | string[], options: TestingBehatFindOptions, ): HTMLElement[] { const elements = this.findElementsBasedOnTextWithinWithExact(container, text, options); @@ -495,6 +499,17 @@ export class TestingBehatDomUtilsService { locator: TestingBehatElementLocator, options: TestingBehatFindOptions = {}, ): HTMLElement | undefined { + if (Array.isArray(locator.text)) { + for (const text of locator.text) { + const element = this.findElementBasedOnText({ ...locator, text }); + if (element) { + return element; + } + } + + return undefined; + } + // Remove extra spaces. const treatedText = locator.text.trim().replace(/\s\s+/g, ' '); if (treatedText !== locator.text) { diff --git a/src/testing/services/behat-runtime.ts b/src/testing/services/behat-runtime.ts index d3c612236..b5530f8d7 100644 --- a/src/testing/services/behat-runtime.ts +++ b/src/testing/services/behat-runtime.ts @@ -809,7 +809,7 @@ export type TestingBehatFindOptions = { }; export type TestingBehatElementLocator = { - text: string; + text: string | string[]; within?: TestingBehatElementLocator; near?: TestingBehatElementLocator; selector?: string;