Merge pull request #22 from NoelDeMartin/MOBILE-3320

MOBILE-3320: Update messages, chat & course tests
main
Dani Palou 2021-06-04 08:45:24 +02:00 committed by GitHub
commit 639a045c07
6 changed files with 648 additions and 570 deletions

View File

@ -1,4 +1,4 @@
@mod @mod_chat @app @app_upto3.9.4 @javascript @mod @mod_chat @app @javascript
Feature: Test basic usage of chat in app Feature: Test basic usage of chat in app
As a student As a student
I need basic chat functionality to work I need basic chat functionality to work
@ -19,23 +19,24 @@ Feature: Test basic usage of chat in app
| activity | name | intro | course | idnumber | groupmode | | activity | name | intro | course | idnumber | groupmode |
| chat | Test chat name | Test chat | C1 | chat | 0 | | chat | Test chat name | Test chat | C1 | chat | 0 |
@app @3.8.0
Scenario: Receive and send messages & See connected users, beep and talk to Scenario: Receive and send messages & See connected users, beep and talk to
# Send messages as student1 # Send messages as student1
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Course 1" near "Course overview" in the app And I press "Course 1" near "Course overview" in the app
And I press "Test chat name" in the app And I press "Test chat name" in the app
Then I should see "Click here to enter the chat now" Then I should find "Click here to enter the chat now" in the app
And I should see "View past chat sessions" And I should find "View past chat sessions" in the app
When I press "Click here to enter the chat now" in the app When I press "Click here to enter the chat now" in the app
And I set the field "New message" to "Hi!" And I set the field "New message" to "Hi!" in the app
And I press "Send" in the app And I press "Send" in the app
And I set the field "New message" to "I am David" 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 And I press "Send" in the app
Then I should see "Hi!" Then I should find "Hi!" in the app
And I should see "I am David" And I should find "I am David" in the app
# Read messages, view connected users, send beep and reply as student2 # Read messages, view connected users, send beep and reply as student2
When I enter the app When I enter the app
@ -43,20 +44,19 @@ Feature: Test basic usage of chat in app
And I press "Course 1" near "Course overview" in the app And I press "Course 1" near "Course overview" in the app
And I press "Test chat name" in the app And I press "Test chat name" in the app
And I press "Click here to enter the chat now" in the app And I press "Click here to enter the chat now" in the app
Then I should see "Hi!" Then I should find "Hi!" in the app
And I should see "I am David" And I should find "I am David" in the app
When I press "people" in the app When I press "Users" in the app
Then I should see "david student" Then I should find "david student" in the app
When I press "Beep" in the app When I press "Beep" in the app
Then I should see "You beeped david student" Then I should find "You beeped david student" in the app
When I set the field "New message" to "Hi David, I am Pau." When I set the field "New message" to "Hi David, I am Pau." in the app
And I press "Send" in the app And I press "Send" in the app
Then I should see "Hi David, I am Pau." Then I should find "Hi David, I am Pau." in the app
@app @3.8.0
Scenario: Past sessions shown for >=3.5 Scenario: Past sessions shown for >=3.5
# Send messages as student1 # Send messages as student1
Given I enter the app Given I enter the app
@ -64,10 +64,13 @@ Feature: Test basic usage of chat in app
And I press "Course 1" near "Course overview" in the app And I press "Course 1" near "Course overview" in the app
And I press "Test chat name" in the app And I press "Test chat name" in the app
And I press "Click here to enter the chat now" in the app And I press "Click here to enter the chat now" in the app
And I set the field "New message" to "Hi!" And I set the field "New message" to "Hi!" in the app
And I press "Send" in the app And I press "Send" in the app
And I set the field "New message" to "I am David" 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 And I press "Send" in the app
Then I should find "I am David" in the app
# Read messages from past sessions as student2 # Read messages from past sessions as student2
When I enter the app When I enter the app
@ -76,6 +79,6 @@ Feature: Test basic usage of chat in app
And I press "Test chat name" in the app And I press "Test chat name" in the app
And I press "View past chat sessions" in the app And I press "View past chat sessions" in the app
And I press "Show incomplete sessions" in the app And I press "Show incomplete sessions" in the app
And I press "david student (2)" in the app And I press "david student" near "(2)" in the app
Then I should see "Hi!" Then I should find "Hi!" in the app
And I should see "I am David" And I should find "I am David" in the app

View File

