Merge remote-tracking moodle-local_moodlemobileapp into MOBILE-4061

main
Pau Ferrer Ocaña 2022-05-12 09:31:55 +02:00
commit edbaa14423
37 changed files with 7262 additions and 0 deletions

View File

@ -0,0 +1,42 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace local_moodlemobileapp\output;
defined('MOODLE_INTERNAL') || die();
class mobile {
/**
* Render index page.
*
* @return array View data.
*/
public static function view_index() {
$templates = [
[
'id' => 'main',
'html' => '<h1 class="text-center">Hello<span id="username"></span>!</h1>',
],
];
$javascript = file_get_contents(__DIR__ . '/../../js/mobile/index.js');
return compact('templates', 'javascript');
}
}

34
db/mobile.php 100644
View File

@ -0,0 +1,34 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
$addons = [
'local_moodlemobileapp' => [
'handlers' => [
'index' => [
'delegate' => 'CoreMainMenuDelegate',
'method' => 'view_index',
'displaydata' => [
'title' => 'pluginname',
'icon' => 'language',
],
],
],
'lang' => [
['pluginname', 'local_moodlemobileapp'],
],
],
];

View File

@ -0,0 +1,5 @@
this.CoreSitesProvider.getSite().then(site => {
const username = site.infos.username;
document.getElementById('username').innerText = `, ${username}`;
});

View File

@ -0,0 +1,154 @@
@mod @mod_assign @app @javascript
Feature: Test basic usage of assignment activity in app
In order to participate in the assignment while using the mobile app
I need basic assignment functionality to work
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | teacher | teacher1@example.com |
| student1 | Student | student | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | attemptreopenmethod |
| assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1029844800 | manual |
Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission
# Create, edit and submit as a student
When I enter the course "Course 1" as "student1" in the app
And I press "assignment1" in the app
Then the header should be "assignment1" in the app
And I should find "Test assignment description1" in the app
And I should find "Due:" in the app
And I should find "20 August 2002, 12:00 PM" in the app
When I press "Add submission" in the app
And I set the field "Online text submissions" to "Submission test" in the app
And I press "Save" in the app
Then I should find "Draft (not submitted)" in the app
And I should find "Not graded" in the app
When I press "Edit submission" in the app
And I set the field "Online text submissions" to "Submission test edited" in the app
And I press "Save" in the app
And I press "OK" in the app
Then I should find "Submission test edited" in the app
When I press "Submit assignment" in the app
And I press "OK" in the app
Then I should find "Submitted for grading" in the app
And I should find "Not graded" in the app
And I should find "Submission test edited" in the app
# View as a teacher
When I enter the course "Course 1" as "teacher1" in the app
And I press "assignment1" in the app
Then the header should be "assignment1" in the app
When I press "Submitted" in the app
Then I should find "Student student" in the app
And I should find "Not graded" in the app
When I press "Student student" near "assignment1" in the app
Then I should find "Online text submissions" in the app
And I should find "Submission test edited" in the app
Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading
# Submit first attempt as a student
Given I enter the course "Course 1" as "student1" in the app
And I press "assignment1" in the app
And I press "Add submission" in the app
And I set the field "Online text submissions" to "Submission test 1st attempt" in the app
And I press "Save" in the app
And I press "Submit assignment" in the app
And I press "OK" in the app
# Allow more attempts as a teacher
When I enter the course "Course 1" as "teacher1" in the app
And I press "assignment1" in the app
And I press "Participants" in the app
And I press "Student student" near "assignment1" in the app
And I press "Grade" in the app
And I press "Allow another attempt" in the app
And I press "Done" in the app
Then I should find "Reopened" in the app
And I should find "Not graded" in the app
# Submit second attempt as a student
When I enter the course "Course 1" as "student1" in the app
And I press "assignment1" in the app
Then I should find "Reopened" in the app
And I should find "2 out of Unlimited" in the app
And I should find "Add a new attempt based on previous submission" in the app
And I should find "Add a new attempt" in the app
When I press "Add a new attempt based on previous submission" in the app
And I press "OK" in the app
Then I should find "Submission test 1st attempt" in the app
When I set the field "Online text submissions" to "Submission test 2nd attempt" in the app
And I press "Save" in the app
And I press "OK" in the app
And I press "Submit assignment" in the app
And I press "OK" in the app
# View second attempt as a teacher
When I enter the course "Course 1" as "teacher1" in the app
And I press "assignment1" in the app
And I press "Participants" in the app
And I press "Student student" near "assignment1" in the app
Then I should find "Online text submissions" in the app
And I should find "Submission test 2nd attempt" in the app
Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions
When I enter the course "Course 1" as "student1" in the app
And I press "assignment1" in the app
And I press "Add submission" in the app
And I switch offline mode to "true"
And I set the field "Online text submissions" to "Submission test" in the app
And I press "Save" in the app
And I press "Submit assignment" in the app
And I press "OK" in the app
Then I should find "This Assignment has offline data to be synchronised." in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "assignment1" in the app
And I press "Information" in the app
And I press "Refresh" in the app
Then I should find "Submitted for grading" in the app
But I should not find "This Assignment has offline data to be synchronised." in the app
Scenario: Edit an offline submission before synchronising it
When I enter the course "Course 1" as "student1" in the app
And I press "assignment1" in the app
And I press "Add submission" in the app
And I switch offline mode to "true"
And I set the field "Online text submissions" to "Submission test original offline" in the app
And I press "Save" in the app
Then I should find "This Assignment has offline data to be synchronised." in the app
And I should find "Submission test original offline" in the app
When I press "Edit submission" in the app
And I set the field "Online text submissions" to "Submission test edited offline" in the app
And I press "Save" in the app
Then I should find "This Assignment has offline data to be synchronised." in the app
And I should find "Submission test edited offline" in the app
But I should not find "Submission test original offline" in the app
When I press "Submit assignment" in the app
And I press "OK" in the app
Then I should find "This Assignment has offline data to be synchronised." in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "assignment1" in the app
Then I should find "Submitted for grading" in the app
And I should find "Submission test edited offline" in the app
But I should not find "This Assignment has offline data to be synchronised." in the app

View File

@ -0,0 +1,224 @@
@mod @mod_assign @app @javascript
Feature: Test assignments navigation
Background:
Given the following "users" exist:
| username | firstname | lastname |
| teacher1 | Teacher | teacher |
| student1 | First | Student |
| student2 | Second | Student |
| student3 | Third | Student |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student2 | G2 |
| student3 | G2 |
And the following "activities" exist:
| activity | name | course | idnumber | assignsubmission_onlinetext_enabled | duedate | groupmode |
| assign | Assignment | C1 | assignment | 1 | 0 | 1 |
And the following "mod_assign > submissions" exist:
| assign | user | onlinetext |
| assignment | student1 | Lorem |
| assignment | student3 | Ipsum |
Scenario: Mobile navigation
Given I enter the course "Course 1" as "teacher1" in the app
# Initial status
When I press "Assignment" in the app
Then I should find "3" near "Participants" in the app
And I should find "2" near "Drafts" in the app
# Participants
When I press "Participants" in the app
Then I should find "First Student" in the app
And I should find "Second Student" in the app
And I should find "Third Student" in the app
# Participants — swipe
When I press "First Student" in the app
And I swipe to the right in the app
Then I should find "First Student" in the app
But I should not find "Second Student" in the app
And I should not find "Third Student" in the app
When I swipe to the left in the app
Then I should find "Second Student" in the app
But I should not find "First Student" in the app
And I should not find "Third Student" in the app
When I swipe to the left in the app
Then I should find "Third Student" in the app
But I should not find "First Student" in the app
And I should not find "Second Student" in the app
When I swipe to the left in the app
Then I should find "Third Student" in the app
But I should not find "First Student" in the app
And I should not find "Second Student" in the app
# Drafts
When I press the back button in the app
And I press the back button in the app
And I press "Drafts" in the app
Then I should find "First Student" in the app
And I should find "Third Student" in the app
But I should not find "Second Student" in the app
# Drafts — swipe
When I press "First Student" in the app
And I swipe to the right in the app
Then I should find "First Student" in the app
But I should not find "Second Student" in the app
And I should not find "Third Student" in the app
When I swipe to the left in the app
Then I should find "Third Student" in the app
But I should not find "First Student" in the app
And I should not find "Second Student" in the app
When I swipe to the left in the app
Then I should find "Third Student" in the app
But I should not find "First Student" in the app
And I should not find "Second Student" in the app
# Filter groups in assignment page
When I press the back button in the app
And I press the back button in the app
And I press "Separate groups" in the app
And I press "Group 1" in the app
Then I should find "2" near "Participants" in the app
And I should find "1" near "Drafts" in the app
When I press "Participants" in the app
Then I should find "First Student" in the app
And I should find "Second Student" in the app
But I should not find "Third Student" in the app
When I press "First Student" in the app
And I swipe to the right in the app
Then I should find "First Student" in the app
But I should not find "Second Student" in the app
And I should not find "Third Student" in the app
When I swipe to the left in the app
Then I should find "Second Student" in the app
But I should not find "First Student" in the app
And I should not find "Third Student" in the app
When I swipe to the left in the app
Then I should find "Second Student" in the app
But I should not find "First Student" in the app
And I should not find "Third Student" in the app
# Filter groups in submissions page
When I press the back button in the app
And I press "Separate groups" in the app
And I press "Group 2" in the app
Then I should find "Second Student" in the app
And I should find "Third Student" in the app
But I should not find "First Student" in the app
When I press "Second Student" in the app
And I swipe to the right in the app
Then I should find "Second Student" in the app
But I should not find "First Student" in the app
And I should not find "Third Student" in the app
When I swipe to the left in the app
Then I should find "Third Student" in the app
But I should not find "First Student" in the app
And I should not find "Second Student" in the app
When I swipe to the left in the app
Then I should find "Third Student" in the app
But I should not find "First Student" in the app
And I should not find "Second Student" in the app
Scenario: Tablet navigation
Given I enter the course "Course 1" as "teacher1" in the app
And I change viewport size to "1200x640"
# Initial status
When I press "Assignment" in the app
Then I should find "3" near "Participants" in the app
And I should find "2" near "Drafts" in the app
# Participants
When I press "Participants" in the app
Then I should find "First Student" in the app
And I should find "Second Student" in the app
And I should find "Third Student" in the app
And "First Student" near "Third Student" should be selected in the app
And I should find "First Student" inside the split-view content in the app
But I should not find "Second Student" inside the split-view content in the app
And I should not find "Third Student" inside the split-view content in the app
# Participants — Split view
When I press "Second Student" in the app
Then "Second Student" near "Third Student" should be selected in the app
And I should find "Second Student" inside the split-view content in the app
But I should not find "First Student" inside the split-view content in the app
And I should not find "Third Student" inside the split-view content in the app
# Drafts
When I press the back button in the app
And I press "Drafts" in the app
Then I should find "First Student" in the app
And I should find "Third Student" in the app
And "First Student" near "Third Student" should be selected in the app
And I should find "First Student" inside the split-view content in the app
But I should not find "Second Student" in the app
And I should not find "Third Student" inside the split-view content in the app
# Drafts — Split view
When I press "Third Student" in the app
Then "Third Student" near "First Student" should be selected in the app
And I should find "Third Student" inside the split-view content in the app
But I should not find "First Student" inside the split-view content in the app
And I should not find "Second Student" in the app
# Filter groups in assignment page
When I press the back button in the app
And I press "Separate groups" in the app
And I press "Group 1" in the app
Then I should find "2" near "Participants" in the app
And I should find "1" near "Drafts" in the app
When I press "Participants" in the app
Then I should find "First Student" in the app
And I should find "Second Student" in the app
And "First Student" near "Second Student" should be selected in the app
And I should find "First Student" inside the split-view content in the app
But I should not find "Third Student" in the app
And I should not find "Second Student" inside the split-view content in the app
# Filter groups in submissions page
When I press "Separate groups" in the app
And I press "Group 2" in the app
Then I should find "Second Student" in the app
And I should find "Third Student" in the app
And "Second Student" near "Third Student" should be selected in the app
And I should find "Second Student" inside the split-view content in the app
But I should not find "First Student" in the app
And I should not find "Third Student" inside the split-view content in the app
When I press "Third Student" in the app
Then "Third Student" near "Second Student" should be selected in the app
And I should find "Third Student" inside the split-view content in the app
But I should not find "Second Student" inside the split-view content in the app
And I should not find "First Student" in the app

View File

@ -0,0 +1,76 @@
@mod @mod_chat @app @javascript
Feature: Test basic usage of chat in app
As a student
I need basic chat functionality to work
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username | firstname | lastname |
| student1 | david | student |
| student2 | pau | student2 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| chat | Test chat name | Test chat | C1 | chat | 0 |
Scenario: Receive and send messages & See connected users, beep and talk to
# Send messages as student1
When I enter the course "Course 1" as "student1" in the app
And I press "Test chat name" in the app
Then I should find "Enter the chat" in the app
And I should find "Past sessions" in the app
When I press "Enter the chat" in the app
And I set the field "New message" to "Hi!" in the app
And I press "Send" in the app
Then I should find "Hi!" in the app
When I set the field "New message" to "I am David" in the app
And I press "Send" in the app
Then I should find "Hi!" in the app
And I should find "I am David" in the app
# Read messages, view connected users, send beep and reply as student2
When I enter the course "Course 1" as "student2" in the app
And I press "Test chat name" in the app
And I press "Enter the chat" in the app
Then I should find "Hi!" in the app
And I should find "I am David" in the app
When I press "Users" in the app
Then I should find "david student" in the app
When I press "Beep" in the app
Then I should find "You beeped david student" in the app
When I set the field "New message" to "Hi David, I am Pau." in the app
And I press "Send" in the app
Then I should find "Hi David, I am Pau." in the app
Scenario: Past sessions shown
# Send messages as student1
Given I enter the course "Course 1" as "student1" in the app
And I press "Test chat name" in the app
And I press "Enter the chat" in the app
And I set the field "New message" to "Hi!" in the app
And I press "Send" in the app
Then I should find "Hi!" in the app
When I set the field "New message" to "I am David" in the app
And I press "Send" in the app
Then I should find "I am David" in the app
# Read messages from past sessions as student2
When I enter the course "Course 1" as "student2" in the app
And I press "Test chat name" in the app
And I press "Past sessions" in the app
And I press "Show incomplete sessions" in the app
And I press "david student" near "(2)" in the app
Then I should find "Hi!" in the app
And I should find "I am David" in the app

View File

@ -0,0 +1,44 @@
@mod @mod_chat @app @javascript
Feature: Test chat navigation
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username | firstname | lastname |
| student1 | Student | first |
| student2 | Student | second |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| chat | Test chat name | Test chat | C1 | chat | 0 |
# Create sessions
# TODO use generator instead
And I enter the course "Course 1" as "student1" in the app
And I press "Test chat name" in the app
And I press "Enter the chat" in the app
And I set the field "New message" to "Test message" in the app
And I press "Send" in the app
Then I should find "Test message" in the app
Scenario: Tablet navigation
Given I enter the course "Course 1" as "student2" in the app
And I change viewport size to "1200x640"
# Sessions
When I press "Test chat name" in the app
And I press "Past sessions" in the app
Then I should find "No sessions found" in the app
# Sessions — split view
When I press "Show incomplete sessions" in the app
Then "Student first" should be selected in the app
And I should find "Test message" in the app
When I press "Show incomplete sessions" in the app
Then I should not find "Student first" in the app
And I should not find "Test message" in the app

View File

@ -0,0 +1,190 @@
@mod @mod_choice @app @javascript
Feature: Test basic usage of choice activity in app
In order to participate in the choice while using the mobile app
As a student
I need basic choice functionality to work
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | teacher | teacher1@example.com |
| student1 | Student | student | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
Scenario: Answer a choice (multi or single, update answer) & View results
Given the following "activities" exist:
| activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults |
| choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test single choice name" in the app
And I select "Option 1" in the app
And I select "Option 2" in the app
And I press "Save my choice" in the app
Then I should find "Are you sure" in the app
When I press "OK" in the app
Then I should find "Option 1: 0" in the app
And I should find "Option 2: 1" in the app
And I should find "Option 3: 0" in the app
But I should not find "Remove my choice" in the app
When I press the back button in the app
And I press "Test single choice name" in the app
Then I should find "Option 1: 0" in the app
And I should find "Option 2: 1" in the app
And I should find "Option 3: 0" in the app
Scenario: Answer a choice (multi or single, update answer) & View results & Delete choice
Given the following "activities" exist:
| activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults |
| choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test multi choice name" in the app
And I select "Option 1" in the app
And I select "Option 2" in the app
And I press "Save my choice" in the app
Then I should find "Option 1: 1" in the app
And I should find "Option 2: 1" in the app
And I should find "Option 3: 0" in the app
And I should find "Remove my choice" in the app
When I unselect "Option 1" in the app
And I select "Option 3" in the app
And I press "Save my choice" in the app
Then I should find "Option 1: 0" in the app
And I should find "Option 2: 1" in the app
And I should find "Option 3: 1" in the app
When I press "Remove my choice" in the app
Then I should find "Are you sure" in the app
When I press "Delete" in the app
Then I should find "The results are not currently viewable" in the app
But I should not find "Remove my choice" in the app
Scenario: Answer and change answer offline & Sync choice
Given the following "activities" exist:
| activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults |
| choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test single choice name" in the app
And I select "Option 1" in the app
And I switch offline mode to "true"
And I select "Option 2" in the app
And I press "Save my choice" in the app
Then I should find "Are you sure" in the app
When I press "OK" in the app
And I press the back button in the app
And I press "Test single choice name" in the app
Then I should find "This Choice has offline data to be synchronised." in the app
But I should not find "Option 1: 0" in the app
And I should not find "Option 2: 1" in the app
And I should not find "Option 3: 0" in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "Test single choice name" in the app
Then I should find "Test single choice description" in the app
When I press "Information" in the app
And I press "Refresh" in the app
Then I should find "Option 1: 0" in the app
And I should find "Option 2: 1" in the app
And I should find "Option 3: 0" in the app
But I should not find "This Choice has offline data to be synchronised." in the app
Scenario: Answer and change answer offline & Auto-sync choice
Given the following "activities" exist:
| activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults |
| choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test single choice name" in the app
And I select "Option 1" in the app
And I switch offline mode to "true"
And I select "Option 2" in the app
And I press "Save my choice" in the app
Then I should find "Are you sure" in the app
When I press "OK" in the app
Then I should find "This Choice has offline data to be synchronised." in the app
But I should not find "Option 1: 0" in the app
And I should not find "Option 2: 1" in the app
And I should not find "Option 3: 0" in the app
When I switch offline mode to "false"
And I run cron tasks in the app
And I wait loading to finish in the app
Then I should find "Option 1: 0" in the app
And I should find "Option 2: 1" in the app
And I should find "Option 3: 0" in the app
But I should not find "This Choice has offline data to be synchronised." in the app
Scenario: Prefetch
Given the following "activities" exist:
| activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults |
| choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 |
| choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 |
When I enter the course "Course 1" as "student1" in the app
And I press "Course downloads" in the app
And I press "Download" within "Test single choice name" "ion-item" in the app
Then I should find "Downloaded" within "Test single choice name" "ion-item" in the app
And I press the back button in the app
When I switch offline mode to "true"
And I press "Test multi choice name" in the app
Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app
When I press "OK" in the app
And I press the back button in the app
And I press "Test single choice name" in the app
And I select "Option 2" in the app
And I press "Save my choice" in the app
Then I should find "Are you sure" in the app
When I press "OK" in the app
And I press the back button in the app
And I press "Test single choice name" in the app
Then I should find "This Choice has offline data to be synchronised." in the app
But I should not find "Option 1: 0" in the app
And I should not find "Option 2: 1" in the app
And I should not find "Option 3: 0" in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "Test single choice name" in the app
Then I should find "Option 1: 0" in the app
And I should find "Option 2: 1" in the app
And I should find "Option 3: 0" in the app
But I should not find "This Choice has offline data to be synchronised." in the app
# TODO remove LMS UI steps in app tests
Scenario: Download students choice in text format
# Submit answer as student
Given the following "activities" exist:
| activity | name | intro | course | idnumber | option |
| choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 |
And I enter the course "Course 1" as "student1" in the app
And I press "Choice name" in the app
And I select "Option 2" in the app
And I press "Save my choice" in the app
And I press "OK" in the app
# Download answers as teacher
When I enter the course "Course 1" as "teacher1" in the app
And I press "Choice name" in the app
Then I should find "Test choice description" in the app
When I press "Information" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I follow "Responses"
And I press "Download in text format"
# TODO Then I should find "..." in the downloads folder

