## Maestro end-to-end testing for Android

The end-to-end tests for the Android app are built using [Maestro](https://maestro.mobile.dev/) and
generate reports. The scripts have been written and tested on Linux. They may work on other systems,
but that has not been thoroughly tested.

### Prerequisites:

* Install Maestro as per the [official instructions](https://maestro.mobile.dev/getting-started/installing-maestro).
* Build the android release apk from the [app-android](../../app-android/) module and the
  HTTP server from the [app-ktor-server](../../app-ktor-server/) module. This would be done by the normal
  **gradlew build** command.
* Start an Android emulator or connect a physical device and get the serial of the device 
  (e.g. using the **adb devices** command). It is highly recommended to use a device created by the
  [Meastro start-device command](https://maestro.mobile.dev/cli/start-device). 
* MacOS only: install the realpath command.
* Chrome browser **must** be updated otherwise H5P tests will fail. The version of Chrome that is
  included with SDK33 will work. To test on devices running earlier versions of Android:
    * Update Google Play Services (e.g. from [APKMirror](https://www.apkmirror.com/apk/google-inc/google-play-services/google-play-services-24-31-33-release/))
    * Update Chrome (e.g. from [APKMirror](https://www.apkmirror.com/apk/google-inc/chrome/chrome-127-0-6533-103-release/))
 
### Run all tests:

```
$ ./run-maestro-test.sh --serial1 emulator-5554
```
Where emulator-5554 is the serial of the emulator as per the **adb devices** command.

Options:

* **--test** specify a test to run as per the test flows found in e2e-tests e.g. --test 001_001_admin_can_add_content_001-h5p
* **--apk** specify a particular apk file to test and install. By default the test runner expects to
 use the release APK file built from source
* **--console-output** use Maestro console output instead of saving to a JUnit XML. Helpful to see 
more verbose output when designing/running/debugging flows etc.

 **Output**

Result artifacts (screenshots, screen recording, etc) will be saved as follows:

* build/results/emulator-serial/report.xml - JUnit XML report for the given serial generated by Maestro
* build/results/emulator-serial/test-name - artifacts for each end-to-end test including screenshots
* build/results/emulator-serial/test-name/screenrecord.mp4 - screen recording of the end to end test

The combined report (with videos for each test) HTML will be saved to build/results/index.html 


### Run a single test using Maestro command line:

1. Build and install APK on emulator or device as per [app-android README](../../app-android)

2. Clear Data Folder in app-ktor-server:Start the server using runserver.sh or runserver.bat as per the [Main README development environment setup](../../README.md)

3. Run Maestro command to run test

```
cd test-end-to-end/android-maestro
maestro test e2e-tests/<test name>.yaml -e USERNAME=admin -e PASSWORD=testpass -e TESTSERIAL=emulator-5554 -e ENDPOINT=http://<ip address>:8087/
```

Replace the values for`PASSWORD` with the server admin password, `TESTSERIAL` with the emulator or device serial (as per adb devices command), `ENDPOINT` with the server url as per the --siteUrl parameter used with runserver.

### Resource IDs (testtags)

Editable fields: testTag should be the label, in snake_case e.g. if a field label is "First names",
then the id will be first_names . This applies to text fields, switches, drop downs.

Date/time combined fields: two test tags - one for date, one for time e.g.  dont_show_before_date,
dont_show_before_time

Buttons: testTag should be label_button

Rich text (click to move to edit): Most screens where the user can enter rich text, they will click
on the text and then be taken to another screen to actually edit the text (due to screen size
limitations).

ID to click on to move to next edit screen: com.toughra.ustadmobile:id/text_input_edit_text

ID to click on to actually edit rich text: com.toughra.ustadmobile:id/editor



**Other Ids**

Floating action button: floating_action_button (note: selecting this by the text in the button
does not work).

Action bar button (e.g. save/done): action_bar_button

Settings (action bar): settings_button

Accounts (top right): header_avatar

Title text: app_title

Exceptions:
Next/prev buttons on attendance edit: prev_day_button and next_day_button

Message list (chat) screen (no label): textfield: message_text

PersonEdit: phone number is split into country code dropdown ( tag: country_code ) and the in country
number ( tag: phone_number_text )