@ -1,4 +1,4 @@
@mod @mod_course @app @app_upto3.9.4 @javascript @mod @mod_course @app @javascript
Feature: Test basic usage of one course in app Feature: Test basic usage of one course in app
In order to participate in one course while using the mobile app In order to participate in one course while using the mobile app
As a student As a student
@ -71,26 +71,25 @@ Feature: Test basic usage of one course in app
| activity | name | intro | course | idnumber | groupmode | section | | activity | name | intro | course | idnumber | groupmode | section |
| workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 |
@app @3.8.0
Scenario: View course contents Scenario: View course contents
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Course 1" near "Recently accessed courses" in the app And I press "Course 1" near "Recently accessed courses" in the app
Then the header should be "Course 1" in the app Then the header should be "Course 1" in the app
And I should see "Choice course 1" And I should find "Choice course 1" in the app
And I should see "assignment" And I should find "assignment" in the app
And I should see "Test forum name" And I should find "Test forum name" in the app
And I should see "Test chat name" And I should find "Test chat name" in the app
And I should see "Web links" And I should find "Web links" in the app
And I should see "Test external name" And I should find "Test external name" in the app
And I should see "Test feedback name" And I should find "Test feedback name" in the app
And I should see "Test glossary" And I should find "Test glossary" in the app
And I should see "Quiz 1" And I should find "Quiz 1" in the app
And I should see "Test survey name" And I should find "Test survey name" in the app
And I should see "Test wiki name" And I should find "Test wiki name" in the app
And I should see "Test lesson name" And I should find "Test lesson name" in the app
And I should see "Test scorm name" And I should find "Test scorm name" in the app
And I should see "Test workshop name" And I should find "Test workshop name" in the app
When I press "Choice course 1" in the app When I press "Choice course 1" in the app
Then the header should be "Choice course 1" in the app Then the header should be "Choice course 1" in the app
@ -149,43 +148,42 @@ Feature: Test basic usage of one course in app
And I press "Test workshop name" in the app And I press "Test workshop name" in the app
Then the header should be "Test workshop name" in the app Then the header should be "Test workshop name" in the app
@app @3.8.0
Scenario: View section contents Scenario: View section contents
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Course 1" near "Recently accessed courses" in the app And I press "Course 1" near "Recently accessed courses" in the app
Then the header should be "Course 1" in the app Then the header should be "Course 1" in the app
And I should see "Choice course 1" And I should find "Choice course 1" in the app
And I should see "assignment" And I should find "assignment" in the app
And I should see "Test forum name" And I should find "Test forum name" in the app
And I should see "Test chat name" And I should find "Test chat name" in the app
And I should see "Web links" And I should find "Web links" in the app
And I should see "Test external name" And I should find "Test external name" in the app
And I should see "Test feedback name" And I should find "Test feedback name" in the app
And I should see "Test glossary" And I should find "Test glossary" in the app
And I should see "Quiz 1" And I should find "Quiz 1" in the app
And I should see "Test survey name" And I should find "Test survey name" in the app
And I should see "Test wiki name" And I should find "Test wiki name" in the app
And I should see "Test lesson name" And I should find "Test lesson name" in the app
And I should see "Test scorm name" And I should find "Test scorm name" in the app
And I should see "Test workshop name" And I should find "Test workshop name" in the app
When I press "arrow dropdown" in the app When I press "Section:" in the app
And I press "General" near "Sections" in the app And I press "General" near "Sections" "h2" in the app
Then I should see "Test forum name" Then I should find "Test forum name" in the app
And I should see "Test wiki name" And I should find "Test wiki name" in the app
But I should not see "Choice course 1" But I should not find "Choice course 1" in the app
And I should not see "assignment" And I should not find "assignment" in the app
And I should not see "Test chat name" And I should not find "Test chat name" in the app
And I should not see "Web links" And I should not find "Web links" in the app
And I should not see "Test external name" And I should not find "Test external name" in the app
And I should not see "Test feedback name" And I should not find "Test feedback name" in the app
And I should not see "Test glossary" And I should not find "Test glossary" in the app
And I should not see "Quiz 1" And I should not find "Quiz 1" in the app
And I should not see "Test survey name" And I should not find "Test survey name" in the app
And I should not see "Test lesson name" And I should not find "Test lesson name" in the app
And I should not see "Test scorm name" And I should not find "Test scorm name" in the app
And I should not see "Test workshop name" And I should not find "Test workshop name" in the app
When I press "Test forum name" in the app When I press "Test forum name" in the app
Then the header should be "Test forum name" in the app Then the header should be "Test forum name" in the app
@ -196,22 +194,22 @@ Feature: Test basic usage of one course in app
Then the header should be "Test wiki name" in the app Then the header should be "Test wiki name" in the app
When I press the back button in the app When I press the back button in the app
And I press "arrow dropdown" in the app And I press "Section:" in the app
And I press "Topic 1" near "Sections" in the app And I press "Topic 1" near "Sections" "h2" in the app
Then I should see "Choice course 1" Then I should find "Choice course 1" in the app
And I should see "assignment" And I should find "assignment" in the app
And I should see "Test external name" And I should find "Test external name" in the app
And I should see "Test survey name" And I should find "Test survey name" in the app
But I should not see "Test forum name" But I should not find "Test forum name" in the app
And I should not see "Test chat name" And I should not find "Test chat name" in the app
And I should not see "Web links" And I should not find "Web links" in the app
And I should not see "Test feedback name" And I should not find "Test feedback name" in the app
And I should not see "Test glossary" And I should not find "Test glossary" in the app
And I should not see "Quiz 1" And I should not find "Quiz 1" in the app
And I should not see "Test wiki name" And I should not find "Test wiki name" in the app
And I should not see "Test lesson name" And I should not find "Test lesson name" in the app
And I should not see "Test scorm name" And I should not find "Test scorm name" in the app
And I should not see "Test workshop name" And I should not find "Test workshop name" in the app
When I press "Choice course 1" in the app When I press "Choice course 1" in the app
Then the header should be "Choice course 1" in the app Then the header should be "Choice course 1" in the app
@ -229,22 +227,22 @@ Feature: Test basic usage of one course in app
Then the header should be "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 When I press the back button in the app
And I press "arrow dropdown" in the app And I press "Section:" in the app
And I press "Topic 2" near "Sections" in the app And I press "Topic 2" near "Sections" "h2" in the app
Then I should see "Quiz 1" Then I should find "Quiz 1" in the app
And I should see "Test chat name" And I should find "Test chat name" in the app
And I should see "Test scorm name" And I should find "Test scorm name" in the app
But I should not see "Choice course 1" But I should not find "Choice course 1" in the app
And I should not see "assignment" And I should not find "assignment" in the app
And I should not see "Test forum name" And I should not find "Test forum name" in the app
And I should not see "Web links" And I should not find "Web links" in the app
And I should not see "Test external name" And I should not find "Test external name" in the app
And I should not see "Test feedback name" And I should not find "Test feedback name" in the app
And I should not see "Test glossary" And I should not find "Test glossary" in the app
And I should not see "Test survey name" And I should not find "Test survey name" in the app
And I should not see "Test wiki name" And I should not find "Test wiki name" in the app
And I should not see "Test lesson name" And I should not find "Test lesson name" in the app
And I should not see "Test workshop name" And I should not find "Test workshop name" in the app
When I press "Test chat name" in the app When I press "Test chat name" in the app
Then the header should be "Test chat name" in the app Then the header should be "Test chat name" in the app
@ -258,22 +256,22 @@ Feature: Test basic usage of one course in app
Then the header should be "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 When I press the back button in the app
And I press "arrow dropdown" in the app And I press "Section:" in the app
And I press "Topic 3" near "Sections" in the app And I press "Topic 3" near "Sections" "h2" in the app
Then I should see "Test feedback name" Then I should find "Test feedback name" in the app
And I should see "Test lesson name" And I should find "Test lesson name" in the app
And I should see "Test workshop name" And I should find "Test workshop name" in the app
But I should not see "Choice course 1" But I should not find "Choice course 1" in the app
And I should not see "assignment" And I should not find "assignment" in the app
And I should not see "Test forum name" And I should not find "Test forum name" in the app
And I should not see "Test chat name" And I should not find "Test chat name" in the app
And I should not see "Web links" And I should not find "Web links" in the app
And I should not see "Test external name" And I should not find "Test external name" in the app
And I should not see "Test glossary" And I should not find "Test glossary" in the app
And I should not see "Quiz 1" And I should not find "Quiz 1" in the app
And I should not see "Test survey name" And I should not find "Test survey name" in the app
And I should not see "Test wiki name" And I should not find "Test wiki name" in the app
And I should not see "Test scorm name" And I should not find "Test scorm name" in the app
When I press "Test feedback name" in the app When I press "Test feedback name" in the app
And I press "OK" in the app And I press "OK" in the app
@ -288,126 +286,126 @@ Feature: Test basic usage of one course in app
Then the header should be "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 When I press the back button in the app
And I press "arrow dropdown" in the app And I press "Section:" in the app
And I press "Topic 4" near "Sections" in the app And I press "Topic 4" near "Sections" "h2" in the app
Then I should see "Web links" Then I should find "Web links" in the app
But I should not see "Choice course 1" But I should not find "Choice course 1" in the app
And I should not see "assignment" And I should not find "assignment" in the app
And I should not see "Test forum name" And I should not find "Test forum name" in the app
And I should not see "Test chat name" And I should not find "Test chat name" in the app
And I should not see "Test external name" And I should not find "Test external name" in the app
And I should not see "Test feedback name" And I should not find "Test feedback name" in the app
And I should not see "Test glossary" And I should not find "Test glossary" in the app
And I should not see "Quiz 1" And I should not find "Quiz 1" in the app
And I should not see "Test survey name" And I should not find "Test survey name" in the app
And I should not see "Test wiki name" And I should not find "Test wiki name" in the app
And I should not see "Test lesson name" And I should not find "Test lesson name" in the app
And I should not see "Test scorm name" And I should not find "Test scorm name" in the app
And I should not see "Test workshop name" And I should not find "Test workshop name" in the app
When I press "Web links" in the app When I press "Web links" in the app
Then the header should be "Web links" in the app Then the header should be "Web links" in the app
When I press the back button in the app When I press the back button in the app
And I press "arrow dropdown" in the app And I press "Section:" in the app
And I press "Topic 5" near "Sections" in the app And I press "Topic 5" near "Sections" "h2" in the app
Then I should see "Test glossary" Then I should find "Test glossary" in the app
But I should not see "Choice course 1" But I should not find "Choice course 1" in the app
And I should not see "assignment" And I should not find "assignment" in the app
And I should not see "Test forum name" And I should not find "Test forum name" in the app
And I should not see "Test chat name" And I should not find "Test chat name" in the app
And I should not see "Web links" And I should not find "Web links" in the app
And I should not see "Test external name" And I should not find "Test external name" in the app
And I should not see "Test feedback name" And I should not find "Test feedback name" in the app
And I should not see "Quiz 1" And I should not find "Quiz 1" in the app
And I should not see "Test survey name" And I should not find "Test survey name" in the app
And I should not see "Test wiki name" And I should not find "Test wiki name" in the app
And I should not see "Test lesson name" And I should not find "Test lesson name" in the app
And I should not see "Test scorm name" And I should not find "Test scorm name" in the app
And I should not see "Test workshop name" And I should not find "Test workshop name" in the app
When I press "Test glossary" in the app When I press "Test glossary" in the app
Then the header should be "Test glossary" in the app Then the header should be "Test glossary" in the app
@app @3.8.0
Scenario: Navigation between sections using the bottom arrows Scenario: Navigation between sections using the bottom arrows
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Course 1" near "Recently accessed courses" in the app And I press "Course 1" near "Recently accessed courses" in the app
Then the header should be "Course 1" in the app Then the header should be "Course 1" in the app
And I should see "Choice course 1" And I should find "Choice course 1" in the app
And I should see "assignment" And I should find "assignment" in the app
And I should see "Test forum name" And I should find "Test forum name" in the app
And I should see "Test chat name" And I should find "Test chat name" in the app
And I should see "Web links" And I should find "Web links" in the app
And I should see "Test external name" And I should find "Test external name" in the app
And I should see "Test feedback name" And I should find "Test feedback name" in the app
And I should see "Test glossary" And I should find "Test glossary" in the app
And I should see "Quiz 1" And I should find "Quiz 1" in the app
And I should see "Test survey name" And I should find "Test survey name" in the app
And I should see "Test wiki name" And I should find "Test wiki name" in the app
And I should see "Test lesson name" And I should find "Test lesson name" in the app
And I should see "Test scorm name" And I should find "Test scorm name" in the app
And I should see "Test workshop name" And I should find "Test workshop name" in the app
When I press "arrow dropdown" in the app When I press "Section:" in the app
And I press "General" near "Sections" in the app And I press "General" near "Sections" "h2" in the app
Then I should see "General" Then I should find "General" in the app
But I should not see "Topic 1" And I should find "Next: Topic 1" in the app
And I should not see "Topic 2" But I should not find "Topic 2" in the app
And I should not see "Topic 3" And I should not find "Topic 3" in the app
And I should not see "Topic 4" And I should not find "Topic 4" in the app
And I should not see "Topic 5" And I should not find "Topic 5" in the app
And I should not find "Previous:" in the app
When I press "arrow forward" near "Test wiki name" in the app When I press "Next:" in the app
Then I should see "Topic 1" Then I should find "Topic 1" in the app
But I should not see "General" And I should find "Previous: General" in the app
And I should not see "Topic 2" And I should find "Next: Topic 2" in the app
And I should not see "Topic 3" But I should not find "Topic 3" in the app
And I should not see "Topic 4" And I should not find "Topic 4" in the app
And I should not see "Topic 5" And I should not find "Topic 5" in the app
When I press "arrow forward" near "Test survey name" in the app When I press "Next:" in the app
Then I should see "Topic 2" Then I should find "Topic 2" in the app
But I should not see "General" And I should find "Previous: Topic 1" in the app
And I should not see "Topic 1" And I should find "Next: Topic 3" in the app
And I should not see "Topic 3" But I should not find "General" in the app
And I should not see "Topic 4" And I should not find "Topic 4" in the app
And I should not see "Topic 5" And I should not find "Topic 5" in the app
When I press "arrow forward" near "Test scorm name" in the app When I press "Next:" in the app
Then I should see "Topic 3" Then I should find "Topic 3" in the app
But I should not see "General" And I should find "Previous: Topic 2" in the app
And I should not see "Topic 1" And I should find "Next: Topic 4" in the app
And I should not see "Topic 2" But I should not find "General" in the app
And I should not see "Topic 4" And I should not find "Topic 1" in the app
And I should not see "Topic 5" And I should not find "Topic 5" in the app
When I press "arrow forward" near "Test workshop name" in the app When I press "Next:" in the app
Then I should see "Topic 4" Then I should find "Topic 4" in the app
But I should not see "General" And I should find "Previous: Topic 3" in the app
And I should not see "Topic 1" And I should find "Next: Topic 5" in the app
And I should not see "Topic 2" But I should not find "General" in the app
And I should not see "Topic 3" And I should not find "Topic 1" in the app
And I should not see "Topic 5" And I should not find "Topic 2" in the app
When I press "arrow forward" near "Web links" in the app When I press "Next:" in the app
Then I should see "Topic 5" Then I should find "Topic 5" in the app
But I should not see "General" And I should find "Previous: Topic 4" in the app
And I should not see "Topic 1" But I should not find "General" in the app
And I should not see "Topic 2" And I should not find "Topic 1" in the app
And I should not see "Topic 3" And I should not find "Topic 2" in the app
And I should not see "Topic 4" And I should not find "Topic 3" in the app
And I should not find "Next:" in the app
When I press "arrow back" near "Test glossary" in the app When I press "Previous:" in the app
Then I should see "Topic 4" Then I should find "Topic 4" in the app
But I should not see "General" And I should find "Previous: Topic 3" in the app
And I should not see "Topic 1" And I should find "Next: Topic 5" in the app
And I should not see "Topic 2" But I should not find "General" in the app
And I should not see "Topic 3" And I should not find "Topic 1" in the app
And I should not see "Topic 5" And I should not find "Topic 2" in the app
@app @3.8.0
Scenario: Self enrol Scenario: Self enrol
Given I enter the app Given I enter the app
And I log in as "teacher1" And I log in as "teacher1"
@ -433,22 +431,21 @@ Feature: Test basic usage of one course in app
And I wait loading to finish in the app And I wait loading to finish in the app
And I press "Contents" in the app And I press "Contents" in the app
Then the header should be "Course 1" in the app Then the header should be "Course 1" in the app
And I should see "Choice course 1" And I should find "Choice course 1" in the app
And I should see "assignment" And I should find "assignment" in the app
And I should see "Test forum name" And I should find "Test forum name" in the app
And I should see "Test chat name" And I should find "Test chat name" in the app
And I should see "Web links" And I should find "Web links" in the app
And I should see "Test external name" And I should find "Test external name" in the app
And I should see "Test feedback name" And I should find "Test feedback name" in the app
And I should see "Test glossary" And I should find "Test glossary" in the app
And I should see "Quiz 1" And I should find "Quiz 1" in the app
And I should see "Test survey name" And I should find "Test survey name" in the app
And I should see "Test wiki name" And I should find "Test wiki name" in the app
And I should see "Test lesson name" And I should find "Test lesson name" in the app
And I should see "Test scorm name" And I should find "Test scorm name" in the app
And I should see "Test workshop name" And I should find "Test workshop name" in the app
@app @3.8.0
Scenario: Guest access Scenario: Guest access
Given I enter the app Given I enter the app
And I log in as "teacher1" And I log in as "teacher1"
@ -469,26 +466,25 @@ Feature: Test basic usage of one course in app
And I press "Site home" in the app And I press "Site home" in the app
And I press "Available courses" in the app And I press "Available courses" in the app
And I press "Course 1" in the app And I press "Course 1" in the app
Then I should see "Download course" Then I should find "Download course" in the app
And I should see "Contents" And I should find "Contents" in the app
When I press "Contents" in the app When I press "Contents" in the app
Then the header should be "Course 1" in the app Then the header should be "Course 1" in the app
And I should see "Choice course 1" And I should find "Choice course 1" in the app
And I should see "assignment" And I should find "assignment" in the app
And I should see "Test forum name" And I should find "Test forum name" in the app
And I should see "Test chat name" And I should find "Test chat name" in the app
And I should see "Web links" And I should find "Web links" in the app
And I should see "Test feedback name" And I should find "Test feedback name" in the app
And I should see "Test glossary" And I should find "Test glossary" in the app
And I should see "Quiz 1" And I should find "Quiz 1" in the app
And I should see "Test survey name" And I should find "Test survey name" in the app
And I should see "Test wiki name" And I should find "Test wiki name" in the app
And I should see "Test lesson name" And I should find "Test lesson name" in the app
And I should see "Test scorm name" And I should find "Test scorm name" in the app
And I should see "Test workshop name" And I should find "Test workshop name" in the app
@app @3.8.0
Scenario: View blocks bellow/beside contents also when All sections selected Scenario: View blocks bellow/beside contents also when All sections selected
Given I enter the app Given I enter the app
And I log in as "teacher1" And I log in as "teacher1"
@ -515,20 +511,20 @@ Feature: Test basic usage of one course in app
And I log in as "student1" And I log in as "student1"
And I press "Course 1" near "Recently accessed courses" in the app And I press "Course 1" near "Recently accessed courses" in the app
Then the header should be "Course 1" in the app Then the header should be "Course 1" in the app
And I should see "Choice course 1" And I should find "Choice course 1" in the app
And I should see "assignment" And I should find "assignment" in the app
And I should see "Test forum name" And I should find "Test forum name" in the app
And I should see "Test chat name" And I should find "Test chat name" in the app
And I should see "Web links" And I should find "Web links" in the app
And I should see "Test external name" And I should find "Test external name" in the app
And I should see "Test feedback name" And I should find "Test feedback name" in the app
And I should see "Test glossary" And I should find "Test glossary" in the app
And I should see "Quiz 1" And I should find "Quiz 1" in the app
And I should see "Test survey name" And I should find "Test survey name" in the app
And I should see "Test wiki name" And I should find "Test wiki name" in the app
And I should see "Test lesson name" And I should find "Test lesson name" in the app
And I should see "Test scorm name" And I should find "Test scorm name" in the app
And I should see "Test workshop name" And I should find "Test workshop name" in the app
And I should see "HTML title test" And I should find "HTML title test" in the app
And I should see "body test" And I should find "body test" in the app
And I should see "Activities" And I should find "Activities" in the app