View File

@ -0,0 +1,340 @@
@mod @mod_comments @app @app_upto3.9.4 @javascript
Feature: Test basic usage of comments in app
In order to participate in the comments while using the mobile app
As a student
I need basic comments functionality to work
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | teacher | teacher1@example.com |
| student1 | Student | student | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale |
| glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | comments |
| data | Data | Data info | C1 | data1 | 1 |
@app @3.8.0
Scenario: Add comments & Delete comments (database)
# Create database entry and comment as a teacher
Given I enter the course "Course 1" as "teacher1" in the app
And I press "Data" in the app
And I press "Display options" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I add a "Text input" field to "Data" database and I fill the form with:
| Field name | Test field name |
| Field description | Test field description |
And I press "Save"
And I close the browser tab opened by the app
When I enter the course "Course 1" as "teacher1" in the app
And I press "Data" in the app
And I press "add" in the app
And I set the field "Test field name" to "Test" in the app
And I press "Save" in the app
And I press "More" in the app
And I press "Comments (0)" in the app
And I press "close" in the app
And I set the field "Add a comment..." to "comment test teacher" in the app
And I press "Save comment" in the app
Then I should see "Comment created"
And I should see "comment test teacher"
When I press the back button in the app
And I should see "Comments (1)"
# Create and delete comments as a student
When I enter the course "Course 1" as "student1" in the app
And I press "Data" in the app
And I press "More" in the app
And I press "Comments (1)" in the app
And I press "close" in the app
And I set the field "Add a comment..." to "comment test student" in the app
And I press "Save comment" in the app
Then I should see "Comment created"
And I should see "comment test teacher"
And I should see "comment test student"
When I press the back button in the app
And I press "Comments (2)" in the app
And I press "Delete" in the app
And I press "trash" in the app
And I press "Delete" near "Cancel" in the app
Then I should see "Comment deleted"
And I should see "comment test teacher"
But I should not see "comment test student"
When I press the back button in the app
Then I should see "Comments (1)"
@app @3.8.0
Scenario: Add comments offline & Delete comments offline & Sync comments (database)
Given I enter the course "Course 1" as "teacher1" in the app
And I press "Data" in the app
And I press "Display options" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I add a "Text input" field to "Data" database and I fill the form with:
| Field name | Test field name |
| Field description | Test field description |
And I press "Save"
And I close the browser tab opened by the app
When I enter the course "Course 1" as "teacher1" in the app
And I press "Data" in the app
And I press "add" in the app
And I set the field "Test field name" to "Test" in the app
And I press "Save" in the app
And I press "More" in the app
And I press "Comments (0)" in the app
And I switch offline mode to "true"
And I press "close" in the app
And I set the field "Add a comment..." to "comment test" in the app
And I press "Save comment" in the app
Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later."
And I should see "There are offline comments to be synchronised."
And I should see "comment test"
When I press the back button in the app
And I press "Comments (0)" in the app
And I switch offline mode to "false"
And I press "Display options" in the app
And I press "Synchronise now" in the app
Then I should see "comment test"
But I should not see "There are offline comments to be synchronised."
When I press the back button in the app
And I press "Comments (1)" in the app
And I switch offline mode to "true"
And I press "Delete" in the app
And I press "trash" in the app
And I press "Delete" near "Cancel" in the app
Then I should see "Comment deleted"
And I should see "There are offline comments to be synchronised."
And I should see "Deleted offline"
And I should see "comment test"
When I press the back button in the app
And I press "Comments (1)" in the app
And I switch offline mode to "false"
And I press "Display options" in the app
And I press "Synchronise now" in the app
Then I should not see "There are offline comments to be synchronised."
And I should not see "comment test"
When I press the back button in the app
And I should see "Comments (0)"
@app @3.8.0
Scenario: Add comments & delete comments (glossary)
# Create glossary entry and comment as a teacher
When I enter the course "Course 1" as "teacher1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "potato" in the app
And I press "Comments (0)" in the app
And I press "close" in the app
And I set the field "Add a comment..." to "comment test teacher" in the app
And I press "Save comment" in the app
Then I should see "Comment created"
And I should see "comment test teacher"
And I press the back button in the app
And I should see "Comments (1)"
# Create and delete comments as a student
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "potato" in the app
And I press "Comments (1)" in the app
And I press "close" in the app
And I set the field "Add a comment..." to "comment test student" in the app
And I press "Save comment" in the app
Then I should see "Comment created"
And I should see "comment test teacher"
And I should see "comment test student"
When I press the back button in the app
And I press "Comments (2)" in the app
And I press "Delete" in the app
And I press "trash" in the app
And I press "Delete" near "Cancel" in the app
Then I should see "Comment deleted"
And I should see "comment test teacher"
But I should not see "comment test student"
When I press the back button in the app
And I should see "Comments (1)"
@app @3.8.0
Scenario: Add comments offline & Delete comments offline & Sync comments (glossary)
When I enter the course "Course 1" as "teacher1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "potato" in the app
And I press "Comments (0)" in the app
And I switch offline mode to "true"
And I press "close" in the app
And I set the field "Add a comment..." to "comment test" in the app
And I press "Save comment" in the app
Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later."
And I should see "There are offline comments to be synchronised."
And I should see "comment test"
When I press the back button in the app
And I press "Comments (0)" in the app
And I switch offline mode to "false"
And I press "Display options" in the app
And I press "Synchronise now" in the app
Then I should see "comment test"
But I should not see "There are offline comments to be synchronised."
When I press the back button in the app
And I press "Comments (1)" in the app
And I switch offline mode to "true"
And I press "Delete" in the app
And I press "trash" in the app
And I press "Delete" near "Cancel" in the app
Then I should see "Comment deleted"
And I should see "There are offline comments to be synchronised."
And I should see "Deleted offline"
And I should see "comment test"
When I press the back button in the app
And I press "Comments (1)" in the app
And I switch offline mode to "false"
And I press "Display options" in the app
And I press "Synchronise now" in the app
Then I should not see "There are offline comments to be synchronised."
And I should not see "comment test"
When I press the back button in the app
And I should see "Comments (0)"
@app @3.8.0
Scenario: Add comments & Delete comments (blogs)
# Create blog as a teacher
Given I enter the course "Course 1" as "teacher1" in the app
And I press "menu" in the app
And I press "Website" in the app
And I switch to the browser tab opened by the app
And I follow "Log in"
And I log in as "teacher1"
And I click on "Side panel" "button"
And I follow "C1"
And I press "Turn editing on"
And I click on "Side panel" "button"
And I follow "Add a block"
And I follow "Blog menu"
And I follow "Add an entry about this course"
And I set the field "Entry title" to "Blog test"
And I set the field "Blog entry body" to "Blog body"
And I press "Save changes"
And I close the browser tab opened by the app
# Create and delete comments as a student
When I enter the course "Course 1" as "student1" in the app
And I press "menu" in the app
And I press "Site blog" in the app
Then I should see "Blog test"
And I should see "Blog body"
When I press "Comments (0)" in the app
And I press "close" in the app
And I set the field "Add a comment..." to "comment test" in the app
And I press "Save comment" in the app
Then I should see "Comment created"
And I should see "comment test"
When I press the back button in the app
And I press "Comments (1)" in the app
And I press "Delete" in the app
And I press "trash" in the app
And I press "Delete" near "Cancel" in the app
Then I should see "Comment deleted"
But I should not see "comment test"
When I press the back button in the app
Then I should see "Comments (0)"
@app @3.8.0
Scenario: Add comments offline & Delete comments offline & Sync comments (blogs)
# Create blog as a teacher
Given I enter the course "Course 1" as "teacher1" in the app
And I press "menu" in the app
And I press "Website" in the app
And I switch to the browser tab opened by the app
And I follow "Log in"
And I log in as "teacher1"
And I click on "Side panel" "button"
And I follow "C1"
And I press "Turn editing on"
And I click on "Side panel" "button"
And I follow "Add a block"
And I follow "Blog menu"
And I follow "Add an entry about this course"
And I set the field "Entry title" to "Blog test"
And I set the field "Blog entry body" to "Blog body"
And I press "Save changes"
And I close the browser tab opened by the app
# Create and delete comments as a student
When I enter the course "Course 1" as "student1" in the app
And I press "menu" in the app
And I press "Site blog" in the app
Then I should see "Blog test"
And I should see "Blog body"
When I press "Comments (0)" in the app
And I switch offline mode to "true"
And I press "close" in the app
And I set the field "Add a comment..." to "comment test" in the app
And I press "Save comment" in the app
Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later."
And I should see "There are offline comments to be synchronised."
And I should see "comment test"
When I press the back button in the app
And I press "Comments (0)" in the app
And I switch offline mode to "false"
And I press "Display options" in the app
And I press "Synchronise now" in the app
Then I should see "comment test"
But I should not see "There are offline comments to be synchronised."
When I press the back button in the app
And I press "Comments (1)" in the app
And I switch offline mode to "true"
And I press "Delete" in the app
And I press "trash" in the app
And I press "Delete" near "Cancel" in the app
Then I should see "Comment deleted"
And I should see "There are offline comments to be synchronised."
And I should see "Deleted offline"
And I should see "comment test"
When I press the back button in the app
And I press "Comments (1)" in the app
And I switch offline mode to "false"
And I press "Display options" in the app
And I press "Synchronise now" in the app
Then I should not see "There are offline comments to be synchronised."
And I should not see "comment test"
When I press the back button in the app
Then I should see "Comments (0)"

View File

@ -0,0 +1,496 @@
@mod @mod_course @app @javascript
Feature: Test basic usage of one course in app
In order to participate in one course while using the mobile app
As a student
I need basic course functionality to work
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | teacher | teacher1@example.com |
| student1 | Student | student | student1@example.com |
| student2 | Student2 | student2 | student2@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber | option | section |
| choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 1 |
And the following "activities" exist:
| activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | section |
| assign | C1 | assign1 | assignment | Test assignment description | 1 | 1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] |
| forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | section |
| chat | Test chat name | Test chat | C1 | chat | 0 | 2 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | section |
| data | Web links | Useful links | C1 | data1 | 4 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | section |
| lti | Test external name | Test external | C1 | external | 0 | 1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | section |
| feedback | Test feedback name | Test feedback | C1 | feedback | 0 | 3 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | section |
| glossary | Test glossary | glossary description | C1 | gloss1 | 5 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | section |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 2 |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | TF1 | Text of the first question |
| Test questions | truefalse | TF2 | Text of the second question |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
| TF2 | 2 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | section |
| survey | Test survey name | Test survey | C1 | survey | 0 | 1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| wiki | Test wiki name | Test wiki | C1 | wiki | 0 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | section |
| lesson | Test lesson name | Test lesson | C1 | lesson | 0 | 3 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | section |
| scorm | Test scorm name | Test scorm | C1 | scorm | 0 | 2 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | section |
| workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 |
Scenario: View course contents
When I enter the course "Course 1" as "student1" in the app
Then the header should be "Course 1" in the app
And I should find "Choice course 1" in the app
And I should find "assignment" in the app
And I should find "Test forum name" in the app
And I should find "Test chat name" in the app
And I should find "Web links" in the app
And I should find "Test external name" in the app
And I should find "Test feedback name" in the app
And I should find "Test glossary" in the app
And I should find "Quiz 1" in the app
And I should find "Test survey name" in the app
And I should find "Test wiki name" in the app
And I should find "Test lesson name" in the app
And I should find "Test scorm name" in the app
And I should find "Test workshop name" in the app
When I press "Choice course 1" in the app
Then the header should be "Choice course 1" in the app
When I press the back button in the app
And I press "assignment" in the app
Then the header should be "assignment" in the app
When I press the back button in the app
And I press "Test forum name" in the app
Then the header should be "Test forum name" in the app
When I press the back button in the app
And I press "Test chat name" in the app
Then the header should be "Test chat name" in the app
When I press the back button in the app
And I press "Web links" in the app
Then the header should be "Web links" in the app
When I press the back button in the app
And I press "Test external name" in the app
Then the header should be "Test external name" in the app
When I press the back button in the app
And I press "Test feedback name" in the app
And I press "OK" in the app
Then the header should be "Test feedback name" in the app
When I press the back button in the app
And I press "Test glossary" in the app
Then the header should be "Test glossary" in the app
When I press the back button in the app
And I press "Quiz 1" in the app
Then the header should be "Quiz 1" in the app
When I press the back button in the app
And I press "Test survey name" in the app
Then the header should be "Test survey name" in the app
When I press the back button in the app
And I press "Test wiki name" in the app
And I press "OK" in the app
Then the header should be "Test wiki name" in the app
When I press the back button in the app
And I press "Test lesson name" in the app
Then the header should be "Test lesson name" in the app
When I press the back button in the app
And I press "Test scorm name" in the app
Then the header should be "Test scorm name" in the app
When I press the back button in the app
And I press "Test workshop name" in the app
Then the header should be "Test workshop name" in the app
Scenario: View section contents
When I enter the course "Course 1" as "student1" in the app
Then the header should be "Course 1" in the app
And I should find "Choice course 1" in the app
And I should find "assignment" in the app
And I should find "Test forum name" in the app
And I should find "Test chat name" in the app
And I should find "Web links" in the app
And I should find "Test external name" in the app
And I should find "Test feedback name" in the app
And I should find "Test glossary" in the app
And I should find "Quiz 1" in the app
And I should find "Test survey name" in the app
And I should find "Test wiki name" in the app
And I should find "Test lesson name" in the app
And I should find "Test scorm name" in the app
And I should find "Test workshop name" in the app
When I press "Course index" in the app
And I press "General" in the app
Then I should find "Test forum name" in the app
And I should find "Test wiki name" in the app
But I should not find "Choice course 1" in the app
And I should not find "assignment" in the app
And I should not find "Test chat name" in the app
And I should not find "Web links" in the app
And I should not find "Test external name" in the app
And I should not find "Test feedback name" in the app
And I should not find "Test glossary" in the app
And I should not find "Quiz 1" in the app
And I should not find "Test survey name" in the app
And I should not find "Test lesson name" in the app
And I should not find "Test scorm name" in the app
And I should not find "Test workshop name" in the app
When I press "Test forum name" in the app
Then the header should be "Test forum name" in the app
When I press the back button in the app
And I press "Test wiki name" in the app
And I press "OK" in the app
Then the header should be "Test wiki name" in the app
When I press the back button in the app
And I press "Course index" in the app
And I press "Topic 1" in the app
Then I should find "Choice course 1" in the app
And I should find "assignment" in the app
And I should find "Test external name" in the app
And I should find "Test survey name" in the app
But I should not find "Test forum name" in the app
And I should not find "Test chat name" in the app
And I should not find "Web links" in the app
And I should not find "Test feedback name" in the app
And I should not find "Test glossary" in the app
And I should not find "Quiz 1" in the app
And I should not find "Test wiki name" in the app
And I should not find "Test lesson name" in the app
And I should not find "Test scorm name" in the app
And I should not find "Test workshop name" in the app
When I press "Choice course 1" in the app
Then the header should be "Choice course 1" in the app
When I press the back button in the app
And I press "assignment" in the app
Then the header should be "assignment" in the app
When I press the back button in the app
And I press "Test external name" in the app
Then the header should be "Test external name" in the app
When I press the back button in the app
And I press "Test survey name" in the app
Then the header should be "Test survey name" in the app
When I press the back button in the app
And I press "Course index" in the app
And I press "Topic 2" in the app
Then I should find "Quiz 1" in the app
And I should find "Test chat name" in the app
And I should find "Test scorm name" in the app
But I should not find "Choice course 1" in the app
And I should not find "assignment" in the app
And I should not find "Test forum name" in the app
And I should not find "Web links" in the app
And I should not find "Test external name" in the app
And I should not find "Test feedback name" in the app
And I should not find "Test glossary" in the app
And I should not find "Test survey name" in the app
And I should not find "Test wiki name" in the app
And I should not find "Test lesson name" in the app
And I should not find "Test workshop name" in the app
When I press "Test chat name" in the app
Then the header should be "Test chat name" in the app
When I press the back button in the app
And I press "Quiz 1" in the app
Then the header should be "Quiz 1" in the app
When I press the back button in the app
And I press "Test scorm name" in the app
Then the header should be "Test scorm name" in the app
When I press the back button in the app
And I press "Course index" in the app
And I press "Topic 3" in the app
Then I should find "Test feedback name" in the app
And I should find "Test lesson name" in the app
And I should find "Test workshop name" in the app
But I should not find "Choice course 1" in the app
And I should not find "assignment" in the app
And I should not find "Test forum name" in the app
And I should not find "Test chat name" in the app
And I should not find "Web links" in the app
And I should not find "Test external name" in the app
And I should not find "Test glossary" in the app
And I should not find "Quiz 1" in the app
And I should not find "Test survey name" in the app
And I should not find "Test wiki name" in the app
And I should not find "Test scorm name" in the app
When I press "Test feedback name" in the app
And I press "OK" in the app
Then the header should be "Test feedback name" in the app
When I press the back button in the app
And I press "Test lesson name" in the app
Then the header should be "Test lesson name" in the app
When I press the back button in the app
And I press "Test workshop name" in the app
Then the header should be "Test workshop name" in the app
When I press the back button in the app
And I press "Course index" in the app
And I press "Topic 4" in the app
Then I should find "Web links" in the app
But I should not find "Choice course 1" in the app
And I should not find "assignment" in the app
And I should not find "Test forum name" in the app
And I should not find "Test chat name" in the app
And I should not find "Test external name" in the app
And I should not find "Test feedback name" in the app
And I should not find "Test glossary" in the app
And I should not find "Quiz 1" in the app
And I should not find "Test survey name" in the app
And I should not find "Test wiki name" in the app
And I should not find "Test lesson name" in the app
And I should not find "Test scorm name" in the app
And I should not find "Test workshop name" in the app
When I press "Web links" in the app
Then the header should be "Web links" in the app
When I press the back button in the app
And I press "Course index" in the app
And I press "Topic 5" in the app
Then I should find "Test glossary" in the app
But I should not find "Choice course 1" in the app
And I should not find "assignment" in the app
And I should not find "Test forum name" in the app
And I should not find "Test chat name" in the app
And I should not find "Web links" in the app
And I should not find "Test external name" in the app
And I should not find "Test feedback name" in the app
And I should not find "Quiz 1" in the app
And I should not find "Test survey name" in the app
And I should not find "Test wiki name" in the app
And I should not find "Test lesson name" in the app
And I should not find "Test scorm name" in the app
And I should not find "Test workshop name" in the app
When I press "Test glossary" in the app
Then the header should be "Test glossary" in the app
Scenario: Navigation between sections using the bottom arrows
When I enter the course "Course 1" as "student1" in the app
Then the header should be "Course 1" in the app
And I should find "Choice course 1" in the app
And I should find "assignment" in the app
And I should find "Test forum name" in the app
And I should find "Test chat name" in the app
And I should find "Web links" in the app
And I should find "Test external name" in the app
And I should find "Test feedback name" in the app
And I should find "Test glossary" in the app
And I should find "Quiz 1" in the app
And I should find "Test survey name" in the app
And I should find "Test wiki name" in the app
And I should find "Test lesson name" in the app
And I should find "Test scorm name" in the app
And I should find "Test workshop name" in the app
When I press "Course index" in the app
And I press "General" in the app
Then I should find "General" in the app
And I should find "Next: Topic 1" in the app
But I should not find "Topic 2" in the app
And I should not find "Topic 3" in the app
And I should not find "Topic 4" in the app
And I should not find "Topic 5" in the app
And I should not find "Previous:" in the app
When I press "Next:" in the app
Then I should find "Topic 1" in the app
And I should find "Previous: General" in the app
And I should find "Next: Topic 2" in the app
But I should not find "Topic 3" in the app
And I should not find "Topic 4" in the app
And I should not find "Topic 5" in the app
When I press "Next:" in the app
Then I should find "Topic 2" in the app
And I should find "Previous: Topic 1" in the app
And I should find "Next: Topic 3" in the app
But I should not find "General" in the app
And I should not find "Topic 4" in the app
And I should not find "Topic 5" in the app
When I press "Next:" in the app
Then I should find "Topic 3" in the app
And I should find "Previous: Topic 2" in the app
And I should find "Next: Topic 4" in the app
But I should not find "General" in the app
And I should not find "Topic 1" in the app
And I should not find "Topic 5" in the app
When I press "Next:" in the app
Then I should find "Topic 4" in the app
And I should find "Previous: Topic 3" in the app
And I should find "Next: Topic 5" in the app
But I should not find "General" in the app
And I should not find "Topic 1" in the app
And I should not find "Topic 2" in the app
When I press "Next:" in the app
Then I should find "Topic 5" in the app
And I should find "Previous: Topic 4" in the app
But I should not find "General" in the app
And I should not find "Topic 1" in the app
And I should not find "Topic 2" in the app
And I should not find "Topic 3" in the app
And I should not find "Next:" in the app
When I press "Previous:" in the app
Then I should find "Topic 4" in the app
And I should find "Previous: Topic 3" in the app
And I should find "Next: Topic 5" in the app
But I should not find "General" in the app
And I should not find "Topic 1" in the app
And I should not find "Topic 2" in the app
Scenario: Self enrol
Given I enter the course "Course 1" as "teacher1" in the app
And I press "Course summary" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I click on "Participants" "link"
And I select "Enrolment methods" from the "jump" singleselect
And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row"
And I close the browser tab opened by the app
When I enter the app
And I log in as "student2"
And I press "Site home" in the app
And I press "Available courses" in the app
And I press "Course 1" in the app
And I press "Enrol me" in the app
And I press "OK" in the app
And I wait loading to finish in the app
Then the header should be "Course 1" in the app
And I should find "Choice course 1" in the app
And I should find "assignment" in the app
And I should find "Test forum name" in the app
And I should find "Test chat name" in the app
And I should find "Web links" in the app
And I should find "Test external name" in the app
And I should find "Test feedback name" in the app
And I should find "Test glossary" in the app
And I should find "Quiz 1" in the app
And I should find "Test survey name" in the app
And I should find "Test wiki name" in the app
And I should find "Test lesson name" in the app
And I should find "Test scorm name" in the app
And I should find "Test workshop name" in the app
Scenario: Guest access
Given I enter the course "Course 1" as "teacher1" in the app
And I press "Course summary" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I click on "Participants" "link"
And I select "Enrolment methods" from the "jump" singleselect
And I click on "Enable" "icon" in the "Guest access" "table_row"
And I close the browser tab opened by the app
When I enter the app
And I log in as "student2"
And I press "Site home" in the app
And I press "Available courses" in the app
And I press "Course 1" in the app
Then I should find "Course summary" in the app
And I should find "Course" in the app
When I press "View course" "ion-button" in the app
Then the header should be "Course 1" in the app
And I should find "Choice course 1" in the app
And I should find "assignment" in the app
And I should find "Test forum name" in the app
And I should find "Test chat name" in the app
And I should find "Web links" in the app
And I should find "Test feedback name" in the app
And I should find "Test glossary" in the app
And I should find "Quiz 1" in the app
And I should find "Test survey name" in the app
And I should find "Test wiki name" in the app
And I should find "Test lesson name" in the app
And I should find "Test scorm name" in the app
And I should find "Test workshop name" in the app
Scenario: View blocks on drawer
Given the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion | configdata |
| html | Course | C1 | course-view-* | site-pre | Tzo4OiJzdGRDbGFzcyI6Mjp7czo1OiJ0aXRsZSI7czoxNToiSFRNTCB0aXRsZSB0ZXN0IjtzOjQ6InRleHQiO3M6OToiYm9keSB0ZXN0Ijt9 |
| activity_modules | Course | C1 | course-view-* | site-pre | |
When I enter the course "Course 1" as "student1" in the app
Then the header should be "Course 1" in the app
And I should find "Choice course 1" in the app
And I should find "assignment" in the app
And I should find "Test forum name" in the app
And I should find "Test chat name" in the app
And I should find "Web links" in the app
And I should find "Test external name" in the app
And I should find "Test feedback name" in the app
And I should find "Test glossary" in the app
And I should find "Quiz 1" in the app
And I should find "Test survey name" in the app
And I should find "Test wiki name" in the app
And I should find "Test lesson name" in the app
And I should find "Test scorm name" in the app
And I should find "Test workshop name" in the app
Then I press "Open block drawer" in the app
And I should find "HTML title test" in the app
And I should find "body test" in the app
And I should find "Activities" in the app

