Skip to content

Commit 35b64d9

Browse files
authored
Merge pull request #25 from NoelDeMartin/MOBILE-3320
MOBILE-3320: Navigation tests
2 parents 2ab5f4c + 9af35ae commit 35b64d9

File tree

4 files changed

+220
-44
lines changed

4 files changed

+220
-44
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
@mod @mod_messages @app @javascript
2+
Feature: Test messages navigation in the app
3+
4+
Background:
5+
Given the following "users" exist:
6+
| username | firstname |
7+
| teacher | Teacher |
8+
| student | Student |
9+
And the following "courses" exist:
10+
| fullname | shortname |
11+
| Course 1 | C1 |
12+
And the following "course enrolments" exist:
13+
| user | course | role |
14+
| teacher | C1 | editingteacher |
15+
| student | C1 | student |
16+
17+
Scenario: Avoid recursive links to profile
18+
When I enter the app
19+
And I log in as "teacher"
20+
And I press "Messages" in the app
21+
And I press "Contacts" in the app
22+
And I press "Search people and messages" in the app
23+
And I set the field "Search" to "student" in the app
24+
And I press "Search" "button" in the app
25+
And I press "Student" in the app
26+
And I set the field "New message" to "Hi there" in the app
27+
And I press "Send" in the app
28+
Then I should find "Hi there" in the app
29+
30+
When I press "Display options" in the app
31+
And I press "User info" in the app
32+
Then I should find "Details" in the app
33+
34+
When I press "Message" in the app
35+
Then I should find "Hi there" in the app
36+
37+
When I press "Display options" in the app
38+
Then I should not find "User info" in the app
39+
40+
When I press the back button in the app
41+
And I press the back button in the app
42+
Then I should find "Hi there" in the app

tests/behat/behat_app.php

Lines changed: 120 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ public function i_launch_the_app() {
100100
$this->prepare_browser();
101101
}
102102

103+
/**
104+
* @Then /^I wait the app to restart$/
105+
*/
106+
public function i_wait_the_app_to_restart() {
107+
// Wait window to reload.
108+
$this->spin(function() {
109+
return $this->evaluate_script("return !window.behat;");
110+
});
111+
112+
// Prepare testing runtime again.
113+
$this->prepare_browser(false);
114+
}
115+
103116
/**
104117
* Finds elements in the app.
105118
*
@@ -347,24 +360,28 @@ public static function close_ionic() {
347360
* @param string $url App URL
348361
* @throws DriverException If the app fails to load properly
349362
*/
350-
protected function prepare_browser() {
351-
// Restart the browser and set its size.
352-
$this->getSession()->restart();
353-
$this->resize_window('360x720', true);
363+
protected function prepare_browser(bool $restart = true) {
364+
if ($restart) {
365+
// Restart the browser and set its size.
366+
$this->getSession()->restart();
367+
$this->resize_window('360x720', true);
368+
369+
if (empty($this->ionicurl)) {
370+
$this->ionicurl = $this->start_or_reuse_ionic();
371+
}
354372

355-
if (empty($this->ionicurl)) {
356-
$this->ionicurl = $this->start_or_reuse_ionic();
357-
}
373+
// Check whether the app is running a legacy version.
374+
$json = @file_get_contents("{$this->ionicurl}/assets/env.json") ?: @file_get_contents("{$this->ionicurl}/config.json");
375+
$data = json_decode($json);
376+
$appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname);
358377

359-
// Check whether the app is running a legacy version.
360-
$json = @file_get_contents("{$this->ionicurl}/assets/env.json") ?: @file_get_contents("{$this->ionicurl}/config.json");
361-
$data = json_decode($json);
362-
$appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname);
378+
$this->islegacy = version_compare($appversion, '3.9.5', '<');
363379

364-
$this->islegacy = version_compare($appversion, '3.9.5', '<');
380+
// Visit the Ionic URL.
381+
$this->getSession()->visit($this->ionicurl);
382+
}
365383