View File

@ -1,4 +1,4 @@
@core @core_course @app @app_upto3.9.4 @javascript @core @core_course @app @javascript
Feature: Check course completion feature. Feature: Check course completion feature.
In order to track the progress of the course on mobile device In order to track the progress of the course on mobile device
As a student As a student
@ -24,13 +24,13 @@ Feature: Check course completion feature.
And I log in as "student1" And I log in as "student1"
And I press "Course 1" near "Recently accessed courses" in the app And I press "Course 1" near "Recently accessed courses" in the app
# Set activities as completed. # Set activities as completed.
And I should see "0%" And I should find "0%" in the app
And I press "Not completed: First forum. Select to mark as complete." in the app And I press "Mark First forum as done" in the app
And I should see "50%" And I should find "50%" in the app
And I press "Not completed: Second forum. Select to mark as complete." in the app And I press "Mark Second forum as done" in the app
And I should see "100%" And I should find "100%" in the app
# Set activities as not completed. # Set activities as not completed.
And I press "Completed: First forum. Select to mark as not complete." in the app And I press "First forum is marked as done. Press to undo." in the app
And I should see "50%" And I should find "50%" in the app
And I press "Completed: Second forum. Select to mark as not complete." in the app And I press "Second forum is marked as done. Press to undo." in the app
And I should see "0%" And I should find "0%" in the app