View File

@ -0,0 +1,34 @@
@core @core_course @app @javascript
Feature: Check course completion feature.
In order to track the progress of the course on mobile device
As a student
I need to be able to update the activity completion status.
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category | enablecompletion |
| Course 1 | C1 | 0 | 1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
Scenario: Activity completion, marking the checkbox manually
Given the following "activities" exist:
| activity | name | course | idnumber | completion | completionview |
| forum | First forum | C1 | forum1 | 1 | 0 |
| forum | Second forum | C1 | forum2 | 1 | 0 |
When I enter the course "Course 1" as "student1" in the app
# Set activities as completed.
And I should find "0%" in the app
And I press "Mark First forum as done" in the app
And I should find "50%" in the app
And I press "Mark Second forum as done" in the app
And I should find "100%" in the app
# Set activities as not completed.
And I press "First forum is marked as done. Press to undo." in the app
And I should find "50%" in the app
And I press "Second forum is marked as done. Press to undo." in the app
And I should find "0%" in the app

View File

@ -0,0 +1,124 @@
@core @core_course @app @javascript
Feature: Test course list shown on app start tab
In order to select a course
As a student
I need to see the correct list of courses
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
| Course 2 | C2 |
And the following "users" exist:
| username |
| student1 |
| student2 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
| student2 | C2 | student |
Scenario: View courses (shortnames not displayed)
When I enter the app
And I log in as "student1"
And I press "My courses" in the app
Then I should find "Course 1" in the app
But I should not find "Course 2" in the app
But I should not find "C1" in the app
But I should not find "C2" in the app
When I enter the app
And I log in as "student2"
And I press "My courses" in the app
Then I should find "Course 1" in the app
And I should find "Course 2" in the app
But I should not find "C1" in the app
But I should not find "C2" in the app
Scenario: Filter courses
Given the following config values are set as admin:
| courselistshortnames | 1 |
And the following "courses" exist:
| fullname | shortname |
| Frog 3 | C3 |
| Frog 4 | C4 |
| Course 5 | C5 |
| Toad 6 | C6 |
And the following "course enrolments" exist:
| user | course | role |
| student2 | C3 | student |
| student2 | C4 | student |
| student2 | C5 | student |
| student2 | C6 | student |
# Create bogus courses so that the main ones aren't shown in the 'recently accessed' part.
# Because these come later in alphabetical order, they may not be displayed in the lower part
# which is OK.
And the following "courses" exist:
| fullname | shortname |
| Zogus 1 | Z1 |
| Zogus 2 | Z2 |
| Zogus 3 | Z3 |
| Zogus 4 | Z4 |
| Zogus 5 | Z5 |
| Zogus 6 | Z6 |
| Zogus 7 | Z7 |
| Zogus 8 | Z8 |
| Zogus 9 | Z9 |
| Zogus 10 | Z10 |
And the following "course enrolments" exist:
| user | course | role |
| student2 | Z1 | student |
| student2 | Z2 | student |
| student2 | Z3 | student |
| student2 | Z4 | student |
| student2 | Z5 | student |
| student2 | Z6 | student |
| student2 | Z7 | student |
| student2 | Z8 | student |
| student2 | Z9 | student |
| student2 | Z10 | student |
When I enter the app
And I log in as "student2"
And I press "My courses" in the app
Then I should find "C1" in the app
And I should find "C2" in the app
And I should find "C3" in the app
And I should find "C4" in the app
And I should find "C5" in the app
And I should find "C6" in the app
And I should find "Course 1" in the app
And I should find "Course 2" in the app
And I should find "Frog 3" in the app
And I should find "Frog 4" in the app
And I should find "Course 5" in the app
And I should find "Toad 6" in the app
And I set the field "search text" to "fr" in the app
Then I should find "C3" in the app
And I should find "C4" in the app
And I should find "Frog 3" in the app
And I should find "Frog 4" in the app
But I should not find "C1" in the app
And I should not find "C2" in the app
And I should not find "C5" in the app
And I should not find "C6" in the app
And I should not find "Course 1" in the app
And I should not find "Course 2" in the app
And I should not find "Course 5" in the app
And I should not find "Toad 6" in the app
When I set the field "search text" to "" in the app
Then I should find "C1" in the app
And I should find "C2" in the app
And I should find "C3" in the app
And I should find "C4" in the app
And I should find "C5" in the app
And I should find "C6" in the app
And I should find "Course 1" in the app
And I should find "Course 2" in the app
And I should find "Frog 3" in the app
And I should find "Frog 4" in the app
And I should find "Course 5" in the app
And I should find "Toad 6" in the app

View File

@ -0,0 +1,146 @@
@mod @mod_courses @app @javascript
Feature: Test basic usage of courses in app
In order to participate in the courses while using the mobile app
As a student
I need basic courses functionality to work
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | teacher | teacher1@example.com |
| student1 | Student | student | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
| Course 2 | C2 | 0 |
| Course 3 | C3 | 0 |
| Course 4 | C4 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher1 | C2 | editingteacher |
| teacher1 | C3 | editingteacher |
| teacher1 | C4 | editingteacher |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber | option |
| choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 |
| choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 |
| choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 |
| choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 |
And the following "activities" exist:
| activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled |
| assign | C1 | assign1 | assignment | Test assignment description | 1 |
Scenario: "Dashboard" tab displayed
When I enter the app
And I log in as "student1"
Then I should see "Dashboard"
And the header should be "Acceptance test site" in the app
And I should see "Timeline"
And I press "Site home" in the app
Then I should find "Dashboard" in the app
And the header should be "Acceptance test site" in the app
When I press "My courses" in the app
Then I should find "Course 1" in the app
And I should find "Course 2" in the app
And I should find "Course 3" in the app
Scenario: See my courses
When I enter the app
And I log in as "student1"
Then the header should be "Acceptance test site" in the app
And I press "My courses" in the app
And I should find "Course 1" in the app
And I should find "Course 2" in the app
And I should find "Course 3" in the app
When I press "Course 1" in the app
Then I should find "Choice course 1" in the app
And the header should be "Course 1" in the app
When I press "Choice course 1" in the app
Then I should find "Test choice description" in the app
And the header should be "Choice course 1" in the app
When I press the back button in the app
And I press the back button in the app
And I press "Course 2" in the app
Then I should find "Choice course 2" in the app
And the header should be "Course 2" in the app
When I press the back button in the app
And I press "Course 3" in the app
Then I should find "Choice course 3" in the app
And the header should be "Course 3" in the app
Scenario: Search for a course
When I enter the app
And I log in as "student1"
And I press "Search courses" in the app
And I set the field "Search" to "Course 4" in the app
And I press "Search" "button" in the app
Then I should find "Course 4" in the app
And the header should be "Available courses" in the app
When I press "Course 4" in the app
Then I should find "Course 4" in the app
And I should find "Course summary" in the app
When I press the back button in the app
And I set the field "Search" to "Course" in the app
And I press "Search" "button" in the app
Then I should find "Course 1" in the app
And I should find "Course 2" in the app
And I should find "Course 3" in the app
And I should find "Course 4" in the app
# TODO remove LMS UI steps in app tests
Scenario: Links to actions in Timeline work for teachers/students
# Configure assignment as teacher
When I enter the course "Course 1" as "teacher1" in the app
And I press "assignment" in the app
And I press "Information" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I navigate to "Settings" in current page administration
And I click on "Expand all" "link"
And I click on "duedate[enabled]" "checkbox"
And I click on "gradingduedate[enabled]" "checkbox"
And I press "Save and return to course"
And I close the browser tab opened by the app
# Submit assignment as student
When I enter the app
And I log in as "student1"
And I press "Add submission" in the app
Then the header should be "assignment" in the app
And I should find "Test assignment description" in the app
And I should find "No attempt" in the app
And I should find "Due:" in the app
When I press "Add submission" in the app
And I set the field "Online text submissions" to "test" in the app
And I press "Save" in the app
And I press "Submit assignment" in the app
And I press "OK" in the app
Then the header should be "assignment" in the app
And I should find "Test assignment description" in the app
And I should find "Submitted for grading" in the app
And I should find "Due:" in the app
# Grade assignment as teacher
When I enter the app
And I log in as "teacher1"
And I press "Grade" in the app
Then the header should be "assignment" in the app
And I should find "Test assignment description" in the app
And I should find "Time remaining" in the app
When I press "Needs grading" in the app
Then I should find "Student student" in the app
And I should find "Not graded" in the app

View File

@ -0,0 +1,183 @@
@mod @mod_data @app @app_upto3.9.4 @javascript
Feature: Users can manage entries in database activities
In order to populate databases
As a user
I need to add and manage entries to databases
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| data | Web links | Useful links | C1 | data1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I add a "Text input" field to "Web links" database and I fill the form with:
| Field name | URL |
| Field description | URL link |
And I add a "Text input" field to "Web links" database and I fill the form with:
| Field name | Description |
| Field description | Link description |
And I log out
Scenario: Create entry
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I should see "No entries in database"
When I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
Then I should see "https://moodle.org/"
And I should see "Moodle community site"
Scenario: Browse entry
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
When I enter the course "Course 1" as "student2" in the app
And I press "Web links" near "General" in the app
And I press "Add entries" in the app
And I set the field "URL" to "https://moodlecloud.com/" in the app
And I set the field "Description" to "Moodle Cloud" in the app
And I press "Save" near "Web links" in the app
And I press "More" near "Moodle community site" in the app
Then I should see "Moodle community site"
And I should not see "Next"
And I should see "Previous"
And I press "Previous" in the app
And I should see "Moodle Cloud"
And I should see "Next"
And I should not see "Previous"
And I press "Next" in the app
And I should see "Moodle community site"
And I should not see "Moodle Cloud"
And I press "back" near "Web links" in the app
And I should see "Moodle community site"
And I should see "Moodle Cloud"
Scenario: Students can not edit or delete other user's entries from list and single view in the app
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
When I enter the course "Course 1" as "student2" in the app
And I press "Web links" near "General" in the app
Then "Edit" "link" should not exist
And "Delete" "link" should not exist
And I press "More" in the app
And "Edit" "link" should not exist
And "Delete" "link" should not exist
Scenario: Delete entry (student) & Update entry (student)
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
When I press "Edit" in the app
And I set the field "URL" to "https://moodlecloud.com/" in the app
And I set the field "Description" to "Moodle Cloud" in the app
And I press "Save" near "Web links" in the app
Then I should not see "https://moodle.org/"
And I should not see "Moodle community site"
And I should see "https://moodlecloud.com/"
And I should see "Moodle Cloud"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Cancel" in the app
And I should see "Moodle Cloud"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Delete" in the app
And I should not see "Moodle Cloud"
And I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
And I press "More" in the app
And I press "Edit" in the app
And I set the field "URL" to "https://moodlecloud.com/" in the app
And I set the field "Description" to "Moodle Cloud" in the app
And I press "Save" near "Web links" in the app
And I should not see "https://moodle.org/"
And I should not see "Moodle community site"
And I should see "https://moodlecloud.com/"
And I should see "Moodle Cloud"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Cancel" in the app
And I should see "Moodle Cloud"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Delete" in the app
And I should not see "Moodle Cloud"
And I should see "No entries in database"
Scenario: Delete entry (teacher) & Update entry (teacher)
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
And I press "Add entries" in the app
And I set the field "URL" to "https://telegram.org/" in the app
And I set the field "Description" to "Telegram" in the app
And I press "Save" near "Web links" in the app
When I enter the course "Course 1" as "teacher1" in the app
And I press "Web links" near "General" in the app
Then I should see "https://moodle.org/"
And I should see "Moodle community site"
And I press "Edit" near "Moodle community site" in the app
And I set the field "URL" to "https://moodlecloud.com/" in the app
And I set the field "Description" to "Moodle Cloud" in the app
And I press "Save" near "Web links" in the app
And I should not see "https://moodle.org/"
And I should not see "Moodle community site"
And I should see "https://moodlecloud.com/"
And I should see "Moodle Cloud"
And I press "Delete" near "Moodle Cloud" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Cancel" in the app
And I should see "Moodle Cloud"
And I press "Delete" near "Moodle Cloud" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Delete" in the app
And I should not see "Moodle Cloud"
And I press "More" in the app
And I should see "https://telegram.org/"
And I should see "Telegram"
And I press "Edit" in the app
And I set the field "URL" to "https://moodlecloud.com/" in the app
And I set the field "Description" to "Moodle Cloud" in the app
And I press "Save" near "Web links" in the app
And I should not see "https://telegram.org/"
And I should not see "Telegram"
And I should see "https://moodlecloud.com/"
And I should see "Moodle Cloud"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Cancel" in the app
And I should see "Moodle Cloud"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Delete" in the app
And I should not see "Moodle Cloud"

View File

@ -0,0 +1,130 @@
@mod @mod_data @app @app_upto3.9.4 @javascript
Feature: Users can store entries in database activities when offline and sync when online
In order to populate databases while offline
As a user
I need to add and manage entries to databases and sync then when online
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| data | Web links | Useful links | C1 | data1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I add a "Text input" field to "Web links" database and I fill the form with:
| Field name | URL |
| Field description | URL link |
And I add a "Text input" field to "Web links" database and I fill the form with:
| Field name | Description |
| Field description | Link description |
And I log out
@app_from3.7
Scenario: Create entry (offline)
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I switch offline mode to "true"
And I should see "No entries in database"
When I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
Then I should see "https://moodle.org/"
And I should see "Moodle community site"
And I should see "This Database has offline data to be synchronised"
And I press "back" near "Web links" in the app
And I switch offline mode to "false"
And I press "Web links" near "General" in the app
And I should see "https://moodle.org/"
And I should see "Moodle community site"
And I should not see "This Database has offline data to be synchronised"
@app_from3.7
Scenario: Update entry (offline) & Delete entry (offline)
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I should see "No entries in database"
And I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
And I should see "https://moodle.org/"
And I should see "Moodle community site"
And I press "Display options" in the app
And I press "Download" in the app
And I wait until the page is ready
And I switch offline mode to "true"
When I press "Edit" in the app
And I set the field "URL" to "https://moodlecloud.com/" in the app
And I set the field "Description" to "Moodle Cloud" in the app
And I press "Save" near "Web links" in the app
Then I should not see "https://moodle.org/"
And I should not see "Moodle community site"
And I should see "https://moodlecloud.com/"
And I should see "Moodle Cloud"
And I should see "This Database has offline data to be synchronised"
And I press "back" near "Web links" in the app
And I switch offline mode to "false"
And I press "Web links" near "General" in the app
And I should not see "https://moodle.org/"
And I should not see "Moodle community site"
And I should see "https://moodlecloud.com/"
And I should see "Moodle Cloud"
And I should not see "This Database has offline data to be synchronised"
And I press "Display options" in the app
And I press "Refresh" in the app
And I wait until the page is ready
And I switch offline mode to "true"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Delete" in the app
And I should see "https://moodlecloud.com/"
And I should see "Moodle Cloud"
And I should see "This Database has offline data to be synchronised"
And I press "back" near "Web links" in the app
And I switch offline mode to "false"
And I press "Web links" near "General" in the app
And I should not see "https://moodlecloud.com/"
And I should not see "Moodle Cloud"
And I should not see "This Database has offline data to be synchronised"
@app_from3.7
Scenario: Students can undo deleting entries to a database in the app while offline
Given I enter the course "Course 1" as "student1" in the app
And I press "Web links" near "General" in the app
And I should see "No entries in database"
And I press "Add entries" in the app
And I set the field "URL" to "https://moodle.org/" in the app
And I set the field "Description" to "Moodle community site" in the app
And I press "Save" near "Web links" in the app
And I should see "https://moodle.org/"
And I should see "Moodle community site"
And I press "Display options" in the app
And I press "Download" in the app
And I wait until the page is ready
When I switch offline mode to "true"
And I press "Delete" in the app
And I should see "Are you sure you want to delete this entry?"
And I press "Delete" in the app
And I should see "https://moodle.org/"
And I should see "Moodle community site"
And I should see "This Database has offline data to be synchronised"
And I press "Restore" in the app
And I press "back" near "Web links" in the app
And I switch offline mode to "false"
And I press "Web links" near "General" in the app
Then I should see "https://moodle.org/"
And I should see "Moodle community site"
And I should not see "This Database has offline data to be synchronised"