366-
// Visit the Ionic URL and wait for it to load.
367-
$this->getSession()->visit($this->ionicurl);
384+
// Wait the application to load.
368385
$this->spin(function($context) {
369386
$title = $context->getSession()->getPage()->find('xpath', '//title');
370387

@@ -387,34 +404,36 @@ protected function prepare_browser() {
387404
$this->execute_script("window.BehatMoodleAppLegacy = $islegacyboolean;");
388405
$this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js'));
389406

390-
// Assert initial page.
391-
$this->spin(function($context) {
392-
$page = $context->getSession()->getPage();
393-
$element = $page->find('xpath', '//page-core-login-site//input[@name="url"]');
407+
if ($restart) {
408+
// Assert initial page.
409+
$this->spin(function($context) {
410+
$page = $context->getSession()->getPage();
411+
$element = $page->find('xpath', '//page-core-login-site//input[@name="url"]');
394412

395-
if ($element) {
396-
// Wait for the onboarding modal to open, if any.
397-
$this->wait_for_pending_js();
413+
if ($element) {
414+
// Wait for the onboarding modal to open, if any.
415+
$this->wait_for_pending_js();
398416

399-
$element = $this->islegacy
400-
? $page->find('xpath', '//page-core-login-site-onboarding')
401-
: $page->find('xpath', '//core-login-site-onboarding');
417+
$element = $this->islegacy
418+
? $page->find('xpath', '//page-core-login-site-onboarding')
419+
: $page->find('xpath', '//core-login-site-onboarding');
402420

403-
if ($element) {
404-
$this->i_press_in_the_app($this->parse_element_locator('"Skip"'));
405-
}
421+
if ($element) {
422+
$this->i_press_in_the_app($this->parse_element_locator('"Skip"'));
423+
}
406424

407-
// Login screen found.
408-
return true;
409-
}
425+
// Login screen found.
426+
return true;
427+
}
410428

411-
if ($page->find('xpath', '//page-core-mainmenu')) {
412-
// Main menu found.
413-
return true;
414-
}
429+
if ($page->find('xpath', '//page-core-mainmenu')) {
430+
// Main menu found.
431+
return true;
432+
}
415433

416-
throw new DriverException('Moodle app not launched properly');
417-
}, false, 60);
434+
throw new DriverException('Moodle app not launched properly');
435+
}, false, 60);
436+
}
418437

419438
// Continue only after JS finishes.
420439
$this->wait_for_pending_js();
@@ -484,12 +503,12 @@ public function i_press_the_standard_button_in_the_app(string $button) {
484503
}
485504

486505
/**
487-
* Receives push notifications for forum events.
506+
* Receives push notifications.
488507
*
489-
* @Given /^I receive a forum push notification for:$/
508+
* @Given /^I receive a push notification in the app for:$/
490509
* @param TableNode $data
491510
*/
492-
public function i_receive_a_forum_push_notification(TableNode $data) {
511+
public function i_receive_a_push_notification(TableNode $data) {
493512
global $DB, $CFG;
494513

495514
$data = (object) $data->getColumnsHash()[0];
@@ -513,6 +532,41 @@ public function i_receive_a_forum_push_notification(TableNode $data) {
513532
$this->wait_for_pending_js();
514533
}
515534

535+
/**
536+
* Replace arguments from the content in the given activity field.
537+
*
538+
* @Given /^I replace the arguments in "([^"]+)" "([^"]+)"$/
539+
*/
540+
public function i_replace_arguments_in_the_activity(string $idnumber, string $field) {
541+
global $DB;
542+
543+
$coursemodule = $DB->get_record('course_modules', compact('idnumber'));
544+
$module = $DB->get_record('modules', ['id' => $coursemodule->module]);
545+
$activity = $DB->get_record($module->name, ['id' => $coursemodule->instance]);
546+
547+
$DB->update_record($module->name, [
548+
'id' => $coursemodule->instance,
549+
$field => $this->replace_arguments($activity->{$field}),
550+
]);
551+
}
552+
553+
/**
554+
* Opens a custom link.
555+
*
556+
* @Given /^I open a custom link in the app for:$/
557+
*/
558+
public function i_open_a_custom_link(TableNode $data) {
559+
global $DB, $CFG;
560+
561+
$data = (object) $data->getColumnsHash()[0];
562+
$discussion = $DB->get_record('forum_discussions', ['name' => $data->discussion]);
563+
$pageurl = "{$CFG->behat_wwwroot}/mod/forum/discuss.php?d={$discussion->id}";
564+
$url = "moodlemobile://link=" . urlencode($pageurl);
565+
566+
$this->evaluate_script("return window.urlSchemes.handleCustomURL('$url')");
567+
$this->wait_for_pending_js();
568+
}
569+
516570
/**
517571
* Closes a popup by clicking on the 'backdrop' behind it.
518572
*
@@ -853,4 +907,31 @@ public function replace_wwwroot($text) {
853907
return str_replace('$WWWROOT', $CFG->behat_wwwroot, $text);
854908
}
855909

910+
/**
911+
* Replace arguments with the format "${activity:field}" from a string, where "activity" is
912+
* the idnumber of an activity and "field" is the activity's field to get replacement from.
913+
*
914+
* At the moment, the only field supported is "cmid", the id of the course module for this activity.
915+
*
916+
* @param string $text Original text.
917+
* @return string Text with arguments replaced.
918+
*/
919+
protected function replace_arguments(string $text): string {
920+
global $DB;
921+
922+
preg_match_all("/\\$\\{([^:}]+):([^}]+)\\}/", $text, $matches);
923+
924+
foreach ($matches[0] as $index => $match) {
925+
switch ($matches[2][$index]) {
926+
case 'cmid':
927+
$coursemodule = $DB->get_record('course_modules', ['idnumber' => $matches[1][$index]]);
928+
$text = str_replace($match, $coursemodule->id, $text);
929+
930+
break;
931+
}
932+
}
933+
934+
return $text;
935+
}
936+
856937
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@app @javascript
2+
Feature: It navigates properly within activities.
3+
4+
Background:
5+
Given the following "users" exist:
6+
| username |
7+
| student |
8+
And the following "courses" exist:
9+
| fullname | shortname |
10+
| Course 1 | C1 |
11+
And the following "course enrolments" exist:
12+
| user | course | role |
13+
| student | C1 | student |
14+
And the following "activities" exist:
15+
| activity | idnumber | course | name | intro | content |
16+
| label | label | C1 | Label | Label description | - |
17+
| page | page | C1 | Page | - | <a href="/mod/label/view.php?id=${label:cmid}">Go to label</a> |
18+
And I replace the arguments in "page" "content"
19+
20+
Scenario: Navigates using deep links
21+
When I enter the app
22+
And I log in as "student"
23+
And I press "Course 1" in the app
24+
And I press "Page" in the app
25+
And I press "Go to label" in the app
26+
Then I should find "Label description" in the app
27+
28+
When I press the back button in the app
29+
Then I should find "Go to label" in the app
30+
31+
When I press the back button in the app
32+
Then I should find "Label description" in the app

tests/behat/navigation_pushnotifications.feature renamed to tests/behat/navigation_deeplinks.feature

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@app @javascript
2-
Feature: It navigates properly after receiving push notifications.
2+
Feature: It navigates properly using deep links.
33

44
Background:
55
Given the following "users" exist:
@@ -22,7 +22,7 @@ Feature: It navigates properly after receiving push notifications.
2222
And the following config values are set as admin:
2323
| forcelogout | 1 | tool_mobile |
2424

25-
Scenario: Open a forum push notification
25+
Scenario: Receive a push notification
2626
When I enter the app
2727
And I log in as "student2"
2828
And I press the main menu button in the app
@@ -31,12 +31,33 @@ Feature: It navigates properly after receiving push notifications.
3131
And I set the field "Your site" to "$WWWROOT" in the app
3232
And I press "Connect to your site" in the app
3333
And I log in as "student1"
34-
And I receive a forum push notification for:
35-
| username | course | module | discussion |
36-
| student2 | C1 | forum | Forum topic |
34+
And I receive a push notification in the app for:
35+
| username | module | discussion |
36+
| student2 | forum | Forum topic |
3737
Then I should find "Reconnect" in the app
3838

3939
When I set the field "Password" to "student2" in the app
4040
And I press "Log in" in the app
4141
Then I should find "Forum topic" in the app
4242
And I should find "Forum message" in the app
43+
But I should not find "Site home" in the app
44+
45+
When I press the back button in the app
46+
Then I should find "Site home" in the app
47+
But I should not find "Forum topic" in the app
48+
And I should not find "Forum message" in the app
49+
50+
Scenario: Open a link with a custom URL
51+
When I launch the app
52+
And I open a custom link in the app for:
53+
| discussion |
54+
| Forum topic |
55+
And I log in as "student1"
56+
Then I should find "Forum topic" in the app
57+
And I should find "Forum message" in the app
58+
But I should not find "Site home" in the app
59+
60+
When I press the back button in the app
61+
Then I should find "Site home" in the app
62+
But I should not find "Forum topic" in the app
63+
And I should not find "Forum message" in the app

0 commit comments

Comments
 (0)