View File

@ -1,4 +1,4 @@
@mod @mod_messages @app @app_upto3.9.4 @javascript @mod @mod_messages @app @javascript
Feature: Test basic usage of messages in app Feature: Test basic usage of messages in app
In order to participate with messages while using the mobile app In order to participate with messages while using the mobile app
As a student As a student
@ -19,23 +19,23 @@ Feature: Test basic usage of messages in app
| student1 | C1 | student | | student1 | C1 | student |
| student2 | C1 | student | | student2 | C1 | student |
@app @3.8.0
Scenario: View recent conversations and contacts Scenario: View recent conversations and contacts
When I enter the app When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Contacts" in the app And I press "Contacts" in the app
Then I should see "No contacts" Then I should find "No contacts" in the app
When I press "addon.messages.search" 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 set the field "Search" to "student" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" 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 set the field "New message" to "heeey student" in the app
And I press "Send" in the app And I press "Send" in the app
And I press "Conversation actions menu" in the app And I press "Display options" in the app
And I press "Add to contacts" in the app And I press "Add to contacts" in the app
And I press "Add" 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 When I enter the app
And I log in as "student1" And I log in as "student1"
@ -44,86 +44,91 @@ Feature: Test basic usage of messages in app
And I press "Requests" in the app And I press "Requests" in the app
And I press "Teacher teacher" in the app And I press "Teacher teacher" in the app
And I press "Accept and add to contacts" in the app And I press "Accept and add to contacts" in the app
And I press the back button in the app Then I should not find "Teacher teacher would like to contact you" in the app
And I press "Contacts" near "Requests" 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 Then the header should be "Contacts" in the app
And I should see "Teacher teacher" And I should find "Teacher teacher" in the app
When I press the back button in the app When I press the back button in the app
And I press "Teacher teacher" in the app And I press "Teacher teacher" in the app
Then the header should be "Teacher teacher" in the app Then the header should be "Teacher teacher" in the app
And I should see "heeey student" And I should find "heeey student" in the app
@app @3.8.0
Scenario: Search users Scenario: Search users
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student2" in the app
And I press "search" in the app And I press "Search" "button" in the app
Then I should see "Student2 student2" Then I should find "Student2 student2" in the app
When I set the field "Search" to "Teacher" in the app When I set the field "Search" to "Teacher" in the app
And I press "search" in the app And I press "Search" "button" in the app
Then I should see "Teacher teacher" Then I should find "Teacher teacher" in the app
@app @3.8.0
Scenario: Send/receive messages in existing conversations Scenario: Send/receive messages in existing conversations
When I enter the app When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Contacts" in the app And I press "Contacts" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" 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 set the field "New message" to "heeey student" in the app
And I press "Send" in the app And I press "Send" in the app
And I enter the app Then I should find "heeey student" in the app
When I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Contacts" in the app And I press "Contacts" in the app
And I press "addon.messages.search" 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 set the field "Search" to "teacher" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Teacher teacher" in the app And I press "Teacher teacher" in the app
Then I should see "heeey student" Then I should find "heeey student" in the app
When I set the field "New message" to "hi" in the app When I set the field "New message" to "hi" in the app
And I press "Send" in the app And I press "Send" in the app
And I enter the app Then I should find "hi" in the app
When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app 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 press "addon.messages.search" in the app
And I set the field "Search" to "student1" in the app And I set the field "Search" to "student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" in the app And I press "Student1 student1" in the app
Then I should see "heeey student" Then I should find "heeey student" in the app
And I should see "hi" And I should find "hi" in the app
And I set the field "New message" to "byee" in the app
And I press "Send" in the app When I set the field "New message" to "byee" in the app
Then I should see "heeey student" And I press "Send" in the app
And I should see "hi" Then I should find "heeey student" in the app
And I should see "byee" And I should find "hi" in the app
And I should find "byee" in the app
@app @3.8.0
Scenario: User profile: send message, add/remove contact Scenario: User profile: send message, add/remove contact
When I enter the app When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Contacts" in the app And I press "Contacts" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" 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 set the field "New message" to "heeey student" in the app
And I press "Send" in the app And I press "Send" in the app
And I press "Conversation actions menu" 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 to contacts" in the app
And I press "Add" in the app And I press "Add" in the app
Then I should see "Contact request sent" Then I should find "Contact request sent" in the app
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
@ -131,159 +136,170 @@ Feature: Test basic usage of messages in app
And I press "Contacts" in the app And I press "Contacts" in the app
And I press "Requests" in the app And I press "Requests" in the app
And I press "Teacher teacher" in the app And I press "Teacher teacher" in the app
Then I should see "Teacher teacher would like to contact you" 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 When I press "Accept and add to contacts" in the app
Then I should not see "Teacher teacher would like to contact you" Then I should not find "Teacher teacher would like to contact you" in the app
When I press "Teacher teacher" 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 press "Message" in the app
And I set the field "New message" to "hi" in the app And I set the field "New message" to "hi" in the app
And I press "Send" in the app And I press "Send" "button" in the app
Then I should see "heeey student" Then I should find "heeey student" in the app
And I should see "hi" And I should find "hi" in the app
When I press the back button in the app When I press "Display options" in the app
And I press "Remove from contacts" in the app And I press "Remove from contacts" in the app
And I press "Remove" in the app And I press "Remove" in the app
Then I should see "Add to contacts" 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 the back button in the app When I press "Display options" in the app
And I press "Conversation actions menu" in the app And I press "Delete conversation" in the app
Then I should see "Add to contacts" 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
When I press "Delete conversation" in the app
And I press "Delete" in the app
And I should not see "heeey student"
And I should not see "hi"
@app @3.8.0
Scenario: Send message offline Scenario: Send message offline
When I enter the app When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Contacts" in the app And I press "Contacts" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" in the app And I press "Student1 student1" in the app
And I switch offline mode to "true" And I switch offline mode to "true"
And I set the field "New message" to "heeey student" 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 "Send" in the app
And I set the field "New message" to "byee" 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 And I press "Send" in the app
And I switch offline mode to "false" 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 the back button in the app
And I press "Student1 student1" in the app And I press "Student1 student1" in the app
And I enter 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 log in as "student1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Teacher teacher" in the app And I press "Teacher teacher" in the app
Then I should see "heeey student" Then I should find "heeey student" in the app
And I should see "byee" And I should find "byee" in the app
@app @3.8.0
Scenario: Auto-sync messages Scenario: Auto-sync messages
When I enter the app When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Contacts" in the app And I press "Contacts" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" in the app And I press "Student1 student1" in the app
And I switch offline mode to "true" And I switch offline mode to "true"
And I set the field "New message" to "heeey student" 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 "Send" in the app
And I set the field "New message" to "byee" in the app And I set the field "New message" to "byee" in the app
And I press "Send" in the app And I press "Send" in the app
And I switch offline mode to "false" 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 run cron tasks in the app
And I enter the app And I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "Teacher teacher" in the app And I press "Teacher teacher" in the app
Then I should see "heeey student" Then I should find "heeey student" in the app
And I should see "byee" And I should find "byee" in the app
@app @3.8.0
Scenario: Search for messages Scenario: Search for messages
When I enter the app When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" 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 set the field "New message" to "test message" in the app
And I press "Send" in the app And I press "Send" in the app
And I set the field "New message" to "search this message" 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 And I press "Send" in the app
And I enter 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 log in as "student1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "addon.messages.search" 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 set the field "Search" to "search this message" in the app
And I press "search" in the app And I press "Search" "button" in the app
Then I should see "Messages" Then I should find "Messages" in the app
And I should see "search this message" And I should find "search this message" in the app
When I press "search this message" near "Teacher teacher" in the app When I press "search this message" near "Teacher teacher" in the app
Then I should see "test message" Then I should find "test message" in the app
And I should see "search this message" And I should find "search this message" in the app
@app @3.8.0
Scenario: Star/Unstar Scenario: Star/Unstar
When I enter the app When I enter the app
And I log in as "teacher1" And I log in as "teacher1"
And I press "Messages" in the app And I press "Messages" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" 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 set the field "New message" to "star message" in the app
And I press "Send" in the app And I press "Send" in the app
And I enter the app Then I should find "star message" in the app
When I enter the app
And I log in as "student2" And I log in as "student2"
And I press "Messages" in the app And I press "Messages" in the app
And I press "addon.messages.search" 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 set the field "Search" to "student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" 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 set the field "New message" to "test message student2" in the app
And I press "Send" in the app And I press "Send" in the app
And I enter 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 log in as "student1"
And I press "Messages" in the app And I press "Messages" in the app
Then I should see "Private (2)" Then I should find "Private (2)" in the app
And I should see "Starred (1)" And I should find "Starred (1)" in the app
When I press "star message" in the app When I press "star message" in the app
And I press "Conversation actions menu" in the app And I press "Display options" in the app
And I press "Star conversation" in the app And I press "Star conversation" in the app
And I press the back button in the app And I press the back button in the app
Then I should see "Private (1)" Then I should find "Private (1)" in the app
And I should see "Starred (2)" And I should find "Starred (2)" in the app
When I press "Starred (2)" in the app When I press "Starred (2)" in the app
Then I should see "Teacher teacher" Then I should find "Teacher teacher" in the app
And I should see "Student1 student1" And I should find "Student1 student1" in the app
@app @3.8.0
Scenario: User blocking feature Scenario: User blocking feature
When I enter the app When I enter the app
And I log in as "student2" And I log in as "student2"
And I press "Course 1" near "Recently accessed courses" in the app And I press "Course 1" near "Recently accessed courses" in the app
And I press "Participants" in the app And I press "Participants" in the app
And I press "Student1 student1" 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" in the app
And I should see "Are you sure you want to block Student1 student1?" And I press "Block user" near "Are you sure you want to block Student1 student1?" in the app
And I press "Cancel" in the app Then I should find "You have blocked this user" in the app
And I should see "Block user"
And I press "Block user" in the app
And I press "Block user" near "Cancel" in the app
Then I should see "Unblock user"
But I should not see "Block user"
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
@ -291,25 +307,21 @@ Feature: Test basic usage of messages in app
And I press "Participants" in the app And I press "Participants" in the app
And I press "Student2 student2" in the app And I press "Student2 student2" in the app
And I press "Message" in the app And I press "Message" in the app
Then I should see "You are unable to message this user" Then I should find "You are unable to message this user" in the app
When I enter the app When I enter the app
And I log in as "student2" And I log in as "student2"
And I press "Course 1" near "Recently accessed courses" in the app And I press "Course 1" near "Recently accessed courses" in the app
And I press "Participants" in the app And I press "Participants" in the app
And I press "Student1 student1" in the app And I press "Student1 student1" in the app
Then I should see "Unblock user" And I press "Message" in the app
But I should not see "Block user" 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 When I press "Unblock user" in the app
And I press "Cancel" in the app And I press "Unblock user" near "Are you sure you want to unblock Student1 student1?" in the app
Then I should see "Unblock user" Then I should not find "You have blocked this user" in the app
But I should not see "Block user"
When I press "Unblock user" in the app
And I press "Unblock user" near "Cancel" in the app
Then I should see "Block user"
But I should not see "Unblock user"
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
@ -319,10 +331,9 @@ Feature: Test basic usage of messages in app
And I press "Message" 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 set the field "New message" to "test message" in the app
And I press "Send" in the app And I press "Send" in the app
Then I should see "test message" Then I should find "test message" in the app
But I should not see "You are unable to message this user" But I should not find "You are unable to message this user" in the app
@app @3.8.0
Scenario: Mute Unmute conversations Scenario: Mute Unmute conversations
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
@ -332,73 +343,80 @@ Feature: Test basic usage of messages in app
And I press "Message" 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 set the field "New message" to "test message" in the app
And I press "Send" in the app And I press "Send" in the app
And I press "Conversation actions menu" 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 And I press "Mute" in the app
And I press "Muted conversation" in the app Then I should find "Muted conversation" in the app
And I press "Conversation actions menu" in the app
Then I should not see "Mute"
When I press "Unmute" in the app When I press "Display options" in the app
And I press "Conversation actions menu" in the app And I press "Unmute" in the app
Then I should not see "Unmute" 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 When I press "Mute" in the app
And I press "Messages" 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 "Private (1)" in the app
And I press "Student2 student2" in the app And I press "Student2 student2" in the app
And I press "Conversation actions menu" in the app Then I should find "test message" in the app
Then I should see "Unmute" And I should find "Muted conversation" in the app
But I should not see "Mute"
@app @3.8.0
Scenario: Self conversations Scenario: Self conversations
When I enter the app When I enter the app
And I log in as "student1" And I log in as "student1"
And I press "Messages" in the app And I press "Messages" in the app
Then I should see "Starred (1)" Then I should find "Starred (1)" in the app
When I press "Student1 student1" 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 set the field "New message" to "self conversation online" in the app
And I press "Send" in the app And I press "Send" in the app
And I switch offline mode to "true" 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 set the field "New message" to "self conversation offline" in the app
And I press "Send" in the app And I press "Send" in the app
And I switch offline mode to "false" 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 the back button in the app
And I press "Student1 student1" in the app And I press "Student1 student1" in the app
And I press "Conversation actions menu" in the app And I press "Display options" in the app
Then I should see "Show delete messages" Then I should find "Show delete messages" in the app
And I should see "Delete conversation" And I should find "Delete conversation" in the app
When I press "Unstar conversation" in the app When I press "Unstar conversation" in the app
And I press "Conversation actions menu" in the app And I press "Display options" in the app
Then I should see "Star conversation" Then I should find "Star conversation" in the app
And I should see "Delete conversation" And I should find "Delete conversation" in the app
When I press "Show delete messages" in the app When I press "Show delete messages" in the app
Then I should see "self conversation online" Then I should find "self conversation online" in the app
And I should see "self conversation offline" And I should find "self conversation offline" in the app
When I press "Delete message" near "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 And I press "OK" in the app
Then I should see "self conversation online" Then I should find "self conversation online" in the app
But I should not see "self conversation offline" But I should not find "self conversation offline" in the app
When I press "Conversation actions menu" in the app When I press "Display options" in the app
And I press "Delete conversation" in the app And I press "Delete conversation" in the app
And I press "Delete" 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 see "self conversation online" Then I should not find "self conversation online" in the app
And I should not see "self conversation offline" And I should not find "self conversation offline" in the app
When I press the back button in the app When I press the back button in the app
And I press "addon.messages.search" 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 set the field "Search" to "Student1 student1" in the app
And I press "search" in the app And I press "Search" "button" in the app
And I press "Student1 student1" 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 set the field "New message" to "auto search test" in the app
And I press "Send" in the app And I press "Send" in the app
And I press the back button 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 the back button in the app
And I press "Private" in the app And I press "Private" in the app
And I press "Student1 student1" in the app And I press "Student1 student1" in the app
Then I should see "auto search test" Then I should find "auto search test" in the app