View File

@ -0,0 +1,393 @@
@mod @mod_forum @app @javascript
Feature: Test basic usage of forum activity in app
In order to participate in the forum while using the mobile app
As a student
I need basic forum functionality to work
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username |
| student1 |
| student2 |
| teacher1 |
| teacher2 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | editingteacher |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode | assessed | scale |
| forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 |
Scenario: Create new discussion
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "My happy subject" in the app
And I set the field "Message" to "An awesome message" in the app
And I press "Post to forum" in the app
Then I should find "My happy subject" in the app
When I press "My happy subject" in the app
Then I should find "An awesome message" in the app
Scenario: Reply a post
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "DiscussionSubject" in the app
And I set the field "Message" to "DiscussionMessage" in the app
And I press "Post to forum" in the app
And I press "DiscussionSubject" in the app
Then I should find "Reply" in the app
When I press "Reply" in the app
And I set the field "Message" to "ReplyMessage" in the app
And I press "Post to forum" in the app
Then I should find "DiscussionMessage" in the app
And I should find "ReplyMessage" in the app
Scenario: Star and pin discussions (student)
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "starred subject" in the app
And I set the field "Message" to "starred message" in the app
And I press "Post to forum" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "normal subject" in the app
And I set the field "Message" to "normal message" in the app
And I press "Post to forum" in the app
And I press "starred subject" in the app
Then I should find "starred message" in the app
When I press the back button in the app
And I press "Display options" near "starred subject" in the app
And I press "Star this discussion" in the app
And I press "starred subject" in the app
Then I should find "starred message" in the app
When I press the back button in the app
And I press "normal subject" in the app
Then I should find "normal message" in the app
When I press the back button in the app
And I press "Display options" near "starred subject" in the app
And I press "Unstar this discussion" in the app
And I press "starred subject" in the app
Then I should find "starred message" in the app
When I press the back button in the app
And I press "normal subject" in the app
Then I should find "normal message" in the app
Scenario: Star and pin discussions (teacher)
When I enter the course "Course 1" as "teacher1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test star" in the app
And I set the field "Message" to "Auto-test star message" in the app
And I press "Post to forum" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test pin" in the app
And I set the field "Message" to "Auto-test pin message" in the app
And I press "Post to forum" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test plain" in the app
And I set the field "Message" to "Auto-test plain message" in the app
And I press "Post to forum" in the app
And I press "Display options" near "Auto-test star" in the app
And I press "Star this discussion" in the app
And I press "Display options" near "Auto-test pin" in the app
And I press "Pin this discussion" in the app
Then I should find "Auto-test pin" in the app
And I should find "Auto-test star" in the app
And I should find "Auto-test plain" in the app
When I press "Display options" near "Auto-test pin" in the app
And I press "Unpin this discussion" in the app
And I press "Display options" near "Auto-test star" in the app
And I press "Unstar this discussion" in the app
Then I should find "Auto-test star" in the app
And I should find "Auto-test pin" in the app
Scenario: Edit a not sent reply offline
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test" in the app
And I set the field "Message" to "Auto-test message" in the app
And I press "Post to forum" in the app
And I press "Auto-test" near "Sort by last post creation date in descending order" in the app
And I should find "Reply" in the app
When I press the back button in the app
And I switch offline mode to "true"
And I press "Auto-test" near "Sort by last post creation date in descending order" in the app
Then I should find "Reply" in the app
When I press "Reply" in the app
And I set the field "Message" to "not sent reply" in the app
And I press "Post to forum" in the app
And I press "Display options" within "not sent reply" "ion-card" in the app
Then I should find "Edit" in the app
When I press "Edit" in the app
And I set the field "Message" to "not sent reply edited" in the app
And I press "Save changes" in the app
Then I should find "Not sent" in the app
And I should find "This Discussion has offline data to be synchronised" in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "Auto-test" near "Sort by last post creation date in descending order" in the app
Then I should not find "Not sent" in the app
And I should not find "This Discussion has offline data to be synchronised" in the app
Scenario: Edit a not sent new discussion offline
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I switch offline mode to "true"
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test" in the app
And I set the field "Message" to "Auto-test message" in the app
And I press "Post to forum" in the app
And I press "Auto-test" in the app
And I set the field "Message" to "Auto-test message edited" in the app
And I press "Post to forum" in the app
Then I should find "This Forum has offline data to be synchronised." in the app
When I switch offline mode to "false"
And I press "Auto-test" in the app
Then I should find "Post to forum" in the app
When I press "Post to forum" in the app
Then I should not find "This Forum has offline data to be synchronised." in the app
When I press "Auto-test" near "Sort by last post creation date in descending order" in the app
And I should find "Auto-test message edited" in the app
Scenario: Edit a forum post (only online)
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test" in the app
And I set the field "Message" to "Auto-test message" in the app
And I press "Post to forum" in the app
Then I should find "Auto-test" in the app
When I press the back button in the app
And I press "Course downloads" in the app
And I press "Download" within "Test forum name" "ion-item" in the app
And I press the back button in the app
And I press "Test forum name" in the app
And I press "Auto-test" near "Sort by last post creation date in descending order" in the app
Then I should find "Reply" in the app
When I press "Display options" near "Reply" in the app
Then I should find "Edit" in the app
When I press "Edit" in the app
And I switch offline mode to "true"
And I set the field "Message" to "Auto-test message edited" in the app
And I press "Save changes" in the app
Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app
Scenario: Delete a forum post (only online)
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test" in the app
And I set the field "Message" to "Auto-test message" in the app
And I press "Post to forum" in the app
Then I should find "Auto-test" in the app
When I press the back button in the app
And I press "Course downloads" in the app
And I press "Download" within "Test forum name" "ion-item" in the app
And I press the back button in the app
And I press "Test forum name" in the app
And I press "Auto-test" near "Sort by last post creation date in descending order" in the app
Then I should find "Reply" in the app
When I press "Display options" near "Reply" in the app
Then I should find "Delete" in the app
When I press "Delete" in the app
And I press "Cancel" in the app
And I switch offline mode to "true"
And I press "Display options" near "Reply" in the app
Then I should not find "Delete" in the app
When I close the popup in the app
And I switch offline mode to "false"
And I press "Display options" near "Reply" in the app
And I press "Delete" in the app
And I press "Delete" in the app
Then I should not find "Auto-test" in the app
Scenario: Add/view ratings
Given I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Auto-test" in the app
And I set the field "Message" to "Auto-test message" in the app
And I press "Post to forum" in the app
And I press "Auto-test" in the app
Then I should find "Reply" in the app
When I press "Reply" in the app
And I set the field "Message" to "test2" in the app
And I press "Post to forum" in the app
Then I should find "test2" "ion-card" in the app
When I enter the course "Course 1" as "teacher1" in the app
And I press "Test forum name" in the app
And I press "Auto-test" in the app
Then I should find "Reply" in the app
When I press "None" near "Auto-test message" in the app
And I press "1" near "Cancel" in the app
And I switch offline mode to "true"
And I press "None" near "test2" in the app
And I press "0" near "Cancel" in the app
Then I should find "Data stored in the device because it couldn't be sent. It will be sent automatically later." inside the toast in the app
And I should find "Average of ratings: -" in the app
And I should find "Average of ratings: 1" in the app
When I switch offline mode to "false"
And I press the back button in the app
Then I should find "This Forum has offline data to be synchronised." in the app
When I press "Information" in the app
And I press "Synchronise now" in the app
Then I should not find "This Forum has offline data to be synchronised." in the app
When I press "Auto-test" in the app
Then I should find "Average of ratings: 1" in the app
And I should find "Average of ratings: 0" in the app
But I should not find "Average of ratings: -" in the app
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Auto-test" in the app
Then I should find "Average of ratings: 1" in the app
And I should find "Average of ratings: 0" in the app
But I should not find "Average of ratings: -" in the app
Scenario: Reply a post offline
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "DiscussionSubject" in the app
And I set the field "Message" to "DiscussionMessage" in the app
And I press "Post to forum" in the app
And I press the back button in the app
And I press "Course downloads" in the app
And I press "Download" within "Test forum name" "ion-item" in the app
And I press the back button in the app
And I press "Test forum name" in the app
And I press "DiscussionSubject" in the app
And I switch offline mode to "true"
Then I should find "Reply" in the app
When I press "Reply" in the app
And I set the field "Message" to "ReplyMessage" in the app
And I press "Post to forum" in the app
Then I should find "DiscussionMessage" in the app
And I should find "ReplyMessage" in the app
And I should find "Not sent" in the app
When I press the back button in the app
And I switch offline mode to "false"
And I press "DiscussionSubject" in the app
Then I should find "DiscussionMessage" in the app
And I should find "ReplyMessage" in the app
But I should not find "Not sent" in the app
Scenario: New discussion offline & Sync Forum
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I switch offline mode to "true"
And I press "Add discussion topic" in the app
And I set the field "Subject" to "DiscussionSubject" in the app
And I set the field "Message" to "DiscussionMessage" in the app
And I press "Post to forum" in the app
Then I should find "DiscussionSubject" in the app
And I should find "Not sent" in the app
And I should find "This Forum has offline data to be synchronised." in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "Test forum name" in the app
And I press "Information" in the app
And I press "Refresh" in the app
And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app
Then I should find "DiscussionSubject" in the app
And I should find "DiscussionMessage" in the app
But I should not find "Not sent" in the app
And I should not find "This Forum has offline data to be synchronised." in the app
Scenario: New discussion offline & Auto-sync forum
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I switch offline mode to "true"
And I press "Add discussion topic" in the app
And I set the field "Subject" to "DiscussionSubject" in the app
And I set the field "Message" to "DiscussionMessage" in the app
And I press "Post to forum" in the app
Then I should find "DiscussionSubject" in the app
And I should find "Not sent" in the app
And I should find "This Forum has offline data to be synchronised." in the app
When I switch offline mode to "false"
And I run cron tasks in the app
And I wait loading to finish in the app
Then I should not find "Not sent" in the app
When I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app
Then I should find "DiscussionSubject" in the app
And I should find "DiscussionMessage" in the app
But I should not find "Not sent" in the app
And I should not find "This Forum has offline data to be synchronised." in the app
Scenario: Prefetch
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "DiscussionSubject 1" in the app
And I set the field "Message" to "DiscussionMessage 1" in the app
And I press "Post to forum" in the app
Then I should find "DiscussionSubject 1" in the app
When I press the back button in the app
And I press "Course downloads" in the app
And I press "Download" within "Test forum name" "ion-item" in the app
Then I should find "Downloaded" within "Test forum name" "ion-item" in the app
And I press the back button in the app
When I press "Test forum name" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "DiscussionSubject 2" in the app
And I set the field "Message" to "DiscussionMessage 2" in the app
And I press "Post to forum" in the app
Then I should find "DiscussionSubject 1" in the app
And I should find "DiscussionSubject 2" in the app
When I press the back button in the app
And I switch offline mode to "true"
And I press "Test forum name" in the app
And I press "DiscussionSubject 2" in the app
Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app
When I press "OK" in the app
And I press the back button in the app
And I press "DiscussionSubject 1" in the app
Then I should find "DiscussionSubject 1" in the app
And I should find "DiscussionMessage 1" in the app
But I should not find "There was a problem connecting to the site. Please check your connection and try again." in the app

View File

@ -0,0 +1,231 @@
@mod @mod_forum @app @javascript
Feature: Test forum navigation
Background:
Given the following "users" exist:
| username | firstname | lastname |
| student1 | First | Student |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | course | idnumber |
| forum | Forum | C1 | forum |
And the following "mod_forum > discussions" exist:
| forum | name | message | timenow |
| forum | Discussion 01 | Discussion 01 message | 1638200100 |
| forum | Discussion 02 | Discussion 02 message | 1638200200 |
| forum | Discussion 03 | Discussion 03 message | 1638200300 |
| forum | Discussion 04 | Discussion 04 message | 1638200400 |
| forum | Discussion 05 | Discussion 05 message | 1638200500 |
| forum | Discussion 06 | Discussion 06 message | 1638200600 |
| forum | Discussion 07 | Discussion 07 message | 1638200700 |
| forum | Discussion 08 | Discussion 08 message | 1638200800 |
| forum | Discussion 09 | Discussion 09 message | 1638200900 |
| forum | Discussion 10 | Discussion 10 message | 1638201000 |
| forum | Discussion 11 | Discussion 11 message | 1638201100 |
| forum | Discussion 12 | Discussion 12 message | 1638201200 |
| forum | Discussion 13 | Discussion 13 message | 1638201300 |
| forum | Discussion 14 | Discussion 14 message | 1638201400 |
| forum | Discussion 15 | Discussion 15 message | 1638201500 |
| forum | Discussion 16 | Discussion 16 message | 1638201600 |
| forum | Discussion 17 | Discussion 17 message | 1638201700 |
| forum | Discussion 18 | Discussion 18 message | 1638201800 |
| forum | Discussion 19 | Discussion 19 message | 1638201900 |
| forum | Discussion 20 | Discussion 20 message | 1638202000 |
And the following "mod_forum > posts" exist:
| discussion | parentsubject | message |
| Discussion 04 | Discussion 04 | Discussion 04 first reply |
| Discussion 05 | Discussion 05 | Discussion 05 first reply |
Scenario: Mobile navigation
Given I enter the course "Course 1" as "student1" in the app
# By last reply
When I press "Forum" in the app
Then I should find "Discussion 05" in the app
And I should find "Discussion 04" in the app
But I should not find "Discussion 12" in the app
# By last reply — Infinite loading
When I load more items in the app
Then I should find "Discussion 12" in the app
And I should find "Discussion 01" in the app
But I should not be able to load more items in the app
# By last reply — Swipe
When I press "Discussion 05" in the app
Then I should find "Discussion 05 first reply" in the app
When I swipe to the right in the app
Then I should find "Discussion 05 first reply" in the app
When I swipe to the left in the app
Then I should find "Discussion 04 first reply" in the app
When I swipe to the left in the app
Then I should find "Discussion 20 message" in the app
# By creation date
When I press the back button in the app
And I scroll to "Discussion 05" in the app
And I press "Sort" in the app
And I press "Sort by creation date in descending order" in the app
Then I should find "Discussion 20" in the app
And I should find "Discussion 19" in the app
But I should not find "Discussion 10" in the app
And I should not find "Discussion 04" in the app
And I should not find "Discussion 05" in the app
# By creation date — Infinite loading
When I load more items in the app
Then I should find "Discussion 10" in the app
And I should find "Discussion 04" in the app
And I should find "Discussion 05" in the app
But I should not be able to load more items in the app
# By creation date — Swipe
When I press "Discussion 20" in the app
Then I should find "Discussion 20 message" in the app
When I swipe to the right in the app
Then I should find "Discussion 20 message" in the app
When I swipe to the left in the app
Then I should find "Discussion 19 message" in the app
When I swipe to the left in the app
Then I should find "Discussion 18 message" in the app
# Offline
When I press the back button in the app
And I press "Add discussion topic" in the app
And I switch offline mode to "true"
And I set the field "Subject" to "Offline discussion 1" in the app
And I set the field "Message" to "Offline discussion 1 message" in the app
And I press "Post to forum" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Offline discussion 2" in the app
And I set the field "Message" to "Offline discussion 2 message" in the app
And I press "Post to forum" in the app
Then I should find "Not sent" in the app
And I should find "Offline discussion 1" in the app
And I should find "Offline discussion 2" in the app
When I press "Offline discussion 2" in the app
And I set the field "Subject" to "Offline discussion 3" in the app
And I set the field "Message" to "Offline discussion 3 message" in the app
And I press "Post to forum" in the app
Then I should find "Not sent" in the app
And I should find "Offline discussion 1" in the app
And I should find "Offline discussion 3" in the app
But I should not find "Offline discussion 2" in the app
# TODO fix flaky test failing on CI but working locally
# # Offline — Swipe
# When I press "Offline discussion 3" in the app
# Then I should find "Offline discussion 3 message" in the app
# When I swipe to the right in the app
# Then I should find "Offline discussion 3 message" in the app
# When I swipe to the left in the app
# Then I should find "Offline discussion 1 message" in the app
# When I swipe to the left in the app
# Then I should find "Discussion 20 message" in the app
Scenario: Tablet navigation
Given I enter the course "Course 1" as "student1" in the app
And I change viewport size to "1200x640"
# By last reply
When I press "Forum" in the app
Then I should find "Discussion 04" in the app
And I should find "Discussion 05" in the app
And "Discussion 05" near "Discussion 04" should be selected in the app
And I should find "Discussion 05 first reply" inside the split-view content in the app
But I should not find "Discussion 12" in the app
# By last reply — Infinite loading
When I load more items in the app
Then I should find "Discussion 12" in the app
And I should find "Discussion 01" in the app
But I should not be able to load more items in the app
# By last reply — Split view
When I press "Discussion 04" in the app
Then "Discussion 04" near "Discussion 05" should be selected in the app
And I should find "Discussion 04 first reply" inside the split-view content in the app
When I press "Discussion 12" in the app
Then "Discussion 12" near "Discussion 11" should be selected in the app
And I should find "Discussion 12 message" inside the split-view content in the app
# By creation date
When I scroll to "Discussion 05" in the app
And I press "Discussion 05" in the app
And I press "Sort" in the app
And I press "Sort by creation date in descending order" in the app
Then I should find "Discussion 20" in the app
And I should find "Discussion 19" in the app
And "Discussion 20" near "Discussion 19" should be selected in the app
And I should find "Discussion 20 message" inside the split-view content in the app
But I should not find "Discussion 10" in the app
And I should not find "Discussion 04" in the app
And I should not find "Discussion 05" in the app
# By creation date — Infinite loading
When I load more items in the app
Then I should find "Discussion 10" in the app
And I should find "Discussion 04" in the app
And I should find "Discussion 05" in the app
But I should not be able to load more items in the app
# By creation date — Split view
When I press "Discussion 19" in the app
Then "Discussion 19" near "Discussion 20" should be selected in the app
And I should find "Discussion 19 message" inside the split-view content in the app
When I press "Discussion 05" in the app
Then "Discussion 05" near "Discussion 04" should be selected in the app
And I should find "Discussion 05 first reply" inside the split-view content in the app
# Offline
When I press "Add discussion topic" in the app
And I switch offline mode to "true"
And I set the field "Subject" to "Offline discussion 1" in the app
And I set the field "Message" to "Offline discussion 1 message" in the app
And I press "Post to forum" in the app
And I press "Add discussion topic" in the app
And I set the field "Subject" to "Offline discussion 2" in the app
And I set the field "Message" to "Offline discussion 2 message" in the app
And I press "Post to forum" in the app
Then I should find "Not sent" in the app
And I should find "Offline discussion 1" in the app
And I should find "Offline discussion 2" in the app
When I press "Offline discussion 2" in the app
And I set the field "Subject" to "Offline discussion 3" in the app
And I set the field "Message" to "Offline discussion 3 message" in the app
And I press "Post to forum" in the app
Then I should find "Not sent" in the app
And I should find "Offline discussion 1" in the app
And I should find "Offline discussion 3" in the app
But I should not find "Offline discussion 2" in the app
# Offline — Split view
When I press "Offline discussion 1" in the app
Then "Offline discussion 1" near "Offline discussion 3" should be selected in the app
And I should find "Offline discussion 1 message" inside the split-view content in the app
When I press "Offline discussion 3" in the app
Then "Offline discussion 3" near "Offline discussion 1" should be selected in the app
And I should find "Offline discussion 3 message" inside the split-view content in the app
When I press "Discussion 20" in the app
Then "Discussion 20" near "Discussion 19" should be selected in the app
And I should find "Discussion 20 message" inside the split-view content in the app

View File

@ -0,0 +1,320 @@
@mod @mod_glossary @app @app_upto3.9.4 @javascript
Feature: Test basic usage of glossary in app
In order to participate in the glossaries while using the mobile app
As a student
I need basic glossary functionality to work
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | teacher | teacher1@example.com |
| teacher2 | Teacher2 | teacher2 | teacher2@example.com |
| student1 | Student | student | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale |
| glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| forum | Test forum name | Test forum | C1 | forum | 0 |
@app @3.8.0
Scenario: View a glossary and its terms
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "car" in the app
And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "mountain" in the app
And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app
And I press "Save" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
When I press "car" in the app
Then I should see "car"
And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods."
@app @3.8.0
Scenario: Change filters (include search)
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "car" in the app
And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "mountain" in the app
And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app
And I press "Save" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
When I press "Search" in the app
And I set the field "Search query" to "something" in the app
And I press "search" near "No entries were found." in the app
Then I should see "No entries were found."
When I set the field "Search query" to "potato" in the app
And I press "search" near "No entries were found." in the app
And I set the field "Search query" to " " in the app
And I press "Display options" in the app
And I press "Refresh" in the app
And I press "potato" in the app
Then I should see "potato"
And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae."
@app @3.8.0
Scenario: Navigate to glossary terms by link (auto-linking)
When the "glossary" filter is "on"
And I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "This entry should be automatically linked" in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "car" in the app
And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app
And I press "This entry should be automatically linked" in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "mountain" in the app
And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app
And I press "This entry should be automatically linked" in the app
And I press "Save" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
When I press the back button in the app
And I press "Test forum name" in the app
And I press "add" in the app
And I set the field "Subject" to "Testing auto-link glossary"
And I set the field "Message" to "Glossary terms auto-linked: potato car mountain" in the app
And I press "Post to forum" in the app
And I press "Testing auto-link glossary" near "Last post a few seconds ago" in the app
Then I should see "car"
When I press "car" in the app
Then the header should be "car" in the app
And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods."
When I press the back button in the app
And I press "mountain" in the app
Then the header should be "mountain" in the app
And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak."
@app @3.8.0
Scenario: See comments
# Create entries as a student
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "car" in the app
And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "mountain" in the app
And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app
And I press "Save" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
When I press "mountain" in the app
Then I should see "Comments (0)"
# Write comments as a teacher
When I enter the course "Course 1" as "teacher1" in the app
And I press "Test glossary" in the app
And I press "mountain" in the app
Then I should see "Comments (0)"
When I press "Comments" in the app
And I should see "No comments"
When I press "close" in the app
And I set the field "Add a comment..." to "teacher first comment" in the app
And I press "Save comment" in the app
Then I should see "teacher first comment"
When I press "close" in the app
And I set the field "Add a comment..." to "teacher second comment" in the app
And I press "Save comment" in the app
Then I should see "teacher first comment"
And I should see "teacher second comment"
# View comments as a student
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "mountain" in the app
Then I should see "Comments (2)"
When I press "Comments" in the app
And I should see "teacher first comment"
And I should see "teacher second comment"
@app @3.8.0
Scenario: Prefetch
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "car" in the app
And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "mountain" in the app
And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app
And I press "Save" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
When I press "Display options" in the app
And I press "Download" in the app
And I press the back button in the app
And I press the back button in the app
And I enter the course "Course 1" in the app
And I switch offline mode to "true"
And I press "Test glossary" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
When I press "mountain" in the app
Then I should see "mountain"
And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak."
And I should not see "Comments cannot be retrieved"
And I should see "Comments (0)"
@app @3.8.0
Scenario: Sync
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I switch offline mode to "true"
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "car" in the app
And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "mountain" in the app
And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app
And I press "Save" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
And I should see "Entries to be synced"
And I should see "This Glossary has offline data to be synchronised."
When I switch offline mode to "false"
And I press "close" in the app
And I set the field "Concept" to "testSync" in the app
And I set the field "Definition" to "testSync" in the app
And I press "Save" in the app
And I press "Display options" in the app
And I press "Synchronise now" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
And I should see "testSync"
But I should not see "Entries to be synced"
And I should not see "This Glossary has offline data to be synchronised."
@app @3.8.0
Scenario: Add/view ratings
# Create entries as a student
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "close" in the app
And I set the field "Concept" to "potato" in the app
And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "car" in the app
And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app
And I press "Save" in the app
And I press "close" in the app
And I set the field "Concept" to "mountain" in the app
And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app
And I press "Save" in the app
Then the header should be "Test glossary" in the app
And I should see "car"
And I should see "mountain"
And I should see "potato"
# Rate entries as teacher1
When I enter the course "Course 1" as "teacher1" in the app
And I press "Test glossary" in the app
And I press "mountain" in the app
Then I should see "Average of ratings: -"
When I press "None" in the app
And I press "1" in the app
Then I should see "Average of ratings: 1"
# Rate entries as teacher2
When I enter the course "Course 1" as "teacher2" in the app
And I press "Test glossary" in the app
And I press "mountain" in the app
And I switch offline mode to "true"
And I press "None" in the app
And I press "0" in the app
Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later."
And I should see "Average of ratings: 1"
When I switch offline mode to "false"
And I press the back button in the app
Then I should see "This Glossary has offline data to be synchronised."
When I press "Display options" in the app
And I press "Synchronise now" in the app
And I press "mountain" in the app
Then I should see "Average of ratings: 0.5"
# View ratings as a student
When I enter the course "Course 1" as "student1" in the app
And I press "Test glossary" in the app
And I press "mountain" in the app
Then the header should be "mountain" in the app
But I should not see "Average of ratings: 0.5"

View File

@ -0,0 +1,289 @@
@mod @mod_glossary @app @javascript
Feature: Test glossary navigation
Background:
Given the following "users" exist:
| username | firstname | lastname |
| student1 | First | Student |
| student2 | Second | Student |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | course | idnumber | displayformat |
| glossary | Fruits glossary | C1 | glossary | entrylist |
And the following "mod_glossary > entries" exist:
| glossary | concept | definition | user |
| glossary | Acerola | Acerola is a fruit | student1 |
| glossary | Apple | Apple is a fruit | student2 |
| glossary | Apricots | Apricots are a fruit | student1 |
| glossary | Avocado | Avocado is a fruit | student2 |
| glossary | Banana | Banana is a fruit | student1 |
| glossary | Blackberries | Blackberries is a fruit | student2 |
| glossary | Blackcurrant | Blackcurrant is a fruit | student1 |
| glossary | Blueberries | Blueberries is a fruit | student2 |
| glossary | Breadfruit | Breadfruit is a fruit | student1 |
| glossary | Cantaloupe | Cantaloupe is a fruit | student2 |
| glossary | Carambola | Carambola is a fruit | student1 |
| glossary | Cherimoya | Cherimoya is a fruit | student2 |
| glossary | Cherries | Cherries is a fruit | student1 |
| glossary | Clementine | Clementine is a fruit | student2 |
| glossary | Coconut | Coconut is a fruit | student1 |
| glossary | Cranberries | Cranberries is a fruit | student2 |
| glossary | Date Fruit | Date Fruit is a fruit | student1 |
| glossary | Durian | Durian is a fruit | student2 |
| glossary | Elderberries | Elderberries is a fruit | student1 |
| glossary | Feijoa | Feijoa is a fruit | student2 |
| glossary | Figs | Figs is a fruit | student1 |
| glossary | Gooseberries | Gooseberries are a fruit | student2 |
| glossary | Grapefruit | Grapefruit is a fruit | student1 |
| glossary | Grapes | Grapes are a fruit | student2 |
| glossary | Guava | Guava is a fruit | student1 |
| glossary | Honeydew Melon | Honeydew Melon is a fruit | student2 |
| glossary | Jackfruit | Jackfruit is a fruit | student1 |
| glossary | Java-Plum | Java-Plum is a fruit | student2 |
| glossary | Jujube Fruit | Jujube Fruit is a fruit | student1 |
| glossary | Kiwifruit | Kiwifruit is a fruit | student2 |
| glossary | Kumquat | Kumquat is a fruit | student1 |
| glossary | Lemon | Lemon is a fruit | student2 |
| glossary | lime | lime is a fruit | student1 |
| glossary | Lime | Lime is a fruit | student2 |
| glossary | Longan | Longan is a fruit | student1 |
| glossary | Loquat | Loquat is a fruit | student2 |
| glossary | Lychee | Lychee is a fruit | student1 |
| glossary | Mandarin | Mandarin is a fruit | student2 |
| glossary | Mango | Mango is a fruit | student1 |
| glossary | Mangosteen | Mangosteen is a fruit | student2 |
| glossary | Mulberries | Mulberries are a fruit | student1 |
| glossary | Nectarine | Nectarine is a fruit | student2 |
| glossary | Olives | Olives are a fruit | student1 |
| glossary | Orange | Orange is a fruit | student2 |
| glossary | Papaya | Papaya is a fruit | student1 |
| glossary | Passion Fruit | Passion Fruit is a fruit | student2 |
| glossary | Peaches | Peaches is a fruit | student1 |
| glossary | Pear | Pear is a fruit | student2 |
| glossary | Persimmon | Persimmon is a fruit | student1 |
| glossary | Pitaya | Pitaya is a fruit | student2 |
| glossary | Pineapple | Pineapple is a fruit | student1 |
| glossary | Pitanga | Pitanga is a fruit | student2 |
| glossary | Plantain | Plantain is a fruit | student1 |
| glossary | Plums | Plums are a fruit | student2 |
| glossary | Pomegranate | Pomegranate is a fruit | student1 |
| glossary | Prickly Pear | Prickly Pear is a fruit | student2 |
| glossary | Prunes | Prunes is a fruit | student1 |
| glossary | Pummelo | Pummelo is a fruit | student2 |
| glossary | Quince | Quince is a fruit | student1 |
| glossary | Raspberries | Raspberries are a fruit | student2 |
| glossary | Rhubarb | Rhubarb is a fruit | student1 |
| glossary | Rose-Apple | Rose-Apple is a fruit | student2 |
| glossary | Sapodilla | Sapodilla is a fruit | student1 |
| glossary | Sapote, Mamey | Sapote, Mamey is a fruit | student2 |
| glossary | Soursop | Soursop is a fruit | student1 |
| glossary | Strawberries | Strawberries is a fruit | student2 |
| glossary | Tamarind | Tamarind is a fruit | student2 |
| glossary | Tangerine | Tangerine is a fruit | student1 |
| glossary | Watermelon | Watermelon is a fruit | student2 |
Scenario: Mobile navigation
Given I enter the course "Course 1" as "student1" in the app
# Alphabetically
When I press "Fruits glossary" in the app
Then I should find "Acerola" in the app
And I should find "Apple" in the app
But I should not find "Honeydew Melon" in the app
# Alphabetically — Infinite loading
When I load more items in the app
Then I should find "Honeydew Melon" in the app
# Alphabetically — Swipe
When I press "Acerola" in the app
Then I should find "Acerola is a fruit" in the app
When I swipe to the right in the app
Then I should find "Acerola is a fruit" in the app
When I swipe to the left in the app
Then I should find "Apple is a fruit" in the app
When I swipe to the left in the app
Then I should find "Apricots are a fruit" in the app
# By author
When I press the back button in the app
And I scroll to "Acerola" in the app
And I press "Browse entries" in the app
And I press "Group by author" in the app
Then I should find "First Student" in the app
And I should find "Acerola" in the app
And I should find "Apricots" in the app
But I should not find "Second Student" in the app
And I should not find "Apple" in the app
# By author — Infinite loading
When I load more items in the app
Then I should find "Second Student" in the app
And I should find "Apple" in the app
# By author — Swipe
When I press "Acerola" in the app
Then I should find "Acerola is a fruit" in the app
When I swipe to the right in the app
Then I should find "Acerola is a fruit" in the app
When I swipe to the left in the app
Then I should find "Apricots are a fruit" in the app
When I swipe to the left in the app
Then I should find "Banana is a fruit" in the app
# Search
When I press the back button in the app
And I scroll to "Acerola" in the app
And I press "Search" in the app
And I set the field "Search" to "melon" in the app
And I press "Search" "button" near "Clear search" in the app
Then I should find "Honeydew Melon" in the app
And I should find "Watermelon" in the app
But I should not find "Acerola" in the app
# Search — Swipe
When I press "Honeydew Melon" in the app
Then I should find "Honeydew Melon is a fruit" in the app
When I swipe to the right in the app
Then I should find "Honeydew Melon is a fruit" in the app
When I swipe to the left in the app
Then I should find "Watermelon is a fruit" in the app
When I swipe to the left in the app
Then I should find "Watermelon is a fruit" in the app
# Offline
When I press the back button in the app
And I press "Clear search" in the app
And I press "Add a new entry" in the app
And I switch offline mode to "true"
And I set the field "Concept" to "Tomato" in the app
And I set the field "Definition" to "Tomato is a fruit" in the app
And I press "Save" in the app
And I press "Add a new entry" in the app
And I set the field "Concept" to "Cashew" in the app
And I set the field "Definition" to "Cashew is a fruit" in the app
And I press "Save" in the app
Then I should find "Entries to be synced" in the app
And I should find "Tomato" in the app
And I should find "Cashew" in the app
# Offline — Swipe
When I press "Cashew" in the app
Then I should find "Cashew is a fruit" in the app
When I swipe to the right in the app
Then I should find "Cashew is a fruit" in the app
When I swipe to the left in the app
Then I should find "Tomato is a fruit" in the app
When I swipe to the left in the app
Then I should find "Acerola is a fruit" in the app
Scenario: Tablet navigation
Given I enter the course "Course 1" as "student1" in the app
And I change viewport size to "1200x640"
# Alphabetically
When I press "Fruits glossary" in the app
Then I should find "Acerola" in the app
And I should find "Apple" in the app
And "Acerola" near "Apple" should be selected in the app
And I should find "Acerola is a fruit" inside the split-view content in the app
But I should not find "Honeydew Melon" in the app
# Alphabetically — Infinite loading
When I load more items in the app
Then I should find "Honeydew Melon" in the app
# Alphabetically — Split view
When I press "Apple" in the app
Then "Apple" near "Acerola" should be selected in the app
And I should find "Apple is a fruit" inside the split-view content in the app
When I press "Honeydew Melon" in the app
Then "Honeydew Melon" near "Guava" should be selected in the app
And I should find "Honeydew Melon is a fruit" inside the split-view content in the app
# By author
When I press "Apple" in the app
When I scroll to "Apple" in the app
And I press "Browse entries" in the app
And I press "Group by author" in the app
Then I should find "First Student" in the app
And I should find "Acerola" in the app
And I should find "Apricots" in the app
And "Acerola" near "Apricots" should be selected in the app
And I should find "Acerola is a fruit" inside the split-view content in the app
But I should not find "Second Student" in the app
And I should not find "Apple" in the app
# By author — Infinite loading
When I load more items in the app
Then I should find "Second Student" in the app
And I should find "Apple" in the app
# By author — Split view
When I press "Apricots" in the app
And "Apricots" near "Acerola" should be selected in the app
And I should find "Apricots are a fruit" inside the split-view content in the app
When I press "Apple" in the app
And "Apple" near "Persimmon" should be selected in the app
And I should find "Apple is a fruit" inside the split-view content in the app
# Search
When I press "Search" in the app
And I set the field "Search" to "melon" in the app
And I press "Search" "button" near "Clear search" in the app
Then I should find "Honeydew Melon" in the app
And I should find "Watermelon" in the app
And "Honeydew Melon" near "Watermelon" should be selected in the app
And I should find "Honeydew Melon is a fruit" inside the split-view content in the app
But I should not find "Acerola" in the app
# Search — Split view
When I press "Watermelon" in the app
Then "Watermelon" near "Honeydew Melon" should be selected in the app
And I should find "Watermelon is a fruit" inside the split-view content in the app
# Offline
When I press "Clear search" in the app
And I press "Add a new entry" in the app
And I switch offline mode to "true"
And I set the field "Concept" to "Tomato" in the app
And I set the field "Definition" to "Tomato is a fruit" in the app
And I press "Save" in the app
And I set the field "Concept" to "Cashew" in the app
And I set the field "Definition" to "Cashew is a fruit" in the app
And I press "Save" in the app
Then I should find "Entries to be synced" in the app
And I should find "Tomato" in the app
And I should find "Cashew" in the app
# Offline — Split view
When I press "Cashew" in the app
Then "Cashew" near "Tomato" should be selected in the app
And I should find "Cashew is a fruit" inside the split-view content in the app
When I press "Tomato" in the app
Then "Tomato" near "Cashew" should be selected in the app
And I should find "Tomato is a fruit" inside the split-view content in the app
When I press "Acerola" in the app
Then "Acerola" near "Tomato" should be selected in the app
And I should find "Acerola is a fruit" inside the split-view content in the app

View File

@ -0,0 +1,82 @@
@mod @mod_login @app @javascript
Feature: Test basic usage of login in app
I need basic login functionality to work
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username | firstname | lastname |
| student1 | david | student |
| student2 | pau | student2 |
| teacher1 | juan | teacher |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
| teacher1 | C1 | editingteacher |
Scenario: Add a new account in the app & Site name in displayed when adding a new account
When I enter the app
And I press the back button in the app
And I set the field "Your site" to "$WWWROOT" in the app
And I press "Connect to your site" in the app
Then I should find "Acceptance test site" in the app
When I set the field "Username" to "student1" in the app
And I set the field "Password" to "student1" in the app
And I press "Log in" near "Forgotten your username or password?" in the app
Then I should find "Acceptance test site" in the app
But I should not find "Log in" in the app
Scenario: Add a non existing account
When I enter the app
And I log in as "student1"
And I press the user menu button in the app
And I press "Log out" in the app
And I wait the app to restart
And I press "Add" in the app
And I set the field "Your site" to "Wrong Site Address" in the app
And I press enter in the app
Then I should find "Cannot connect" in the app
And I should find "Wrong Site Address" in the app
Scenario: Add a non existing account from accounts switcher
When I enter the app
And I log in as "student1"
And I press the user menu button in the app
And I press "Switch account" in the app
And I press "Add" in the app
And I wait the app to restart
And I set the field "Your site" to "Wrong Site Address" in the app
And I press enter in the app
Then I should find "Cannot connect" in the app
And I should find "Wrong Site Address" in the app
Scenario: Delete an account
When I enter the app
And I log in as "student1"
And I press the user menu button in the app
And I press "Log out" in the app
And I wait the app to restart
Then I should find "Acceptance test site" in the app
And I press "Edit accounts list" in the app
And I press "Remove account" near "Acceptance test site" in the app
And I press "Delete" near "Are you sure you want to remove the account on Acceptance test site?" in the app
Then I should find "Connect to Moodle" in the app
But I should not find "Acceptance test site" in the app
Scenario: Require minium version of the app for a site
# Log in with a previous required version
Given the following config values are set as admin:
| minimumversion | 3.8.1 | tool_mobile |
When I enter the app
Then I should not find "App update required" in the app
# Log in with a future required version
Given the following config values are set as admin:
| minimumversion | 11.0.0 | tool_mobile |
When I enter the app
Then I should find "App update required" in the app

View File