View File

@ -11,13 +11,13 @@
* *
* @param {string} text Information to log * @param {string} text Information to log
*/ */
var log = function(text) { var log = function() {
var now = new Date(); var now = new Date();
var nowFormatted = String(now.getHours()).padStart(2, '0') + ':' + var nowFormatted = String(now.getHours()).padStart(2, '0') + ':' +
String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' +
String(now.getSeconds()).padStart(2, '0') + '.' + String(now.getSeconds()).padStart(2, '0') + '.' +
String(now.getMilliseconds()).padStart(2, '0'); String(now.getMilliseconds()).padStart(2, '0');
console.log('BEHAT: ' + nowFormatted + ' ' + text); // eslint-disable-line no-console console.log('BEHAT: ' + nowFormatted, ...arguments); // eslint-disable-line no-console
}; };
/** /**
@ -185,13 +185,14 @@
if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none') if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none')
return false; return false;
if (element.parentElement === container) const parentElement = getParentElement(element);
if (parentElement === container)
return true; return true;
if (!element.parentElement) if (!parentElement)
return false; return false;
return isElementVisible(element.parentElement, container); return isElementVisible(parentElement, container);
}; };
/** /**
@ -210,10 +211,11 @@
) )
return true; return true;
if (!element.parentElement || element.parentElement === container) const parentElement = getParentElement(element);
if (!parentElement || parentElement === container)
return false; return false;
return isElementSelected(element.parentElement, container); return isElementSelected(parentElement, container);
}; };
/** /**
@ -352,19 +354,28 @@
return [...uniqueElements]; return [...uniqueElements];
}; };
/**
* Get parent element, including Shadow DOM parents.
*
* @param {HTMLElement} element Element.
* @return {HTMLElement} Parent element.
*/
var getParentElement = function(element) {
return element.parentElement ?? element.getRootNode()?.host ?? null;
};
/** /**
* Function to find elements based on their text or Aria label. * Function to find elements based on their text or Aria label.
* *
* @param {string} text Text (full or partial) * @param {object} locator Element locator.
* @param {string} [near] Optional 'near' text - if specified, must have a single match on page
* @return {HTMLElement} Found elements * @return {HTMLElement} Found elements
*/ */
var findElementsBasedOnText = function(text, near) { var findElementsBasedOnText = function(locator) {
const topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); const topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html');
let container = topContainer; let container = topContainer;
if (topContainer && near) { if (topContainer && locator.near) {
const nearElements = findElementsBasedOnText(near); const nearElements = findElementsBasedOnText(locator.near);
if (nearElements.length === 0) { if (nearElements.length === 0) {
throw new Error('There was no match for near text') throw new Error('There was no match for near text')
@ -375,23 +386,77 @@
throw new Error('Too many matches for near text'); throw new Error('Too many matches for near text');
} }
container = nearElementsAncestors[0].parentElement; container = getParentElement(nearElementsAncestors[0]);
} else { } else {
container = nearElements[0].parentElement; container = getParentElement(nearElements[0]);
} }
} }
do { do {
const elements = findElementsBasedOnTextWithin(container, text); const elements = findElementsBasedOnTextWithin(container, locator.text);
const filteredElements = locator.selector
? elements.filter(element => element.matches(locator.selector))
: elements;
if (elements.length > 0) { if (filteredElements.length > 0) {
return elements; return filteredElements;
} }
} while ((container = container.parentElement) && container !== topContainer); } while ((container = getParentElement(container)) && container !== topContainer);
return []; return [];
}; };
/**
* Press an element.
*
* @param {HTMLElement} element Element to press.
*/
var pressElement = function(element) {
if (window.BehatMoodleAppLegacy) {
var mainContent = getNavCtrl().getActive().contentRef().nativeElement;
var rect = element.getBoundingClientRect();
// Scroll the item into view.
mainContent.scrollTo(rect.x, rect.y);
// Simulate a mouse click on the button.
var eventOptions = {
clientX: rect.left + rect.width / 2,
clientY: rect.top + rect.height / 2,
bubbles: true,
view: window,
cancelable: true,
};
setTimeout(() => element.dispatchEvent(new MouseEvent('mousedown', eventOptions)), 0);
setTimeout(() => element.dispatchEvent(new MouseEvent('mouseup', eventOptions)), 0);
setTimeout(() => element.dispatchEvent(new MouseEvent('click', eventOptions)), 0);
} else {
// Scroll the item into view.
element.scrollIntoView();
// Events don't bubble up across Shadow DOM boundaries, and some buttons
// may not work without doing this.
const parentElement = getParentElement(element);
if (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. * Function to find and click an app standard button.
* *
@ -444,10 +509,13 @@
} else { } else {
switch (button) { switch (button) {
case 'back': case 'back':
foundButton = findElementsBasedOnText('Back')[0]; foundButton = findElementsBasedOnText({ text: 'Back' })[0];
break; break;
case 'main menu': case 'main menu':
foundButton = findElementsBasedOnText('more', 'Notifications')[0]; foundButton = findElementsBasedOnText({
text: 'more',
near: { text: 'Notifications' },
})[0];
break; break;
default: default:
return 'ERROR: Unsupported standard button type'; return 'ERROR: Unsupported standard button type';
@ -455,10 +523,7 @@
} }
// Click button // Click button
foundButton.click(); pressElement(foundButton);
// Mark busy until the button click finishes processing.
addPendingDelay();
return 'OK'; return 'OK';
}; };
@ -500,15 +565,14 @@
/** /**
* Function to find an arbitrary item based on its text or aria label. * Function to find an arbitrary item based on its text or aria label.
* *
* @param {string} text Text (full or partial) * @param {object} locator Element locator.
* @param {string} [near] Optional 'near' text
* @return {string} OK if successful, or ERROR: followed by message * @return {string} OK if successful, or ERROR: followed by message
*/ */
var behatFind = function(text, near) { var behatFind = function(locator) {
log(`Action - Find ${text}`); log('Action - Find', locator);
try { try {
const element = findElementsBasedOnText(text, near)[0]; const element = findElementsBasedOnText(locator)[0];
if (!element) { if (!element) {
return 'ERROR: No matches for text'; return 'ERROR: No matches for text';
@ -540,15 +604,14 @@
/** /**
* Check whether an item is selected or not. * Check whether an item is selected or not.
* *
* @param {string} text Text (full or partial) * @param {object} locator Element locator.
* @param {string} near Optional 'near' text
* @return {string} YES or NO if successful, or ERROR: followed by message * @return {string} YES or NO if successful, or ERROR: followed by message
*/ */
var behatIsSelected = function(text, near) { var behatIsSelected = function(locator) {
log(`Action - Is Selected: "${text}"${near ? ` near "${near}"`: ''}`); log('Action - Is Selected', locator);
try { try {
const element = findElementsBasedOnText(text, near)[0]; const element = findElementsBasedOnText(locator)[0];
return isElementSelected(element, document.body) ? 'YES' : 'NO'; return isElementSelected(element, document.body) ? 'YES' : 'NO';
} catch (error) { } catch (error) {
@ -559,16 +622,15 @@
/** /**
* Function to press arbitrary item based on its text or Aria label. * Function to press arbitrary item based on its text or Aria label.
* *
* @param {string} text Text (full or partial) * @param {object} locator Element locator.
* @param {string} near Optional 'near' text
* @return {string} OK if successful, or ERROR: followed by message * @return {string} OK if successful, or ERROR: followed by message
*/ */
var behatPress = function(text, near) { var behatPress = function(locator) {
log('Action - Press ' + text + (near === undefined ? '' : ' - near ' + near)); log('Action - Press', locator);
var found; var found;
try { try {
found = findElementsBasedOnText(text, near)[0]; found = findElementsBasedOnText(locator)[0];
if (!found) { if (!found) {
return 'ERROR: No matches for text'; return 'ERROR: No matches for text';
@ -577,32 +639,7 @@
return 'ERROR: ' + error.message; return 'ERROR: ' + error.message;
} }
if (window.BehatMoodleAppLegacy) { pressElement(found);
var mainContent = getNavCtrl().getActive().contentRef().nativeElement;
var rect = found.getBoundingClientRect();
// Scroll the item into view.
mainContent.scrollTo(rect.x, rect.y);
// Simulate a mouse click on the button.
var eventOptions = {clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2,
bubbles: true, view: window, cancelable: true};
setTimeout(function() {
found.dispatchEvent(new MouseEvent('mousedown', eventOptions));
}, 0);
setTimeout(function() {
found.dispatchEvent(new MouseEvent('mouseup', eventOptions));
}, 0);
setTimeout(function() {
found.dispatchEvent(new MouseEvent('click', eventOptions));
}, 0);
} else {
found.scrollIntoView();
setTimeout(() => found.click(), 300);
}
// Mark busy until the button click finishes processing.
addPendingDelay();
return 'OK'; return 'OK';
}; };
@ -697,8 +734,7 @@
return 'ERROR: No matches for text'; return 'ERROR: No matches for text';
} }
} else { } else {
const elements = findElementsBasedOnText(field); found = findElementsBasedOnText({ text: field, selector: 'input, textarea' })[0];
var found = elements.filter(element => element.matches('input, textarea'))[0];
if (!found) { if (!found) {
return 'ERROR: No matches for text'; return 'ERROR: No matches for text';

View File

@ -103,18 +103,15 @@ class behat_app extends behat_base {
/** /**
* Finds elements in the app. * Finds elements in the app.
* *
* @Then /^I should(?P<not_boolean> not)? find "(?P<text_string>(?:[^"]|\\")*)"(?: near "(?P<near_string>(?:[^"]|\\")*)")? in the app$/ * @Then /^I should( not)? find (".+") in the app$/
* @param string $not * @param bool $not
* @param string $text * @param object $locator
* @param string $near
*/ */
public function i_find_in_the_app($not, $text='', $near='') { public function i_find_in_the_app(bool $not, object $locator) {
$not = !empty($not); $locatorjson = json_encode($locator);
$text = addslashes_js($text);
$near = addslashes_js($near);
$this->spin(function() use ($not, $text, $near) { $this->spin(function() use ($not, $locatorjson) {
$result = $this->evaluate_script("return window.behat.find(\"$text\", \"$near\");"); $result = $this->evaluate_script("return window.behat.find($locatorjson);");
if ($not && $result === 'OK') { if ($not && $result === 'OK') {
throw new DriverException('Error, found an item that should not be found'); throw new DriverException('Error, found an item that should not be found');
@ -126,22 +123,22 @@ class behat_app extends behat_base {
return true; return true;
}); });
$this->wait_for_pending_js(); $this->wait_for_pending_js();
} }
/** /**
* Check if elements are selected in the app. * Check if elements are selected in the app.
* *
* @Then /^"(?P<text_string>(?:[^"]|\\")*)"(?: near "(?P<near_string>(?:[^"]|\\")*)")? should(?P<not_boolean> not)? be selected in the app$/ * @Then /^(".+") should( not)? be selected in the app$/
* @param string $text * @param object $locator
* @param bool $not
*/ */
public function be_selected_in_the_app($text, $near='', $not='') { public function be_selected_in_the_app(object $locator, bool $not = false) {
$not = !empty($not); $locatorjson = json_encode($locator);
$text = addslashes_js($text);
$near = addslashes_js($near);
$this->spin(function() use ($not, $text, $near) { $this->spin(function() use ($locatorjson, $not) {
$result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);");
switch ($result) { switch ($result) {
case 'YES': case 'YES':
@ -160,6 +157,7 @@ class behat_app extends behat_base {
return true; return true;
}); });
$this->wait_for_pending_js(); $this->wait_for_pending_js();
} }
@ -403,7 +401,7 @@ class behat_app extends behat_base {
: $page->find('xpath', '//core-login-site-onboarding'); : $page->find('xpath', '//core-login-site-onboarding');
if ($element) { if ($element) {
$this->i_press_in_the_app('Skip'); $this->i_press_in_the_app($this->parse_element_locator('"Skip"'));
} }
// Login screen found. // Login screen found.
@ -431,7 +429,7 @@ class behat_app extends behat_base {
global $CFG; global $CFG;
$this->i_set_the_field_in_the_app($this->islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot); $this->i_set_the_field_in_the_app($this->islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot);
$this->i_press_in_the_app($this->islegacy ? 'Connect!' : 'Connect to your site'); $this->i_press_in_the_app($this->parse_element_locator($this->islegacy ? '"Connect!"' : '"Connect to your site"'));
$this->wait_for_pending_js(); $this->wait_for_pending_js();
} }
@ -448,7 +446,7 @@ class behat_app extends behat_base {
// Note there are two 'Log in' texts visible (the title and the button) so we have to use // Note there are two 'Log in' texts visible (the title and the button) so we have to use
// a 'near' value here. // a 'near' value here.
$this->i_press_in_the_app('Log in', 'Forgotten'); $this->i_press_in_the_app($this->parse_element_locator('"Log in" near "Forgotten"'));
// Wait until the main page appears. // Wait until the main page appears.
$this->spin( $this->spin(
@ -467,18 +465,21 @@ class behat_app extends behat_base {
/** /**
* Presses standard buttons in the app. * Presses standard buttons in the app.
* *
* @Given /^I press the (?P<button_name>back|main menu|page menu) button in the app$/ * @Given /^I press the (back|main menu|page menu) button in the app$/
* @param string $button Button type * @param string $button Button type
* @throws DriverException If the button push doesn't work * @throws DriverException If the button push doesn't work
*/ */
public function i_press_the_standard_button_in_the_app(string $button) { public function i_press_the_standard_button_in_the_app(string $button) {
$this->spin(function($context, $args) use ($button) { $this->spin(function() use ($button) {
$result = $this->evaluate_script("return window.behat.pressStandard('{$button}');"); $result = $this->evaluate_script("return window.behat.pressStandard('$button');");
if ($result !== 'OK') { if ($result !== 'OK') {
throw new DriverException('Error pressing standard button - ' . $result); throw new DriverException('Error pressing standard button - ' . $result);
} }
return true; return true;
}); });
$this->wait_for_pending_js(); $this->wait_for_pending_js();
} }
@ -519,13 +520,16 @@ class behat_app extends behat_base {
* @throws DriverException If there isn't a popup to close * @throws DriverException If there isn't a popup to close
*/ */
public function i_close_the_popup_in_the_app() { public function i_close_the_popup_in_the_app() {
$this->spin(function($context, $args) { $this->spin(function() {
$result = $this->evaluate_script("return window.behat.closePopup();"); $result = $this->evaluate_script("return window.behat.closePopup();");
if ($result !== 'OK') { if ($result !== 'OK') {
throw new DriverException('Error closing popup - ' . $result); throw new DriverException('Error closing popup - ' . $result);
} }
return true; return true;
}); });
$this->wait_for_pending_js(); $this->wait_for_pending_js();
} }
@ -535,13 +539,24 @@ class behat_app extends behat_base {
* Note it is difficult to use the standard 'click on' or 'press' steps because those do not * Note it is difficult to use the standard 'click on' or 'press' steps because those do not
* distinguish visible items and the app always has many non-visible items in the DOM. * distinguish visible items and the app always has many non-visible items in the DOM.
* *
* @Then /^I press "(?P<text_string>(?:[^"]|\\")*)"(?: near "(?P<near_string>(?:[^"]|\\")*)")? in the app$/ * @Then /^I press (".+") in the app$/
* @param string $text Text identifying click target * @param object $locator Element locator
* @param string $near Text identifying a nearby unique piece of text
* @throws DriverException If the press doesn't work * @throws DriverException If the press doesn't work
*/ */
public function i_press_in_the_app($text, $near='') { public function i_press_in_the_app(object $locator) {
$this->press($text, $near); $locatorjson = json_encode($locator);
$this->spin(function() use ($locatorjson) {
$result = $this->evaluate_script("return window.behat.press($locatorjson);");
if ($result !== 'OK') {
throw new DriverException('Error pressing item - ' . $result);
}
return true;
});
$this->wait_for_pending_js();
} }
/** /**
@ -551,34 +566,32 @@ class behat_app extends behat_base {
* with JavaScript, and clicks may not work until they are initialized properly which may cause flaky tests due * with JavaScript, and clicks may not work until they are initialized properly which may cause flaky tests due
* to race conditions. * to race conditions.
* *
* @Then /^I (?P<select_string>unselect|select) "(?P<text_string>(?:[^"]|\\")*)"(?: near "(?P<near_string>(?:[^"]|\\")*)")? in the app$/ * @Then /^I (unselect|select) (".+") in the app$/
* @param string $selectedtext Select/unselect string * @param string $selectedtext
* @param string $text Text identifying click target * @param object $locator
* @param string $near Text identifying a nearby unique piece of text
* @throws DriverException If the press doesn't work * @throws DriverException If the press doesn't work
*/ */
public function i_select_in_the_app(string $selectedtext, string $text, string $near = '') { public function i_select_in_the_app(string $selectedtext, object $locator) {
$selected = $selectedtext === 'select' ? 'YES' : 'NO'; $selected = $selectedtext === 'select' ? 'YES' : 'NO';
$text = addslashes_js($text); $locatorjson = json_encode($locator);
$near = addslashes_js($near);
$this->spin(function() use ($selectedtext, $selected, $text, $near) { $this->spin(function() use ($selectedtext, $selected, $locatorjson) {
// Don't do anything if the item is already in the expected state. // Don't do anything if the item is already in the expected state.
$result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);");
if ($result === $selected) { if ($result === $selected) {
return true; return true;
} }
// Press item. // Press item.
$result = $this->evaluate_script("return window.behat.press(\"$text\", \"$near\");"); $result = $this->evaluate_script("return window.behat.press($locatorjson);");
if ($result !== 'OK') { if ($result !== 'OK') {
throw new DriverException('Error pressing item - ' . $result); throw new DriverException('Error pressing item - ' . $result);
} }
// Check that it worked as expected. // Check that it worked as expected.
$result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);");
switch ($result) { switch ($result) {
case 'YES': case 'YES':
@ -606,54 +619,31 @@ class behat_app extends behat_base {
return !is_null($logininput); return !is_null($logininput);
} }
/**
* Clicks on / touches something that is visible in the app, near some other text.
*
* If the $near is specified then when there are multiple matches, it picks the one
* nearest (in DOM terms) $near. $near should be an exact match, or a partial match that only
* has one result.
*
* @param behat_base $base Behat context
* @param string $text Text identifying click target
* @param string $near Text identifying a nearby unique piece of text
* @throws DriverException If the press doesn't work
*/
protected function press(string $text, string $near = '') {
$text = addslashes_js($text);
$near = addslashes_js($near);
$this->spin(function() use ($text, $near) {
$result = $this->evaluate_script("return window.behat.press(\"$text\", \"$near\");");
if ($result !== 'OK') {
throw new DriverException('Error pressing item - ' . $result);
}
return true;
});
$this->wait_for_pending_js();
}
/** /**
* Sets a field to the given text value in the app. * Sets a field to the given text value in the app.
* *
* Currently this only works for input fields which must be identified using a partial or * Currently this only works for input fields which must be identified using a partial or
* exact match on the placeholder text. * exact match on the placeholder text.
* *
* @Given /^I set the field "(?P<field_name>(?:[^"]|\\")*)" to "(?P<text_string>(?:[^"]|\\")*)" in the app$/ * @Given /^I set the field "((?:[^"]|\\")+)" to "((?:[^"]|\\")+)" in the app$/
* @param string $field Text identifying field * @param string $field Text identifying field
* @param string $value Value for field * @param string $value Value for field
* @throws DriverException If the field set doesn't work * @throws DriverException If the field set doesn't work
*/ */
public function i_set_the_field_in_the_app(string $field, string $value) { public function i_set_the_field_in_the_app(string $field, string $value) {
$this->spin(function($context, $args) use ($field, $value) { $field = addslashes_js($field);
$result = $this->evaluate_script('return window.behat.setField("' . $value = addslashes_js($value);
addslashes_js($field) . '", "' . addslashes_js($value) . '");');
$this->spin(function() use ($field, $value) {
$result = $this->evaluate_script("return window.behat.setField(\"$field\", \"$value\");");
if ($result !== 'OK') { if ($result !== 'OK') {
throw new DriverException('Error setting field - ' . $result); throw new DriverException('Error setting field - ' . $result);
} }
return true; return true;
}); });
$this->wait_for_pending_js(); $this->wait_for_pending_js();
} }
@ -662,7 +652,7 @@ class behat_app extends behat_base {
* *
* This can be used to see if the app went to the expected page. * This can be used to see if the app went to the expected page.
* *
* @Then /^the header should be "(?P<text_string>(?:[^"]|\\")*)" in the app$/ * @Then /^the header should be "((?:[^"]|\\")+)" in the app$/
* @param string $text Expected header text * @param string $text Expected header text
* @throws DriverException If the header can't be retrieved * @throws DriverException If the header can't be retrieved
* @throws ExpectationException If the header text is different to the expected value * @throws ExpectationException If the header text is different to the expected value
@ -690,12 +680,10 @@ class behat_app extends behat_base {
/** /**
* Check that the app opened a new browser tab. * Check that the app opened a new browser tab.
* *
* @Given /^the app should(?P<not_boolean> not)? have opened a browser tab$/ * @Given /^the app should( not)? have opened a browser tab$/
* @param string $not * @param bool $not
*/ */
public function the_app_should_have_opened_a_browser_tab($not = '') { public function the_app_should_have_opened_a_browser_tab(bool $not) {
$not = !empty($not);
$this->spin(function() use ($not) { $this->spin(function() use ($not) {
$openedbrowsertab = count($this->getSession()->getWindowNames()) === 2; $openedbrowsertab = count($this->getSession()->getWindowNames()) === 2;
@ -748,11 +736,48 @@ class behat_app extends behat_base {
/** /**
* Switch navigator online mode. * Switch navigator online mode.
* *
* @Given /^I switch offline mode to "(?P<offline_string>(?:[^"]|\\")*)"$/ * @Given /^I switch offline mode to "(true|false)"$/
* @param string $offline New value for navigator online mode * @param string $offline New value for navigator online mode
* @throws DriverException If the navigator.online mode is not available * @throws DriverException If the navigator.online mode is not available
*/ */
public function i_switch_offline_mode(string $offline) { public function i_switch_offline_mode(string $offline) {
$this->execute_script('appProvider.setForceOffline(' . $offline . ');'); $this->execute_script("appProvider.setForceOffline($offline);");
} }
/**
* Parse an element locator string.
*
* @Transform /^".+"$/
* @param string $text Element locator string.
* @return object
*/
public function parse_element_locator($text): object {
preg_match('/^"((?:[^"]|\\")+?)"(?: "([^"]+?)")?(?: near "((?:[^"]|\\")+?)"(?: "([^"]+?)")?)?$/', $text, $matches);
$locator = [
'text' => str_replace('\\"', '"', $matches[1]),
'selector' => $matches[2] ?? null,
];
if (!empty($matches[3])) {
$locator['near'] = (object) [
'text' => str_replace('\\"', '"', $matches[3]),
'selector' => $matches[4] ?? null,
];
}
return (object) $locator;
}
/**
* Parse a negation string.
*
* @Transform /^not $/
* @param string $not Negation string.
* @return bool
*/
public function parse_negation(string $not): bool {
return !empty($not);
}
} }