@ -0,0 +1,412 @@
@mod @mod_messages @app @javascript
Feature: Test basic usage of messages in app
In order to participate with messages while using the mobile app
As a student
I need basic message functionality to work
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | teacher | teacher1@example.com |
| student1 | Student1 | student1 | student1@example.com |
| student2 | Student2 | student2 | student2@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
Scenario: View recent conversations and contacts
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Contacts" in the app
Then I should find "No contacts" in the app
When I press "Search people and messages" in the app
And I set the field "Search" to "student" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I set the field "New message" to "heeey student" in the app
And I press "Send" in the app
And I press "Display options" in the app
And I press "Add to contacts" in the app
And I press "Add" near "Are you sure you want to add Student1 student1 to your contacts?" in the app
Then I should find "Contact request sent" in the app
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Requests" in the app
And I press "Teacher teacher" in the app
And I press "Accept and add to contacts" in the app
Then I should not find "Teacher teacher would like to contact you" in the app
When I press the back button in the app
And I press "Contacts" near "No contact requests" in the app
Then the header should be "Contacts" in the app
And I should find "Teacher teacher" in the app
When I press the back button in the app
And I press "Teacher teacher" in the app
Then the header should be "Teacher teacher" in the app
And I should find "heeey student" in the app
Scenario: Search users
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student2" in the app
And I press "Search" "button" in the app
Then I should find "Student2 student2" in the app
When I set the field "Search" to "Teacher" in the app
And I press "Search" "button" in the app
Then I should find "Teacher teacher" in the app
Scenario: Send/receive messages in existing conversations
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I set the field "New message" to "heeey student" in the app
And I press "Send" in the app
Then I should find "heeey student" in the app
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "teacher" in the app
And I press "Search" "button" in the app
And I press "Teacher teacher" in the app
Then I should find "heeey student" in the app
When I set the field "New message" to "hi" in the app
And I press "Send" in the app
Then I should find "hi" in the app
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
Then I should find "heeey student" in the app
And I should find "hi" in the app
When I set the field "New message" to "byee" in the app
And I press "Send" in the app
Then I should find "heeey student" in the app
And I should find "hi" in the app
And I should find "byee" in the app
Scenario: User profile: send message, add/remove contact
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I set the field "New message" to "heeey student" in the app
And I press "Send" in the app
Then I should find "heeey student" in the app
When I press "Display options" in the app
And I press "Add to contacts" in the app
And I press "Add" in the app
Then I should find "Contact request sent" in the app
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Requests" in the app
And I press "Teacher teacher" in the app
Then I should find "Teacher teacher would like to contact you" in the app
When I press "Accept and add to contacts" in the app
Then I should not find "Teacher teacher would like to contact you" in the app
When I press "Display options" in the app
And I press "User info" in the app
And I press "Message" in the app
And I set the field "New message" to "hi" in the app
And I press "Send" "button" in the app
Then I should find "heeey student" in the app
And I should find "hi" in the app
When I press "Display options" in the app
And I press "Remove from contacts" in the app
And I press "Remove" in the app
And I wait loading to finish in the app
And I press the back button in the app
And I press the back button in the app
And I press "Display options" in the app
Then I should find "Add to contacts" in the app
When I press "Delete conversation" in the app
And I press "Delete" near "Are you sure you would like to delete this entire conversation?" in the app
Then I should not find "heeey student" in the app
And I should not find "hi" in the app
Scenario: Send message offline
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I switch offline mode to "true"
And I set the field "New message" to "heeey student" in the app
And I press "Send" in the app
Then I should find "heeey student" in the app
When I set the field "New message" to "byee" in the app
And I press "Send" in the app
Then I should find "byee" in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "Student1 student1" in the app
Then I should find "heeey student" in the app
And I should find "byee" in the app
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Teacher teacher" in the app
Then I should find "heeey student" in the app
And I should find "byee" in the app
Scenario: Auto-sync messages
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I switch offline mode to "true"
And I set the field "New message" to "heeey student" in the app
And I press "Send" in the app
And I set the field "New message" to "byee" in the app
And I press "Send" in the app
Then I should find "byee" in the app
When I switch offline mode to "false"
And I run cron tasks in the app
And I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Teacher teacher" in the app
Then I should find "heeey student" in the app
And I should find "byee" in the app
Scenario: Search for messages
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I set the field "New message" to "test message" in the app
And I press "Send" in the app
Then I should find "test message" in the app
When I set the field "New message" to "search this message" in the app
And I press "Send" in the app
Then I should find "search this message" in the app
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "search this message" in the app
And I press "Search" "button" in the app
Then I should find "Messages" in the app
And I should find "search this message" in the app
When I press "search this message" near "Teacher teacher" in the app
Then I should find "test message" in the app
And I should find "search this message" in the app
Scenario: Star/Unstar
When I enter the app
And I log in as "teacher1"
And I press "Messages" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I set the field "New message" to "star message" in the app
And I press "Send" in the app
Then I should find "star message" in the app
When I enter the app
And I log in as "student2"
And I press "Messages" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I set the field "New message" to "test message student2" in the app
And I press "Send" in the app
Then I should find "test message student2" in the app
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
Then I should find "Private (2)" in the app
And I should find "Starred (1)" in the app
When I press "star message" in the app
And I press "Display options" in the app
And I press "Star conversation" in the app
And I press the back button in the app
Then I should find "Private (1)" in the app
And I should find "Starred (2)" in the app
When I press "Starred (2)" in the app
Then I should find "Teacher teacher" in the app
And I should find "Student1 student1" in the app
Scenario: User blocking feature
When I enter the course "Course 1" as "student2" in the app
And I press "Participants" in the app
And I press "Student1 student1" in the app
And I press "Message" in the app
And I press "Display options" in the app
And I press "Block user" in the app
And I press "Block user" near "Are you sure you want to block Student1 student1?" in the app
Then I should find "You have blocked this user" in the app
When I enter the course "Course 1" as "student1" in the app
And I press "Participants" in the app
And I press "Student2 student2" in the app
And I press "Message" in the app
Then I should find "You are unable to message this user" in the app
When I enter the course "Course 1" as "student2" in the app
And I press "Participants" in the app
And I press "Student1 student1" in the app
And I press "Message" in the app
And I press "Display options" in the app
Then I should find "Unblock user" in the app
But I should not find "Block user" in the app
When I press "Unblock user" in the app
And I press "Unblock user" near "Are you sure you want to unblock Student1 student1?" in the app
Then I should not find "You have blocked this user" in the app
When I enter the course "Course 1" as "student1" in the app
And I press "Participants" in the app
And I press "Student2 student2" in the app
And I press "Message" in the app
And I set the field "New message" to "test message" in the app
And I press "Send" in the app
Then I should find "test message" in the app
But I should not find "You are unable to message this user" in the app
Scenario: Mute Unmute conversations
When I enter the course "Course 1" as "student1" in the app
And I press "Participants" in the app
And I press "Student2 student2" in the app
And I press "Message" in the app
And I set the field "New message" to "test message" in the app
And I press "Send" in the app
Then I should find "test message" in the app
When I press "Display options" in the app
And I press "Mute" in the app
Then I should find "Muted conversation" in the app
When I press "Display options" in the app
And I press "Unmute" in the app
Then I should not find "Muted conversation" in the app
When I press "Display options" in the app
When I press "Mute" in the app
Then I should find "Muted conversation" in the app
When I press "Messages" in the app
And I press "Private (1)" in the app
And I press "Student2 student2" in the app
Then I should find "test message" in the app
And I should find "Muted conversation" in the app
Scenario: Self conversations
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
Then I should find "Starred (1)" in the app
When I press "Student1 student1" in the app
And I set the field "New message" to "self conversation online" in the app
And I press "Send" in the app
Then I should find "self conversation online" in the app
When I switch offline mode to "true"
And I set the field "New message" to "self conversation offline" in the app
And I press "Send" in the app
Then I should find "self conversation offline" in the app
When I switch offline mode to "false"
And I press the back button in the app
And I press "Student1 student1" in the app
And I press "Display options" in the app
Then I should find "Show delete messages" in the app
And I should find "Delete conversation" in the app
When I press "Unstar conversation" in the app
And I press "Display options" in the app
Then I should find "Star conversation" in the app
And I should find "Delete conversation" in the app
When I press "Show delete messages" in the app
And I close the popup in the app
Then I should find "self conversation online" in the app
And I should find "self conversation offline" in the app
When I press "Delete message" near "self conversation offline" in the app
And I press "OK" in the app
Then I should find "self conversation online" in the app
But I should not find "self conversation offline" in the app
When I press "Display options" in the app
And I press "Delete conversation" in the app
And I press "Delete" near "Are you sure you would like to delete this entire personal conversation?" in the app
Then I should not find "self conversation online" in the app
And I should not find "self conversation offline" in the app
When I press the back button in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "Student1 student1" in the app
And I press "Search" "button" in the app
And I press "Student1 student1" in the app
And I set the field "New message" to "auto search test" in the app
And I press "Send" in the app
Then I should find "auto search test" in the app
When I press the back button in the app
And I press the back button in the app
And I press "Private" in the app
And I press "Student1 student1" in the app
Then I should find "auto search test" in the app

View File

@ -0,0 +1,43 @@
@mod @mod_messages @app @javascript
Feature: Test messages navigation in the app
Background:
Given the following "users" exist:
| username | firstname |
| teacher | Teacher |
| student | Student |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| teacher | C1 | editingteacher |
| student | C1 | student |
Scenario: Avoid recursive links to profile
When I enter the app
And I log in as "teacher"
And I press "Messages" in the app
And I press "Contacts" in the app
And I press "Search people and messages" in the app
And I set the field "Search" to "student" in the app
And I press "Search" "button" in the app
And I press "Student" in the app
And I set the field "New message" to "Hi there" in the app
And I press "Send" in the app
Then I should find "Hi there" in the app
When I press "Display options" in the app
And I press "User info" in the app
Then I should find "Details" in the app
When I press "Message" in the app
Then I should find "Hi there" in the app
When I press "Display options" in the app
Then I should not find "User info" in the app
When I close the popup in the app
And I press the back button in the app
And I press the back button in the app
Then I should find "Hi there" in the app

View File

@ -0,0 +1,18 @@
@mod @mod_messages @app @javascript
Feature: Test messages settings
Background:
Given the following "users" exist:
| username |
| student1 |
Scenario: Modify settings
When I enter the app
And I log in as "student1"
And I press "Messages" in the app
And I press "Message preferences" in the app
And I select "My contacts only" in the app
Then "My contacts only" should be selected in the app
And I select "My contacts and anyone in my courses" in the app
Then "My contacts and anyone in my courses" should be selected in the app

View File

@ -0,0 +1,166 @@
@mod @mod_quiz @app @javascript
Feature: Attempt a quiz in app
As a student
In order to demonstrate what I know
I need to be able to attempt quizzes
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username |
| student1 |
| teacher1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | TF1 | Text of the first question |
| Test questions | truefalse | TF2 | Text of the second question |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
| TF2 | 2 |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Quiz 2 | Quiz 2 description | C1 | quiz2 |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions 2|
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | multichoice | TF3 | Text of the first question |
| Test questions | shortanswer | TF4 | Text of the second question |
| Test questions | numerical | TF5 | Text of the third question |
| Test questions | essay | TF6 | Text of the fourth question |
| Test questions | ddwtos | TF7 | The [[1]] brown [[2]] jumped over the [[3]] dog. |
| Test questions | truefalse | TF8 | Text of the sixth question |
| Test questions | match | TF9 | Text of the seventh question |
And quiz "Quiz 2" contains the following questions:
| question | page |
| TF3 | 1 |
| TF4 | 2 |
| TF5 | 3 |
| TF6 | 4 |
| TF7 | 5 |
| TF8 | 6 |
| TF9 | 7 |
Scenario: View a quiz entry page (attempts, status, etc.)
When I enter the course "Course 1" as "student1" in the app
And I press "Quiz 1" in the app
And I press "Attempt quiz now" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app
When I press "Next" near "Question 1" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app
When I press "Previous" near "Question 2" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app
When I press "Next" near "Quiz 1" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app
When I press "Previous" near "Quiz 1" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app
When I press "Next" near "Question 1" in the app
And I press "Submit" near "Quiz 1" in the app
Then I should find "Summary of attempt" in the app
When I press "Not yet answered" within "2" "ion-item" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app
When I press "Submit" in the app
And I press "Submit all and finish" in the app
Then I should find "Once you submit" in the app
When I press "Cancel" near "Once you submit" in the app
Then I should find "Summary of attempt" in the app
When I press "Submit all and finish" in the app
And I press "OK" near "Once you submit" in the app
Then I should find "Review" in the app
And I should find "Started on" in the app
And I should find "State" in the app
And I should find "Completed on" in the app
And I should find "Time taken" in the app
And I should find "Marks" in the app
And I should find "Grade" in the app
And I should find "Question 1" in the app
And I should find "Question 2" in the app
Scenario: Attempt a quiz (all question types)
When I enter the course "Course 1" as "student1" in the app
And I press "Quiz 2" in the app
And I press "Attempt quiz now" in the app
And I press "Four" in the app
And I press "Three" in the app
And I press "Next" near "Quiz 2" in the app
And I set the field "Answer" to "testing" in the app
And I press "Next" near "Question 2" in the app
And I set the field "Answer" to "5" in the app
And I press "Next" near "Question 3" in the app
And I set the field "Answer" to "Testing an essay" in the app
And I press "Next" "ion-button" near "Question 4" in the app
And I press "quick" ".drag" in the app
And I press "" ".place1.drop" in the app
And I press "fox" ".drag" in the app
And I press "" ".place2.drop" in the app
And I press "lazy" ".drag" in the app
And I press "" ".place3.drop" in the app
And I press "Next" near "Question 5" in the app
And I press "True" in the app
And I press "Next" near "Question 6" in the app
And I press "Choose... , frog" in the app
And I press "amphibian" in the app
And I press "Choose... , newt" in the app
And I press "insect" in the app
And I press "Choose... , cat" in the app
And I press "mammal" in the app
And I press "Submit" near "Question 7" in the app
Then I should not find "Not yet answered" in the app
When I press "Submit all and finish" in the app
And I press "OK" in the app
Then I should find "Review" in the app
And I should find "Finished" in the app
And I should find "Not yet graded" in the app
Scenario: Submit a quiz & Review a quiz attempt
When I enter the course "Course 1" as "student1" in the app
And I press "Quiz 1" in the app
And I press "Attempt quiz now" in the app
And I press "True" in the app
And I press "Next" near "Question 1" in the app
And I press "False" in the app
And I press "Submit" near "Question 2" in the app
And I press "Submit all and finish" in the app
And I press "OK" in the app
Then I should find "Review" in the app
When I enter the course "Course 1" as "teacher1" in the app
And I press "Quiz 1" in the app
And I press "Information" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I follow "Attempts: 1"
And I follow "Review attempt"
Then I should see "Finished"
And I should see "1.00/2.00"

View File

@ -0,0 +1,74 @@
@mod @mod_quiz @app @javascript
Feature: Attempt a quiz in app
As a student
In order to demonstrate what I know
I need to be able to attempt quizzes
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username |
| student1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | TF1 | Text of the first question |
| Test questions | truefalse | TF2 | Text of the second question |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
| TF2 | 2 |
Scenario: Next and previous navigation
Given I enter the app
And I log in as "student1"
When I enter the course "Course 1" in the app
And I press "Quiz 1" in the app
And I press "Attempt quiz now" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app
When I press "Next" near "Question 1" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app
When I press "Previous" near "Question 2" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app
When I press "Next" near "Quiz 1" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app
When I press "Previous" near "Quiz 1" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app
When I press "Next" near "Question 1" in the app
And I press "Submit" in the app
Then I should find "Summary of attempt" in the app
When I press "Not yet answered" within "2" "ion-item" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app
When I press "Submit" in the app
And I press "Submit all and finish" in the app
Then I should find "Once you submit" in the app
When I press "Cancel" near "Once you submit" in the app
Then I should find "Summary of attempt" in the app
When I press "Submit all and finish" in the app
And I press "OK" near "Once you submit" in the app
Then I should find "Review" in the app

View File

@ -0,0 +1,395 @@
@mod @mod_survey @app @app_upto3.9.4 @javascript
Feature: Test basic usage of survey activity in app
In order to participate in surveys while using the mobile app
As a student
I need basic survey functionality to work
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username |
| student1 |
| teacher1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| survey | Test survey name | Test survey | C1 | survey | 0 |
@app @3.8.0
Scenario: Answer a survey & View results (ATTLS)
When I enter the course "Course 1" as "student1" in the app
And I press "Test survey name" in the app
And I press "Choose" near "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app
And I press "Strongly agree" in the app
And I press "Choose" near "2. I like playing devil's advocate - arguing the opposite of what someone is saying." in the app
And I press "Strongly disagree" in the app
And I press "Choose" near "3. I like to understand where other people are 'coming from', what experiences have led them to feel the way they do." in the app
And I press "Somewhat agree" in the app
And I press "Choose" near "4. The most important part of my education has been learning to understand people who are very different to me." in the app
And I press "Somewhat disagree" in the app
And I press "Choose" near "5. I feel that the best way for me to achieve my own identity is to interact with a variety of other people." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "6. I enjoy hearing the opinions of people who come from backgrounds different to mine - it helps me to understand how the same things can be seen in such different ways." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "7. I find that I can strengthen my own position through arguing with someone who disagrees with me." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "8. I am always interested in knowing why people say and believe the things they do." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "9. I often find myself arguing with the authors of books that I read, trying to logically figure out why they're wrong." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "10. It's important for me to remain as objective as possible when I analyze something." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "11. I try to think with people instead of against them." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "12. I have certain criteria I use in evaluating arguments." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "13. I'm more likely to try to understand someone else's opinion than to try to evaluate it." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "14. I try to point out weaknesses in other people's thinking to help them clarify their arguments." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "15. I tend to put myself in other people's shoes when discussing controversial issues, to see why they think the way they do." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "16. One could call my way of analysing things 'putting them on trial' because I am careful to consider all the evidence." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "17. I value the use of logic and reason over the incorporation of my own concerns when solving problems." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "18. I can obtain insight into opinions that differ from mine through empathy." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "19. When I encounter people whose opinions seem alien to me, I make a deliberate effort to 'extend' myself into that person, to try to see how they could have those opinions." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Choose" near "20. I spend time figuring out what's 'wrong' with things. For example, I'll look for something in a literary interpretation that isn't argued well enough." in the app
And I press "Somewhat agree" near "Neither agree nor disagree" in the app
And I press "Submit" in the app
And I press "OK" in the app
And I press "open" in the app
And I switch to the browser tab opened by the app
And I log in as "student1"
Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages."
And I should see "1 people have completed this survey so far"
@app @3.8.0
Scenario: Answer a survey & View results (Critical incidents)
Given the following "activities" exist:
| activity | name | intro | template |course | idnumber | groupmode |
| survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test survey critical incidents" in the app
And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most engaged as a learner?']" to "1st answer"
And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most distanced as a learner?']" to "2nd answer"
And I set the field with xpath "//textarea[@aria-label='What action from anyone in the forums did you find most affirming or helpful?']" to "3rd answer"
And I set the field with xpath "//textarea[@aria-label='What action from anyone in the forums did you find most puzzling or confusing?']" to "4th answer"
And I set the field with xpath "//textarea[@aria-label='What event surprised you most?']" to "5th answer"
And I press "Submit" in the app
And I press "OK" in the app
Then I should see "Results"
When I press "Results" in the app
And I switch to the browser tab opened by the app
And I log in as "student1"
Then I should see "Test survey critical incidents"
And I should see "1st answer"
And I should see "2nd answer"
And I should see "3rd answer"
And I should see "4th answer"
And I should see "5th answer"
@app @3.8.0
Scenario: Answer a survey & View results (Colles actual)
Given the following "activities" exist:
| activity | name | intro | template |course | idnumber | groupmode |
| survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test survey Colles (actual)" in the app
And I press "Choose" near "1. my learning focuses on issues that interest me." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "2. what I learn is important for my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "3. I learn how to improve my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "4. what I learn connects well with my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "5. I think critically about how I learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "6. I think critically about my own ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "7. I think critically about other students' ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "8. I think critically about ideas in the readings." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "9. I explain my ideas to other students." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "10. I ask other students to explain their ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "11. other students ask me to explain my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "12. other students respond to my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "13. the tutor stimulates my thinking." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "14. the tutor encourages me to participate." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "15. the tutor models good discourse." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "16. the tutor models critical self-reflection." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "17. other students encourage my participation." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "18. other students praise my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "19. other students value my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "20. other students empathise with my struggle to learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "21. I make good sense of other students' messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "22. other students make good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "23. I make good sense of the tutor's messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "24. the tutor makes good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "25. How long did this survey take you to complete?" in the app
And I press "under 1 min" in the app
And I press "Submit" in the app
And I press "OK" in the app
Then I should see "You have completed this survey"
When I press "Results" in the app
And I switch to the browser tab opened by the app
And I log in as "student1"
Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages."
And I should see "1 people have completed this survey so far"
@app @3.8.0
Scenario: Answer a survey & View results (Colles preferred)
Given the following "activities" exist:
| activity | name | intro | template | course | idnumber | groupmode |
| survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test survey Colles (preferred)" in the app
And I press "Choose" near "1. my learning focuses on issues that interest me." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "2. what I learn is important for my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "3. I learn how to improve my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "4. what I learn connects well with my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "5. I think critically about how I learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "6. I think critically about my own ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "7. I think critically about other students' ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "8. I think critically about ideas in the readings." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "9. I explain my ideas to other students." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "10. I ask other students to explain their ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "11. other students ask me to explain my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "12. other students respond to my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "13. the tutor stimulates my thinking." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "14. the tutor encourages me to participate." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "15. the tutor models good discourse." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "16. the tutor models critical self-reflection." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "17. other students encourage my participation." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "18. other students praise my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "19. other students value my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "20. other students empathise with my struggle to learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "21. I make good sense of other students' messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "22. other students make good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "23. I make good sense of the tutor's messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "24. the tutor makes good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "25. How long did this survey take you to complete?" in the app
And I press "under 1 min" in the app
And I press "Submit" in the app
And I press "OK" in the app
Then I should see "You have completed this survey"
When I press "Results" in the app
And I switch to the browser tab opened by the app
And I log in as "student1"
Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages."
And I should see "1 people have completed this survey so far"
@app @3.8.0
Scenario: Answer a survey & View results (Colles preferred amd actual)
Given the following "activities" exist:
| activity | name | intro | template | course | idnumber | groupmode |
| survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test survey Colles (preferred and actual)" in the app
And I press "Choose" near "1. I prefer that my learning focuses on issues that interest me." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "2. I found that my learning focuses on issues that interest me." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "3. I prefer that what I learn is important for my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "4. I found that what I learn is important for my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "5. I prefer that I learn how to improve my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "6. I found that I learn how to improve my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "7. I prefer that what I learn connects well with my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "8. I found that what I learn connects well with my professional practice." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "9. I prefer that I think critically about how I learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "10. I found that I think critically about how I learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "11. I prefer that I think critically about my own ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "12. I found that I think critically about my own ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "13. I prefer that I think critically about other students' ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "14. I found that I think critically about other students' ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "15. I prefer that I think critically about ideas in the readings." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "16. I found that I think critically about ideas in the readings." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "17. I prefer that I explain my ideas to other students." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "18. I found that I explain my ideas to other students." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "19. I prefer that I ask other students to explain their ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "20. I found that I ask other students to explain their ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "21. I prefer that other students ask me to explain my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "22. I found that other students ask me to explain my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "23. I prefer that other students respond to my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "24. I found that other students respond to my ideas." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "25. I prefer that the tutor stimulates my thinking." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "26. I found that the tutor stimulates my thinking." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "27. I prefer that the tutor encourages me to participate." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "28. I found that the tutor encourages me to participate." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "29. I prefer that the tutor models good discourse." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "30. I found that the tutor models good discourse." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "31. I prefer that the tutor models critical self-reflection." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "32. I found that the tutor models critical self-reflection." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "33. I prefer that other students encourage my participation." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "34. I found that other students encourage my participation." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "35. I prefer that other students praise my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "36. I found that other students praise my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "37. I prefer that other students value my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "38. I found that other students value my contribution." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "39. I prefer that other students empathise with my struggle to learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "40. I found that other students empathise with my struggle to learn." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "41. I prefer that I make good sense of other students' messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "42. I found that I make good sense of other students' messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "43. I prefer that other students make good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "44. I found that other students make good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "45. I prefer that I make good sense of the tutor's messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "46. I found that I make good sense of the tutor's messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "47. I prefer that the tutor makes good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "48. I found that the tutor makes good sense of my messages." in the app
And I press "Sometimes" near "Often" in the app
And I press "Choose" near "49. How long did this survey take you to complete?" in the app
And I press "1-2 min" in the app
And I press "Submit" in the app
And I press "OK" in the app
Then I should see "You have completed this survey"
When I press "Results" in the app
And I switch to the browser tab opened by the app
And I log in as "student1"
Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages."
And I should see "1 people have completed this survey so far"
@app @3.8.0
Scenario: Answer survey offline & Sync survey
Given the following "activities" exist:
| activity | name | intro | template | course | idnumber | groupmode |
| survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 |
When I enter the course "Course 1" as "student1" in the app
And I press "Test survey critical incidents" in the app
And I switch offline mode to "true"
And I press "Submit" in the app
And I press "OK" in the app
Then I should see "This Survey has offline data to be synchronised."
When I switch offline mode to "false"
And I press the back button in the app
And I press "Test survey critical incidents" in the app
And I press "Display options" in the app
And I press "Refresh" in the app
Then I should see "Results"
And I should see "You have completed this survey."
But I should not see "This Survey has offline data to be synchronised."
@app @3.8.0
Scenario: Prefetch & Auto-sync survey
Given the following "activities" exist:
| activity | name | intro | template | course | idnumber | groupmode |
| survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 |
When I enter the course "Course 1" as "student1" in the app
And I press "Display options" in the app
And I press "Course downloads" in the app
And I press "cloud download" near "Test survey critical incidents" in the app
And I press the back button in the app
And I switch offline mode to "true"
And I press "Test survey name" in the app
Then I should see "There was a problem connecting to the site. Please check your connection and try again."
When I press "OK" in the app
And I press the back button in the app
And I press "Test survey critical incidents" in the app
And I press "Submit" in the app
And I press "OK" in the app
Then I should see "This Survey has offline data to be synchronised."
When I switch offline mode to "false"
And I run cron tasks in the app
Then I should not see "This Survey has offline data to be synchronised."
And I should see "You have completed this survey."

View File

@ -0,0 +1,908 @@
(function() {
// Set up the M object - only pending_js is implemented.
window.M = window.M ? window.M : {};
const M = window.M;
M.util = M.util ? M.util : {};
M.util.pending_js = M.util.pending_js ? M.util.pending_js : []; // eslint-disable-line camelcase
/**
* Logs information from this Behat runtime JavaScript, including the time and the 'BEHAT'
* keyword so we can easily filter for it if needed.
*
* @param {string} text Information to log
*/
const log = function() {
const now = new Date();
const nowFormatted = String(now.getHours()).padStart(2, '0') + ':' +
String(now.getMinutes()).padStart(2, '0') + ':' +
String(now.getSeconds()).padStart(2, '0') + '.' +
String(now.getMilliseconds()).padStart(2, '0');
console.log('BEHAT: ' + nowFormatted, ...arguments); // eslint-disable-line no-console
};
/**
* Run after several setTimeouts to ensure queued events are finished.
*
* @param {function} target function to run
* @param {number} count Number of times to do setTimeout (leave blank for 10)
*/
const runAfterEverything = function(target, count) {
if (count === undefined) {
count = 10;
}
setTimeout(function() {
count--;
if (count == 0) {
target();
} else {
runAfterEverything(target, count);
}
}, 0);
};
/**
* Adds a pending key to the array.
*
* @param {string} key Key to add
*/
const addPending = function(key) {
// Add a special DELAY entry whenever another entry is added.
if (window.M.util.pending_js.length == 0) {
window.M.util.pending_js.push('DELAY');
}
window.M.util.pending_js.push(key);
log('PENDING+: ' + window.M.util.pending_js);
};
/**
* Removes a pending key from the array. If this would clear the array, the actual clear only
* takes effect after the queued events are finished.
*
* @param {string} key Key to remove
*/
const removePending = function(key) {
// Remove the key immediately.
window.M.util.pending_js = window.M.util.pending_js.filter(function(x) { // eslint-disable-line camelcase
return x !== key;
});
log('PENDING-: ' + window.M.util.pending_js);
// If the only thing left is DELAY, then remove that as well, later...
if (window.M.util.pending_js.length === 1) {
runAfterEverything(function() {
// Check there isn't a spinner...
checkUIBlocked();
// Only remove it if the pending array is STILL empty after all that.
if (window.M.util.pending_js.length === 1) {
window.M.util.pending_js = []; // eslint-disable-line camelcase
log('PENDING-: ' + window.M.util.pending_js);
}
});
}
};
/**
* Adds a pending key to the array, but removes it after some setTimeouts finish.
*/
const addPendingDelay = function() {
addPending('...');
removePending('...');
};
// Override XMLHttpRequest to mark things pending while there is a request waiting.
const realOpen = XMLHttpRequest.prototype.open;
let requestIndex = 0;
XMLHttpRequest.prototype.open = function() {
const index = requestIndex++;
const key = 'httprequest-' + index;
try {
// Add to the list of pending requests.
addPending(key);
// Detect when it finishes and remove it from the list.
this.addEventListener('loadend', function() {
removePending(key);
});
return realOpen.apply(this, arguments);
} catch (error) {
removePending(key);
throw error;
}
};
let waitingBlocked = false;
/**
* Checks if a loading spinner is present and visible; if so, adds it to the pending array
* (and if not, removes it).
*/
const checkUIBlocked = function() {
const blocked = document.querySelector('span.core-loading-spinner, ion-loading, .click-block-active');
if (blocked && blocked.offsetParent) {
if (!waitingBlocked) {
addPending('blocked');
waitingBlocked = true;
}
} else {
if (waitingBlocked) {
removePending('blocked');
waitingBlocked = false;
}
}
};
// It would be really beautiful if you could detect CSS transitions and animations, that would
// cover almost everything, but sadly there is no way to do this because the transitionstart
// and animationcancel events are not implemented in Chrome, so we cannot detect either of
// these reliably. Instead, we have to look for any DOM changes and do horrible polling. Most
// of the animations are set to 500ms so we allow it to continue from 500ms after any DOM
// change.
let recentMutation = false;
let lastMutation;
/**
* Called from the mutation callback to remove the pending tag after 500ms if nothing else
* gets mutated.
*
* This will be called after 500ms, then every 100ms until there have been no mutation events
* for 500ms.
*/
const pollRecentMutation = function() {
if (Date.now() - lastMutation > 500) {
recentMutation = false;
removePending('dom-mutation');
} else {
setTimeout(pollRecentMutation, 100);
}
};
/**
* Mutation callback, called whenever the DOM is mutated.
*/
const mutationCallback = function() {
lastMutation = Date.now();
if (!recentMutation) {
recentMutation = true;
addPending('dom-mutation');
setTimeout(pollRecentMutation, 500);
}
// Also update the spinner presence if needed.
checkUIBlocked();
};
// Set listener using the mutation callback.
const observer = new MutationObserver(mutationCallback);
observer.observe(document, {attributes: true, childList: true, subtree: true});
/**
* Check if an element is visible.
*
* @param {HTMLElement} element Element
* @param {HTMLElement} container Container
* @returns {boolean} Whether the element is visible or not
*/
const isElementVisible = (element, container) => {
if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none')
return false;
const parentElement = getParentElement(element);
if (parentElement === container)
return true;
if (!parentElement)
return false;
return isElementVisible(parentElement, container);
};
/**
* Check if an element is selected.
*
* @param {HTMLElement} element Element
* @param {HTMLElement} container Container
* @returns {boolean} Whether the element is selected or not
*/
const isElementSelected = (element, container) => {
const ariaCurrent = element.getAttribute('aria-current');
if (
(ariaCurrent && ariaCurrent !== 'false') ||
(element.getAttribute('aria-selected') === 'true') ||
(element.getAttribute('aria-checked') === 'true')
)
return true;
const parentElement = getParentElement(element);
if (!parentElement || parentElement === container)
return false;
return isElementSelected(parentElement, container);
};
/**
* Finds elements within a given container with exact info.
*
* @param {HTMLElement} container Parent element to search the element within
* @param {string} text Text to look for
* @return {Array} Elements containing the given text with exact boolean.
*/
const findElementsBasedOnTextWithinWithExact = (container, text) => {
const elements = [];
const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"]`;
for (const foundByAttributes of container.querySelectorAll(attributesSelector)) {
if (!isElementVisible(foundByAttributes, container))
continue;
const exact = foundByAttributes.title == text || foundByAttributes.alt == text || foundByAttributes.ariaLabel == text;
elements.push({ element: foundByAttributes, exact: exact });
}
const treeWalker = document.createTreeWalker(
container,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT_FRAGMENT | NodeFilter.SHOW_TEXT,
{
acceptNode: node => {
if (
node instanceof HTMLStyleElement ||
node instanceof HTMLLinkElement ||
node instanceof HTMLScriptElement
)
return NodeFilter.FILTER_REJECT;
if (
node instanceof HTMLElement && (
node.getAttribute('aria-hidden') === 'true' || getComputedStyle(node).display === 'none'
)
)
return NodeFilter.FILTER_REJECT;
return NodeFilter.FILTER_ACCEPT;
}
},
);
let currentNode;
while (currentNode = treeWalker.nextNode()) {
if (currentNode instanceof Text) {
if (currentNode.textContent.includes(text)) {
elements.push({ element: currentNode.parentElement, exact: currentNode.textContent.trim() == text });
}
continue;
}
const labelledBy = currentNode.getAttribute('aria-labelledby');
const labelElement = labelledBy && container.querySelector(`#${labelledBy}`);
if (labelElement && labelElement.innerText && labelElement.innerText.includes(text)) {
elements.push({ element: currentNode, exact: labelElement.innerText.trim() == text });
continue;
}
if (currentNode.shadowRoot) {
for (const childNode of currentNode.shadowRoot.childNodes) {
if (
!(childNode instanceof HTMLElement) || (
childNode instanceof HTMLStyleElement ||
childNode instanceof HTMLLinkElement ||
childNode instanceof HTMLScriptElement
)
) {
continue;
}
if (childNode.matches(attributesSelector)) {
const exact = childNode.title == text || childNode.alt == text || childNode.ariaLabel == text;
elements.push({ element: childNode, exact: exact});
continue;
}
elements.push(...findElementsBasedOnTextWithinWithExact(childNode, text));
}
}
}
return elements;
};
/**
* Finds elements within a given container.
*
* @param {HTMLElement} container Parent element to search the element within.
* @param {string} text Text to look for.
* @return {HTMLElement[]} Elements containing the given text.
*/
const findElementsBasedOnTextWithin = (container, text) => {
const elements = findElementsBasedOnTextWithinWithExact(container, text);
// Give more relevance to exact matches.
elements.sort((a, b) => {
return b.exact - a.exact;
});
return elements.map(element => element.element);
};
/**
* Given a list of elements, get the top ancestors among all of them.
*
* This will remote duplicates and drop any elements nested within each other.
*
* @param {Array} elements Elements list.
* @return {Array} Top ancestors.
*/
const getTopAncestors = function(elements) {
const uniqueElements = new Set(elements);
for (const element of uniqueElements) {
for (otherElement of uniqueElements) {
if (otherElement === element) {
continue;
}
if (element.contains(otherElement)) {
uniqueElements.delete(otherElement);
}
}
}
return Array.from(uniqueElements);
};
/**
* Get parent element, including Shadow DOM parents.
*
* @param {HTMLElement} element Element.
* @return {HTMLElement} Parent element.
*/
const getParentElement = function(element) {
return element.parentElement || (element.getRootNode() && element.getRootNode().host) || null;
};
/**
* Get closest element matching a selector, without traversing up a given container.
*
* @param {HTMLElement} element Element.
* @param {string} selector Selector.
* @param {HTMLElement} container Topmost container to search within.
* @return {HTMLElement} Closest matching element.
*/
const getClosestMatching = function(element, selector, container) {
if (element.matches(selector)) {
return element;
}
if (element === container || !element.parentElement) {
return null;
}
return getClosestMatching(element.parentElement, selector, container);
};
/**
* Function to find top container element.
*
* @param {string} containerName Whether to search inside the a container name.
* @return {HTMLElement} Found top container element.
*/
const getCurrentTopContainerElement = function (containerName) {
let topContainer;
let containers;
switch (containerName) {
case 'html':
containers = document.querySelectorAll('html');
break;
case 'toast':
containers = document.querySelectorAll('ion-app ion-toast.hydrated');
containers = Array.from(containers).map(container => container.shadowRoot.querySelector('.toast-container'));
break;
case 'alert':
containers = document.querySelectorAll('ion-app ion-alert.hydrated');
break;
case 'action-sheet':
containers = document.querySelectorAll('ion-app ion-action-sheet.hydrated');
break;
case 'modal':
containers = document.querySelectorAll('ion-app ion-modal.hydrated');
break;
case 'popover':
containers = document.querySelectorAll('ion-app ion-popover.hydrated');
break;
case 'user-tour':
containers = document.querySelectorAll('core-user-tours-user-tour.is-active');
break;
default:
// Other containerName or not implemented.
const containerSelector = 'ion-alert, ion-popover, ion-action-sheet, ion-modal, core-user-tours-user-tour.is-active, page-core-mainmenu, ion-app';
containers = document.querySelectorAll(containerSelector);
}
if (containers.length > 0) {
// Get the one with more zIndex.
topContainer = Array.from(containers).reduce((a, b) => {
return getComputedStyle(a).zIndex > getComputedStyle(b).zIndex ? a : b;
}, containers[0]);
}
if (containerName == 'page' || containerName == 'split-view content') {
// Find non hidden pages inside the container.
let pageContainers = topContainer.querySelectorAll('.ion-page:not(.ion-page-hidden)');
pageContainers = Array.from(pageContainers).filter((page) => {
return !page.closest('.ion-page.ion-page-hidden');
});
if (pageContainers.length > 0) {
// Get the more general one to avoid failing.
topContainer = pageContainers[0];
}
if (containerName == 'split-view content') {
topContainer = topContainer.querySelector('core-split-view ion-router-outlet');
}
}
return topContainer;
}
/**
* Function to find elements based on their text or Aria label.
*
* @param {object} locator Element locator.
* @param {string} containerName Whether to search only inside a specific container.
* @return {HTMLElement} Found elements
*/
const findElementsBasedOnText = function(locator, containerName) {
let topContainer = getCurrentTopContainerElement(containerName);
let container = topContainer;
if (locator.within) {
const withinElements = findElementsBasedOnText(locator.within);
if (withinElements.length === 0) {
throw new Error('There was no match for within text')
} else if (withinElements.length > 1) {
const withinElementsAncestors = getTopAncestors(withinElements);
if (withinElementsAncestors.length > 1) {
throw new Error('Too many matches for within text');
}
topContainer = container = withinElementsAncestors[0];
} else {
topContainer = container = withinElements[0];
}
}
if (topContainer && locator.near) {
const nearElements = findElementsBasedOnText(locator.near);
if (nearElements.length === 0) {
throw new Error('There was no match for near text')
} else if (nearElements.length > 1) {
const nearElementsAncestors = getTopAncestors(nearElements);
if (nearElementsAncestors.length > 1) {
throw new Error('Too many matches for near text');
}
container = getParentElement(nearElementsAncestors[0]);
} else {
container = getParentElement(nearElements[0]);
}
}
do {
const elements = findElementsBasedOnTextWithin(container, locator.text);
const filteredElements = locator.selector
? elements.map(element => getClosestMatching(element, locator.selector, container)).filter(element => !!element)
: elements;
if (filteredElements.length > 0) {
return filteredElements;
}
} while (container !== topContainer && (container = getParentElement(container)) && container !== topContainer);
return [];
};
/**
* Make sure that an element is visible and wait to trigger the callback.
*
* @param {HTMLElement} element Element.
* @param {Function} callback Callback called when the element is visible, passing bounding box parameter.
*/
const ensureElementVisible = function(element, callback) {
const initialRect = element.getBoundingClientRect();
element.scrollIntoView(false);
requestAnimationFrame(function () {
const rect = element.getBoundingClientRect();
if (initialRect.y !== rect.y) {
setTimeout(function () {
callback(rect);
}, 300);
addPendingDelay();
return;
}
callback(rect);
});
addPendingDelay();
};
/**
* Press an element.
*
* @param {HTMLElement} element Element to press.
*/
const pressElement = function(element) {
ensureElementVisible(element, function(rect) {
// Simulate a mouse click on the button.
const eventOptions = {
clientX: rect.left + rect.width / 2,
clientY: rect.top + rect.height / 2,
bubbles: true,
view: window,
cancelable: true,
};
// Events don't bubble up across Shadow DOM boundaries, and some buttons
// may not work without doing this.
const parentElement = getParentElement(element);
if (parentElement && parentElement.matches('ion-button, ion-back-button')) {
element = parentElement;
}
// There are some buttons in the app that don't respond to click events, for example
// buttons using the core-supress-events directive. That's why we need to send both
// click and mouse events.
element.dispatchEvent(new MouseEvent('mousedown', eventOptions));
setTimeout(() => {
element.dispatchEvent(new MouseEvent('mouseup', eventOptions));
element.click();
}, 300);
// Mark busy until the button click finishes processing.
addPendingDelay();
});
};
/**
* Function to find and click an app standard button.
*
* @param {string} button Type of button to press
* @return {string} OK if successful, or ERROR: followed by message
*/
const behatPressStandard = function(button) {
log('Action - Click standard button: ' + button);
// Find button
let foundButton = null;
switch (button) {
case 'back':
foundButton = findElementsBasedOnText({ text: 'Back' })[0];
break;
case 'main menu': // Deprecated name.
case 'more menu':
foundButton = findElementsBasedOnText({
text: 'More',
near: { text: 'Messages' },
})[0];
break;
case 'user menu' :
foundButton = findElementsBasedOnText({ text: 'User account' })[0];
break;
case 'page menu':
foundButton = findElementsBasedOnText({ text: 'Display options' })[0];
break;
default:
return 'ERROR: Unsupported standard button type';
}
// Click button
pressElement(foundButton);
return 'OK';
};
/**
* When there is a popup, clicks on the backdrop.
*
* @return {string} OK if successful, or ERROR: followed by message
*/
const behatClosePopup = function() {
log('Action - Close popup');
let backdrops = Array.from(document.querySelectorAll('ion-backdrop'));
backdrops = backdrops.filter(function(backdrop) {
return !!backdrop.offsetParent;
});
if (!backdrops.length) {
return 'ERROR: Could not find backdrop';
}
if (backdrops.length > 1) {
return 'ERROR: Found too many backdrops';
}
const backdrop = backdrops[0];
backdrop.click();
// Mark busy until the click finishes processing.
addPendingDelay();
return 'OK';
};
/**
* Function to find an arbitrary element based on its text or aria label.
*
* @param {object} locator Element locator.
* @param {string} containerName Whether to search only inside a specific container content.
* @return {string} OK if successful, or ERROR: followed by message
*/
const behatFind = function(locator, containerName) {
log('Action - Find', { locator, containerName });
try {
const element = findElementsBasedOnText(locator, containerName)[0];
if (!element) {
return 'ERROR: No matches for text';
}
log('Action - Found', { locator, containerName, element });
return 'OK';
} catch (error) {
return 'ERROR: ' + error.message;
}
};
/**
* Scroll an element into view.
*
* @param {object} locator Element locator.
* @return {string} OK if successful, or ERROR: followed by message
*/
const behatScrollTo = function(locator) {
log('Action - scrollTo', { locator });
try {
let element = findElementsBasedOnText(locator)[0];
if (!element) {
return 'ERROR: No matches for text';
}
element = element.closest('ion-item') ?? element.closest('button') ?? element;
element.scrollIntoView();
log('Action - Scrolled to', { locator, element });
return 'OK';
} catch (error) {
return 'ERROR: ' + error.message;
}
}
/**
* Load more items form an active list with infinite loader.
*
* @return {string} OK if successful, or ERROR: followed by message
*/
const behatLoadMoreItems = async function() {
log('Action - loadMoreItems');
try {
const infiniteLoading = Array
.from(document.querySelectorAll('core-infinite-loading'))
.find(element => !element.closest('.ion-page-hidden'));
if (!infiniteLoading) {
return 'ERROR: There isn\'t an infinite loader in the current page';
}
const initialOffset = infiniteLoading.offsetTop;
const isLoading = () => !!infiniteLoading.querySelector('ion-spinner[aria-label]');
const isCompleted = () => !isLoading() && !infiniteLoading.querySelector('ion-button');
const hasMoved = () => infiniteLoading.offsetTop !== initialOffset;
if (isCompleted()) {
return 'ERROR: All items are already loaded';
}
infiniteLoading.scrollIntoView({ behavior: 'smooth' });
// Wait 100ms
await new Promise(resolve => setTimeout(resolve, 100));
if (isLoading() || isCompleted() || hasMoved()) {
return 'OK';
}
infiniteLoading.querySelector('ion-button').click();
// Wait 100ms
await new Promise(resolve => setTimeout(resolve, 100));
return (isLoading() || isCompleted() || hasMoved()) ? 'OK' : 'ERROR: Couldn\'t load more items';
} catch (error) {
return 'ERROR: ' + error.message;
}
}
/**
* Check whether an item is selected or not.
*
* @param {object} locator Element locator.
* @return {string} YES or NO if successful, or ERROR: followed by message
*/
const behatIsSelected = function(locator) {
log('Action - Is Selected', locator);
try {
const element = findElementsBasedOnText(locator)[0];
return isElementSelected(element, document.body) ? 'YES' : 'NO';
} catch (error) {
return 'ERROR: ' + error.message;
}
}
/**
* Function to press arbitrary item based on its text or Aria label.
*
* @param {object} locator Element locator.
* @return {string} OK if successful, or ERROR: followed by message
*/
const behatPress = function(locator) {
log('Action - Press', locator);
let found;
try {
found = findElementsBasedOnText(locator)[0];
if (!found) {
return 'ERROR: No matches for text';
}
} catch (error) {
return 'ERROR: ' + error.message;
}
pressElement(found);
return 'OK';
};
/**
* Gets the currently displayed page header.
*
* @return {string} OK: followed by header text if successful, or ERROR: followed by message.
*/
const behatGetHeader = function() {
log('Action - Get header');
let titles = Array.from(document.querySelectorAll('.ion-page:not(.ion-page-hidden) > ion-header h1'));
titles = titles.filter(function(title) {
return isElementVisible(title, document.body);
});
if (titles.length > 1) {
return 'ERROR: Too many possible titles';
} else if (!titles.length) {
return 'ERROR: No title found';
} else {
const title = titles[0].innerText.trim();
return 'OK:' + title;
}
};
/**
* Sets the text of a field to the specified value.
*
* This currently matches fields only based on the placeholder attribute.
*
* @param {string} field Field name
* @param {string} value New value
* @return {string} OK or ERROR: followed by message
*/
const behatSetField = function(field, value) {
log('Action - Set field ' + field + ' to: ' + value);
const found = findElementsBasedOnText({ text: field, selector: 'input, textarea, [contenteditable="true"]' })[0];
if (!found) {
return 'ERROR: No matches for text';
}
// Functions to get/set value depending on field type.
let setValue;
let getValue;
switch (found.nodeName) {
case 'INPUT':
case 'TEXTAREA':
setValue = function(text) {
found.value = text;
};
getValue = function() {
return found.value;
};
break;
case 'DIV':
setValue = function(text) {
found.innerHTML = text;
};
getValue = function() {
return found.innerHTML;
};
break;
}
// Pretend we have cut and pasted the new text.
let event;
if (getValue() !== '') {
event = new InputEvent('input', {bubbles: true, view: window, cancelable: true,
inputType: 'devareByCut'});
setTimeout(function() {
setValue('');
found.dispatchEvent(event);
}, 0);
}
if (value !== '') {
event = new InputEvent('input', {bubbles: true, view: window, cancelable: true,
inputType: 'insertFromPaste', data: value});
setTimeout(function() {
setValue(value);
found.dispatchEvent(event);
}, 0);
}
return 'OK';
};
/**
* Get an Angular component instance.
*
* @param {string} selector Element selector
* @param {string} className Constructor class name
* @return {object} Component instance
*/
const behatGetAngularInstance = function(selector, className) {
log('Action - Get Angular instance ' + selector + ', ' + className);
const activeElement = Array.from(document.querySelectorAll(`.ion-page:not(.ion-page-hidden) ${selector}`)).pop();
if (!activeElement || !activeElement.__ngContext__) {
return null;
}
return activeElement.__ngContext__.find(node => node?.constructor?.name === className);
};
// Make some functions publicly available for Behat to call.
window.behat = {
pressStandard : behatPressStandard,
closePopup : behatClosePopup,
find : behatFind,
scrollTo : behatScrollTo,
loadMoreItems: behatLoadMoreItems,
isSelected : behatIsSelected,
press : behatPress,
setField : behatSetField,
getHeader : behatGetHeader,
getAngularInstance: behatGetAngularInstance,
};
})();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
@app @javascript
Feature: Main Menu opens the right page
Background:
Given the following "users" exist:
| username |
| student |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student | C1 | student |
Scenario: Opens Site Home when defaulthomepage is set to Site
Given the following config values are set as admin:
| defaulthomepage | 0 |
When I enter the app
And I log in as "student"
Then "Site home" should be selected in the app
And I should find "Available courses" in the app
And "Site home" "text" should appear before "Dashboard" "text" in the ".core-tabs-bar" "css_element"
And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element"
Scenario: Opens Dashboard when defaulthomepage is set to Dashboard
Given the following config values are set as admin:
| defaulthomepage | 1 |
When I enter the app
And I log in as "student"
Then "Dashboard" should be selected in the app
And I should find "Timeline" in the app
And "Dashboard" "text" should appear before "Site home" "text" in the ".core-tabs-bar" "css_element"
And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element"
Scenario: Opens My Courses when defaulthomepage is set to My Courses
Given the following config values are set as admin:
| defaulthomepage | 3 |
When I enter the app
And I log in as "student"
Then "My courses" near "Home" should be selected in the app
And I should find "Course 1" in the app
And "My courses" "text" should appear before "Home" "text" in the ".mainmenu-tabs" "css_element"

View File

@ -0,0 +1,30 @@
@app @javascript
Feature: It navigates properly within activities.
Background:
Given the following "users" exist:
| username |
| student |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student | C1 | student |
And the following "activities" exist:
| activity | idnumber | course | name | intro | content |
| label | label | C1 | Label | Label description | - |
| page | page | C1 | Page | - | <a href="/mod/label/view.php?id=${label:cmid}">Go to label</a> |
And I replace the arguments in "page" "content"
Scenario: Navigates using deep links
When I enter the course "Course 1" as "student" in the app
And I press "Page" in the app
And I press "Go to label" in the app
Then I should find "Label description" in the app
When I press the back button in the app
Then I should find "Go to label" in the app
When I press the back button in the app
Then I should find "Label description" in the app

View File

@ -0,0 +1,86 @@
@app @javascript
Feature: It navigates properly using deep links.
Background:
Given the following "users" exist:
| username |
| student1 |
| student2 |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| forum | Test forum | Test forum | C1 | forum |
And the following forum discussions exist in course "Course 1":
| forum | user | name | message |
| Test forum | student1 | Forum topic | Forum message |
And the following config values are set as admin:
| forcelogout | 1 | tool_mobile |
| defaulthomepage | 0 | |
Scenario: Receive a push notification
When I enter the app
And I log in as "student2"
And I press the user menu button in the app
And I press "Log out" in the app
And I wait the app to restart
And I press "Add" in the app
And I set the field "Your site" to "$WWWROOT" in the app
And I press "Connect to your site" in the app
And I log in as "student1"
And I receive a push notification in the app for:
| username | module | discussion |
| student2 | forum | Forum topic |
And I wait the app to restart
Then I should find "Reconnect" in the app
When I set the field "Password" to "student2" in the app
And I press "Log in" in the app
Then I should find "Forum topic" in the app
And I should find "Forum message" in the app
But I should not find "Site home" in the app
When I press the back button in the app
Then I should find "Site home" in the app
But I should not find "Forum topic" in the app
And I should not find "Forum message" in the app
Scenario: Open a link with a custom URL
When I launch the app
And I open a custom link in the app for:
| discussion |
| Forum topic |
And I log in as "student1"
And I wait loading to finish in the app
Then I should find "Forum topic" in the app
And I should find "Forum message" in the app
But I should not find "Site home" in the app
When I press the back button in the app
Then I should find "Site home" in the app
But I should not find "Forum topic" in the app
And I should not find "Forum message" in the app
Scenario: Open a link with a custom URL that calls WebServices for a logged out site
When I enter the app
And I log in as "student2"
And I press the user menu button in the app
And I press "Log out" in the app
And I wait the app to restart
And I open a custom link in the app for:
| forum |
| Test forum |
Then I should find "Reconnect" in the app
When I set the field "Password" to "student2" in the app
And I press "Log in" in the app
Then I should find "Test forum" in the app
When I press the back button in the app
Then I should find "Site home" in the app
But I should not find "Test forum" in the app

View File

@ -0,0 +1,47 @@
@app @javascript
Feature: It opens external links properly.
Background:
Given the following "users" exist:
| username |
| student1 |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| forum | Test forum | Test forum | C1 | forum |
And the following forum discussions exist in course "Course 1":
| forum | user | name | message |
| Test forum | student1 | Forum topic | See <a href="https://moodle.org/">moodle.org external link</a> |
Scenario: Click an external link
When I enter the course "Course 1" as "student1" in the app
And I press "Test forum" in the app
And I press "Forum topic" in the app
And I press "moodle.org external link" in the app
Then I should find "You are about to leave the app" in the app
When I press "Cancel" in the app
And I press "moodle.org external link" in the app
And I press "OK" in the app
Then the app should have opened a browser tab with url "moodle.org"
When I close the browser tab opened by the app
And I press the back button in the app
And I press "Information" in the app
And I press "Open in browser" in the app
Then the app should have opened a browser tab
When I close the browser tab opened by the app
When I close the popup in the app
And I press "Forum topic" in the app
And I press "moodle.org external link" in the app
And I select "Don't show again." in the app
And I press "OK" in the app
And I close the browser tab opened by the app
And I press "moodle.org external link" in the app
Then the app should have opened a browser tab with url "moodle.org"

View File

@ -0,0 +1,59 @@
@app @javascript
Feature: It navigates using gestures.
Background:
Given the following "users" exist:
| username | firstname | lastname |
| student1 | Student | First |
| teacher1 | Teacher | First |
| student2 | Student | Second |
| teacher2 | Teacher | Second |
| student3 | Student | Third |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | teacher |
| student2 | C1 | student |
| teacher2 | C1 | teacher |
| student3 | C1 | student |
Scenario: Swipe between participants
When I enter the course "Course 1" as "student1" in the app
And I press "Participants" in the app
And I press "Student First" in the app
And I swipe to the left in the app
Then I should find "Teacher First" in the app
When I swipe to the left in the app
Then I should find "Student Second" in the app
When I swipe to the right in the app
Then I should find "Teacher First" in the app
When I swipe to the right in the app
Then I should find "Student First" in the app
When I swipe to the right in the app
Then I should find "Student First" in the app
Scenario: Swipe between filtered participants
When I enter the course "Course 1" as "student1" in the app
And I press "Participants" in the app
And I press "Search" in the app
And I set the field "Search" to "student" in the app
And I press "Search" "button" near "Clear search" in the app
And I press "Student First" in the app
And I swipe to the left in the app
Then I should find "Student Second" in the app
When I swipe to the left in the app
Then I should find "Student Third" in the app
When I swipe to the right in the app
Then I should find "Student Second" in the app
When I swipe to the right in the app
Then I should find "Student First" in the app

View File

@ -0,0 +1,111 @@
@app @javascript
Feature: It navigates properly in pages with a split-view component.
Background:
Given the following "users" exist:
| username |
| student1 |
And the following "courses" exist:
| fullname | shortname |
| Course 2 | C2 |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
And the following "grade categories" exist:
| fullname | course |
| Grade category C1 | C1 |
| Grade category C2 | C2 |
And the following "grade items" exist:
| gradecategory | itemname | grademin | grademax | course |
| Grade category C1 | Grade item C1 | 20 | 40 | C1 |
| Grade category C2 | Grade item C2 | 60 | 80 | C2 |
Scenario: Navigate in grades tab on mobile
# Open user menu
Given I enter the app
And I log in as "student1"
And I press the user menu button in the app
# Open grades page
When I press "Grades" in the app
Then the header should be "Grades" in the app
And I should find "Course 1" in the app
And I should find "Course 2" in the app
# Open C1 course grades
When I press "Course 1" in the app
Then the header should be "Course 1" in the app
And I should find "Grade category C1" in the app
# Open C1 grade item
When I press "Grade item C1" in the app
Then I should find "20" near "Range" in the app
And I should find "40" near "Range" in the app
# Go back to grades page
When I press the back button in the app
Then the header should be "Grades" in the app
And I should find "Course 1" in the app
And I should find "Course 2" in the app
# Open C2 course grades
When I press "Course 2" in the app
Then the header should be "Course 2" in the app
And I should find "Grade category C2" in the app
# Open C2 grade item
When I press "Grade item C2" in the app
Then I should find "60" near "Range" in the app
And I should find "80" near "Range" in the app
# Go back to grades page
When I press the back button in the app
Then the header should be "Grades" in the app
And I should find "Course 1" in the app
And I should find "Course 2" in the app
# Go back to main page
When I press the back button in the app
Then I should find "Acceptance test site" in the app
And I should find "User account" in the app
But I should not find "Back" in the app
Scenario: Navigate in grades tab on tablet
# Open user menu
Given I enter the app
And I change viewport size to "1200x640"
And I log in as "student1"
And I press the user menu button in the app
# Open grades page
When I press "Grades" in the app
Then the header should be "Grades" in the app
And I should find "Course 1" in the app
And I should find "Course 2" in the app
And I should find "Grade category C1" in the app
# Open C1 course grades
When I press "Grade item C1" in the app
Then I should find "Grade category C1" in the app
And I should find "20" near "Range" in the app
And I should find "40" near "Range" in the app
# Select C2 course
When I press "Course 2" in the app
Then "Course 2" should be selected in the app
And I should find "Grade category C2" in the app
# Open C2 course grades
When I press "Grade item C2" in the app
Then I should find "60" near "Range" in the app
And I should find "80" near "Range" in the app
# Go back to main page
When I press the back button in the app
Then I should find "Acceptance test site" in the app
And I should find "User account" in the app
But I should not find "Back" in the app

View File

@ -0,0 +1,16 @@
@app @javascript
Feature: Plugins work properly.
Background:
Given the following "users" exist:
| username |
| studentusername |
Scenario: See more menu button
When I enter the app
And I log in as "studentusername"
And I press the more menu button in the app
Then I should find "Moodle Mobile language strings" in the app
When I press "Moodle Mobile language strings" in the app
Then I should find "studentusername" in the app

View File

@ -0,0 +1,82 @@
@app @javascript
Feature: It navigates properly within settings.
Background:
Given the following "users" exist:
| username |
| student1 |
Scenario: Mobile navigation
Given I enter the app
And I log in as "student1"
# Settings
When I press "More" in the app
And I press "App settings" in the app
Then I should find "General" in the app
And I should find "Space usage" in the app
And I should find "Synchronisation" in the app
And I should find "About" in the app
# Settings details
When I press "General" in the app
Then I should find "Language" in the app
And I should find "Text size" in the app
When I press the back button in the app
And I press "About" in the app
Then I should find "Moodle Mobile" in the app
And I should find "Privacy policy" in the app
# Preferences
When I press the back button in the app
And I press the back button in the app
And I press the user menu button in the app
And I press "Preferences" in the app
Then I should find "Messages" in the app
And I should find "Notifications" in the app
And I should find "Manage downloads" in the app
# Preferences details
When I press "Messages" in the app
Then I should find "Accept messages from" in the app
And I should find "Notification preferences" in the app
When I press the back button in the app
And I press "Manage downloads" in the app
Then I should find "Total space used" in the app
Scenario: Tablet navigation
Given I enter the app
And I log in as "student1"
And I change viewport size to "1200x640"
# Settings
When I press "More" in the app
And I press "App settings" in the app
Then I should find "General" in the app
And I should find "Space usage" in the app
And I should find "Synchronisation" in the app
And I should find "About" in the app
And "General" should be selected in the app
And I should find "Language" in the app
And I should find "Text size" in the app
When I press "About" in the app
Then "About" should be selected in the app
And I should find "Moodle Mobile" in the app
And I should find "Privacy policy" in the app
# Preferences
When I press the user menu button in the app
And I press "Preferences" in the app
Then I should find "Messages" in the app
And I should find "Notifications" in the app
And I should find "Manage downloads" in the app
And "Messages" should be selected in the app
And I should find "Accept messages from" in the app
And I should find "Notification preferences" in the app
When I press "Manage downloads" in the app
Then "Manage downloads" should be selected in the app
And I should find "Total space used" in the app

View File

@ -0,0 +1,48 @@
@app @javascript
Feature: User Tours work properly.
Background:
Given the following "users" exist:
| username | firstname | lastname |
| student1 | Student | First |
| student2 | Student | Second |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
And the app has the following config:
| disableUserTours | false |
Scenario: Acknowledge User Tours
When I enter the app
And I log in as "student1"
Then I should find "Explore your personal area" in the app
But I should not find "Expand to explore" in the app
When I press "Got it" in the app
Then I should find "Expand to explore" in the app
But I should not find "Explore your personal area" in the app
When I press "Got it" in the app
Then I should not find "Expand to explore" in the app
And I should not find "Explore your personal area" in the app
When I enter the course "Course 1" in the app
Then I should find "Find your way around" in the app
When I press "Got it" in the app
Then I should not find "Find your way around" in the app
When I press "Participants" in the app
And I press "Student First" in the app
Then I should find "Swipe left and right to navigate around" in the app
When I press "Got it" in the app
Then I should not find "Swipe left and right to navigate around" in the app
When I press the back button in the app
And I press "Student First" in the app
Then I should not find "Swipe left and right to navigate around" in the app