From a8139a2a0a4cbc6a3023943c9e8a2aab28b2c743 Mon Sep 17 00:00:00 2001 From: andreia Date: Mon, 5 Jan 2026 19:41:48 +0100 Subject: [PATCH 01/16] Update github actions for E2E test --- .github/actions/submit-test/action.yml | 255 ++++++++++--------------- .github/workflows/test-e2e.yml | 34 ++-- 2 files changed, 112 insertions(+), 177 deletions(-) diff --git a/.github/actions/submit-test/action.yml b/.github/actions/submit-test/action.yml index 4145499adb..5f5f541760 100644 --- a/.github/actions/submit-test/action.yml +++ b/.github/actions/submit-test/action.yml @@ -14,166 +14,107 @@ name: Submit to survey inputs: - android-repository: - description: 'ground-android repository under test' - default: google/ground-android + android-repository: + description: 'ground-android repository under test' + default: google/ground-android - platform-repository: - description: 'ground-platform repository under test (if applicable)' - default: google/ground-platform + platform-repository: + description: 'ground-platform repository under test (if applicable)' + default: google/ground-platform - use-repo-data: - description: 'Whether to use the local repository emulator data or not' - default: 'true' + use-repo-data: + description: 'Whether to use the local repository emulator data or not' + default: 'true' - upload-artifacts: - description: 'Whether to upload the final emulator data artifacts' - default: 'false' + upload-artifacts: + description: 'Whether to upload the final emulator data artifacts' + default: 'false' - google-maps-key: - description: 'A Google Maps API key' + google-maps-key: + description: 'A Google Maps API key' runs: - using: composite - steps: - - name: Enable KVM group perms - shell: bash - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - ls /dev/kvm - - - name: Gradle cache - uses: gradle/actions/setup-gradle@v3 - - - name: AVD cache - uses: actions/cache@v4 - id: avd-cache - with: - path: | - ~/.android/avd/* - ~/.android/adb* - key: avd-24 - - - name: Checkout - uses: actions/checkout@v4 - with: - repository: ${{ inputs.android-repository }} - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: 17 - - - name: Setup Gradle - uses: gradle/gradle-build-action@v3 - - - name: Set up Node.js 18 - uses: actions/setup-node@v4 - with: - node-version: 18 - - - name: Checkout ground-platform - uses: actions/checkout@v4 - with: - repository: ${{ inputs.platform-repository }} - path: ground-platform - - - name: Cache node modules - id: cache-npm - uses: actions/cache@v3 - env: - cache-name: cache-node-modules - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Build ground functions - shell: bash - run: | - cd ground-platform - npm run build:local - cd ../ - - - name: Install firebase-tools - shell: bash - run: | - npm install -g firebase-tools - - - name: Cache Firebase emulator - uses: actions/cache@v4 - with: - path: ~/.cache/firebase/emulators - key: ${{ runner.os }}-firebase-emulators-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-firebase-emulators- - - - name: Copy Firebase emulator data - uses: actions/download-artifact@v4 - if: inputs.use-repo-data != 'true' - with: - name: data-create - path: data/ - - - name: Copy the local repo data - if: inputs.use-repo-data == 'true' - shell: bash - run: cp -r ground-platform/data/test-create ground-platform/data/test - - - name: Replace Google Maps API key - shell: bash - env: - GOOGLE_MAPS_KEY: ${{ inputs.google-maps-key }} - run: | - sed -E -i 's/("current_key": ")[[:alnum:]_-]+(")/\1'"$GOOGLE_MAPS_KEY"'\2/' app/src/debug/local/google-services.json - - - name: Move the local google-services.json - shell: bash - run: | - cp -r app/src/debug/local/google-services.json app/src/debug/ - - - name: Build projects and run instrumentation tests - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 24 - target: google_apis_playstore - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' - disable-animations: true - script: | - firebase emulators:exec './gradlew :e2eTest:connectedLocalDebugAndroidTest --stacktrace' --config ground-platform/firebase.local.json --project local --import data/test --export-on-exit data/test - - - name: Upload test reports - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-reports - path: '**/build/reports/androidTests' - - - name: Upload screenshots - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-screenshots - path: '**/build/outputs/connected_android_test_additional_output' - - - name: Move Firebase emulator data (avoids .gitignore) - shell: bash - run: mv data/test/ ./test - - - name: Copy Firebase emulator data - if: inputs.upload-artifacts == 'true' - uses: actions/upload-artifact@v4 - with: - name: data-submit - path: '**/test' - retention-days: 7 - overwrite: true - if-no-files-found: error \ No newline at end of file + using: composite + steps: + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '21' + + - name: Gradle cache + uses: gradle/actions/setup-gradle@v3 + + - name: AVD cache + uses: actions/cache@v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-24 + + - name: Checkout + uses: actions/checkout@v4 + with: + repository: ${{ inputs.android-repository }} + + - name: Setup Gradle + uses: gradle/gradle-build-action@v3 + + - name: Checkout ground-platform + uses: actions/checkout@v4 + with: + repository: ${{ inputs.platform-repository }} + path: ground-platform + + - name: Copy Firebase emulator data + uses: actions/download-artifact@v4 + if: inputs.use-repo-data != 'true' + with: + name: data-create + path: data/ + + - name: Replace Google Maps API key + shell: bash + env: + GOOGLE_MAPS_KEY: ${{ inputs.google-maps-key }} + run: | + sed -E -i 's/("current_key": ")[[:alnum:]_-]+(")/\1'"$GOOGLE_MAPS_KEY"'\2/' app/src/debug/local/google-services.json + + - name: Move the local google-services.json + shell: bash + run: | + cp -r app/src/debug/local/google-services.json app/src/debug/ + + - name: Build projects and run instrumentation tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 24 + target: google_apis_playstore + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' + disable-animations: true + script: | + firebase emulators:exec './gradlew :e2eTest:connectedLocalDebugAndroidTest --stacktrace' --config ground-platform/firebase.local.json --project local --import data/test-android --export-on-exit data/test-android + + - name: Upload test reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-reports + path: '**/build/reports/androidTests' + + - name: Move Firebase emulator data (avoids .gitignore) + shell: bash + run: mv data/test-android/ ./test-android + + - name: Copy Firebase emulator data + if: inputs.upload-artifacts == 'true' + uses: actions/upload-artifact@v4 + with: + name: data-submit + path: '**/test-android' + retention-days: 7 + overwrite: true + if-no-files-found: error \ No newline at end of file diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 565a7775be..ed686d0cba 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -15,7 +15,7 @@ name: End to End Test on: issue_comment: - types: [created] + types: [ created ] jobs: e2eTest: @@ -23,44 +23,38 @@ jobs: timeout-minutes: 15 if: github.event.issue.pull_request && contains(github.event.comment.body, '/e2eTest') steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Start test run: | echo "Begin end to end test" - createTest: + startEmulator: needs: e2eTest - name: Create a new survey + name: Run the firebase emulator with prefilled data runs-on: ubuntu-latest timeout-minutes: 10 steps: - - name: Run create-test - uses: google/ground-platform/.github/actions/create-test@master + - name: Run test-start-emulator + uses: google/ground-platform/.github/actions/start-emulator@master with: - upload-artifacts: true + upload-artifacts: true submitTest: - needs: createTest + needs: startEmulator name: Submit to survey runs-on: ubuntu-latest timeout-minutes: 15 steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Run submit-test uses: ./.github/actions/submit-test with: android-repository: ${{ github.repository }} google-maps-key: ${{ secrets.GOOGLE_MAPS_KEY }} - use-repo-data: false + use-repo-data: true upload-artifacts: true - - - verifyTest: - needs: submitTest - name: Verify survey submissions - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Run verify-test - uses: google/ground-platform/.github/actions/verify-test@master - with: - use-repo-data: false From 4305c1fd1a511d7830622580aa618e293bd51b88 Mon Sep 17 00:00:00 2001 From: andreia Date: Tue, 6 Jan 2026 12:03:04 +0100 Subject: [PATCH 02/16] Update workflow to run on merge to master --- .github/workflows/test-e2e.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index ed686d0cba..1b95392762 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -14,14 +14,14 @@ name: End to End Test on: - issue_comment: - types: [ created ] + push: + branches: + - master jobs: e2eTest: runs-on: ubuntu-latest timeout-minutes: 15 - if: github.event.issue.pull_request && contains(github.event.comment.body, '/e2eTest') steps: - name: Checkout repository uses: actions/checkout@v4 From 8baf5197c97c0a1aa781cfd9a7f1aa692ea6de2d Mon Sep 17 00:00:00 2001 From: andreia Date: Tue, 13 Jan 2026 18:26:27 +0100 Subject: [PATCH 03/16] Update workflow file and rename action --- .../action.yml | 108 +++++++++--------- .github/workflows/test-e2e.yml | 36 ++---- .gitignore | 1 + 3 files changed, 67 insertions(+), 78 deletions(-) rename .github/actions/{submit-test => run-automation-tests}/action.yml (50%) diff --git a/.github/actions/submit-test/action.yml b/.github/actions/run-automation-tests/action.yml similarity index 50% rename from .github/actions/submit-test/action.yml rename to .github/actions/run-automation-tests/action.yml index 5f5f541760..f4ee13b92d 100644 --- a/.github/actions/submit-test/action.yml +++ b/.github/actions/run-automation-tests/action.yml @@ -1,4 +1,4 @@ -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,21 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -name: Submit to survey +name: Run all automated tests in the e2eTeest module inputs: android-repository: description: 'ground-android repository under test' default: google/ground-android - platform-repository: - description: 'ground-platform repository under test (if applicable)' - default: google/ground-platform - - use-repo-data: - description: 'Whether to use the local repository emulator data or not' - default: 'true' - upload-artifacts: description: 'Whether to upload the final emulator data artifacts' default: 'false' @@ -36,12 +28,35 @@ inputs: runs: using: composite steps: + - name: Checkout + uses: actions/checkout@v6 + with: + repository: ${{ inputs.android-repository }} + + - name: Check Firebase emulator connection + shell: bash + run: | + echo "Checking connection to Firebase emulator..." + if curl -v http://localhost:4000; then + echo "Successfully connected to Firebase emulator!" + else + echo "Failed to connect to Firebase emulator (http://localhost:4000)" + exit 1 + fi + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '21' + - name: Enable KVM group perms + shell: bash + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Gradle cache uses: gradle/actions/setup-gradle@v3 @@ -52,51 +67,45 @@ runs: path: | ~/.android/avd/* ~/.android/adb* - key: avd-24 - - - name: Checkout - uses: actions/checkout@v4 - with: - repository: ${{ inputs.android-repository }} + key: avd-35-google_apis_playstore-x86_64 - name: Setup Gradle uses: gradle/gradle-build-action@v3 - - name: Checkout ground-platform - uses: actions/checkout@v4 - with: - repository: ${{ inputs.platform-repository }} - path: ground-platform - - - name: Copy Firebase emulator data - uses: actions/download-artifact@v4 - if: inputs.use-repo-data != 'true' + - name: create AVD and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 with: - name: data-create - path: data/ + api-level: 35 + target: google_apis_playstore + arch: x86_64 + force-avd-creation: true + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' + disable-animations: true + script: | + adb shell settings put secure location_mode 3 + adb shell settings put secure location_providers_allowed +gps + adb shell settings put secure location_providers_allowed +network + echo "Generated AVD snapshot for caching." - - name: Replace Google Maps API key - shell: bash + - name: Run tests + uses: reactivecircus/android-emulator-runner@v2 env: GOOGLE_MAPS_KEY: ${{ inputs.google-maps-key }} - run: | - sed -E -i 's/("current_key": ")[[:alnum:]_-]+(")/\1'"$GOOGLE_MAPS_KEY"'\2/' app/src/debug/local/google-services.json - - - name: Move the local google-services.json - shell: bash - run: | - cp -r app/src/debug/local/google-services.json app/src/debug/ - - - name: Build projects and run instrumentation tests - uses: reactivecircus/android-emulator-runner@v2 with: - api-level: 24 + api-level: 35 target: google_apis_playstore + arch: x86_64 force-avd-creation: false emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' disable-animations: true script: | - firebase emulators:exec './gradlew :e2eTest:connectedLocalDebugAndroidTest --stacktrace' --config ground-platform/firebase.local.json --project local --import data/test-android --export-on-exit data/test-android + adb shell settings put secure location_mode 3 + adb shell settings put secure location_providers_allowed +gps + adb shell settings put secure location_providers_allowed +network + adb emu geo fix -122.084 37.4220 + sleep 2 + echo "Generated AVD snapshot for caching." - name: Upload test reports if: always() @@ -104,17 +113,14 @@ runs: with: name: test-reports path: '**/build/reports/androidTests' + retention-days: 7 + if-no-files-found: warn - - name: Move Firebase emulator data (avoids .gitignore) - shell: bash - run: mv data/test-android/ ./test-android - - - name: Copy Firebase emulator data - if: inputs.upload-artifacts == 'true' + - name: Upload test screenshots + if: always() uses: actions/upload-artifact@v4 with: - name: data-submit - path: '**/test-android' + name: test-screenshots + path: '**/build/outputs/connected_android_test_additional_output' retention-days: 7 - overwrite: true - if-no-files-found: error \ No newline at end of file + if-no-files-found: warn \ No newline at end of file diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 1b95392762..f8ca114f34 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -21,40 +21,22 @@ on: jobs: e2eTest: runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 45 + env: + FIREBASE_CLI_EXPERIMENTS: webframeworks steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Start test - run: | - echo "Begin end to end test" - - - startEmulator: - needs: e2eTest - name: Run the firebase emulator with prefilled data - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Run test-start-emulator + - name: Start Firebase emulator uses: google/ground-platform/.github/actions/start-emulator@master with: - upload-artifacts: true - - submitTest: - needs: startEmulator - name: Submit to survey - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout repository - uses: actions/checkout@v4 + token: ${{ secrets.PLATFORM_ACCESS_TOKEN }} - - name: Run submit-test - uses: ./.github/actions/submit-test + - name: Run E2E Tests + uses: google/ground-android/.github/actions/run-automation-tests@master with: + token: ${{ secrets.PLATFORM_ACCESS_TOKEN }} android-repository: ${{ github.repository }} google-maps-key: ${{ secrets.GOOGLE_MAPS_KEY }} - use-repo-data: true upload-artifacts: true diff --git a/.gitignore b/.gitignore index 7d9736a185..e6dda87116 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ secrets.properties !app/src/debug/local/google-services.json !.gitignore !gradle/ +!.github/ # Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore # From b6fcb6ea54eeea9e2d86c985a4bff5b2a2a066ab Mon Sep 17 00:00:00 2001 From: andreia Date: Wed, 14 Jan 2026 17:11:18 +0100 Subject: [PATCH 04/16] Update action and remove test-submit since it needs the firebase emulator to be running --- .../actions/run-automation-tests/action.yml | 34 +++++++++--------- .github/workflows/test-e2e.yml | 5 +-- .github/workflows/test-submit.yml | 35 ------------------- 3 files changed, 18 insertions(+), 56 deletions(-) delete mode 100644 .github/workflows/test-submit.yml diff --git a/.github/actions/run-automation-tests/action.yml b/.github/actions/run-automation-tests/action.yml index f4ee13b92d..deffe41d99 100644 --- a/.github/actions/run-automation-tests/action.yml +++ b/.github/actions/run-automation-tests/action.yml @@ -44,6 +44,17 @@ runs: exit 1 fi + - name: Validate MAPS_API_KEY + env: + MAPS_API_KEY: ${{ inputs.google-maps-key }} + shell: bash + run: | + if [ -z "${MAPS_API_KEY}" ]; then + echo "MAPS_API_KEY is missing from GitHub secrets" + exit 1 + fi + echo "MAPS_API_KEY is set" + - name: Set up JDK 21 uses: actions/setup-java@v4 with: @@ -67,10 +78,8 @@ runs: path: | ~/.android/avd/* ~/.android/adb* - key: avd-35-google_apis_playstore-x86_64 - - - name: Setup Gradle - uses: gradle/gradle-build-action@v3 + key: avd-35-google_apis_playstore-x86_64-v1 + restore-keys: avd-35-google_apis_playstore-x86_64- - name: create AVD and generate snapshot for caching if: steps.avd-cache.outputs.cache-hit != 'true' @@ -83,15 +92,10 @@ runs: emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' disable-animations: true script: | - adb shell settings put secure location_mode 3 - adb shell settings put secure location_providers_allowed +gps - adb shell settings put secure location_providers_allowed +network echo "Generated AVD snapshot for caching." - name: Run tests uses: reactivecircus/android-emulator-runner@v2 - env: - GOOGLE_MAPS_KEY: ${{ inputs.google-maps-key }} with: api-level: 35 target: google_apis_playstore @@ -100,15 +104,11 @@ runs: emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' disable-animations: true script: | - adb shell settings put secure location_mode 3 - adb shell settings put secure location_providers_allowed +gps - adb shell settings put secure location_providers_allowed +network - adb emu geo fix -122.084 37.4220 - sleep 2 - echo "Generated AVD snapshot for caching." + echo "MAPS_API_KEY=${{ inputs.google-maps-key }}" > secrets.properties + ./gradlew :e2eTest:connectedLocalDebugAndroidTest --stacktrace - name: Upload test reports - if: always() + if: ${{ inputs.upload-artifacts == 'true' }} uses: actions/upload-artifact@v4 with: name: test-reports @@ -117,7 +117,7 @@ runs: if-no-files-found: warn - name: Upload test screenshots - if: always() + if: ${{ inputs.upload-artifacts == 'true' }} uses: actions/upload-artifact@v4 with: name: test-screenshots diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index f8ca114f34..d4a4b97bcf 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -30,13 +30,10 @@ jobs: - name: Start Firebase emulator uses: google/ground-platform/.github/actions/start-emulator@master - with: - token: ${{ secrets.PLATFORM_ACCESS_TOKEN }} - name: Run E2E Tests uses: google/ground-android/.github/actions/run-automation-tests@master with: - token: ${{ secrets.PLATFORM_ACCESS_TOKEN }} android-repository: ${{ github.repository }} - google-maps-key: ${{ secrets.GOOGLE_MAPS_KEY }} + google-maps-key: ${{ secrets.MAPS_API_KEY }} upload-artifacts: true diff --git a/.github/workflows/test-submit.yml b/.github/workflows/test-submit.yml deleted file mode 100644 index 90a329a918..0000000000 --- a/.github/workflows/test-submit.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2024 The Ground Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -name: Submission Test - -on: - issue_comment: - types: [created] - -jobs: - submitTest: - if: github.event.issue.pull_request && contains(github.event.comment.body, '/submitTest') - name: Submit to survey - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout code - uses: actions/checkout@v6 - - name: Run submit-test - uses: ./.github/actions/submit-test - with: - android-repository: ${{ github.repository }} - google-maps-key: ${{ secrets.GOOGLE_MAPS_KEY }} - use-repo-data: true - upload-artifacts: false \ No newline at end of file From 80f95238deebd146dd49add6a7acd56f4eb1205b Mon Sep 17 00:00:00 2001 From: andreia Date: Wed, 14 Jan 2026 18:28:37 +0100 Subject: [PATCH 05/16] Add documentation --- .github/workflows/test-e2e.yml | 1 + docs/e2e-testing-doc.md | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/e2e-testing-doc.md diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index d4a4b97bcf..99730633a0 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -18,6 +18,7 @@ on: branches: - master +# See docs/e2e-testing-doc.md for details jobs: e2eTest: runs-on: ubuntu-latest diff --git a/docs/e2e-testing-doc.md b/docs/e2e-testing-doc.md new file mode 100644 index 0000000000..d69c72907b --- /dev/null +++ b/docs/e2e-testing-doc.md @@ -0,0 +1,35 @@ +# End to end testing on Android + +## Current setup + +The Android E2E tests rely on a predefined test survey created by the web application and stored in the Firebase emulator data + +### 1. Predefined test survey +The test data was originally generated by running the web application locally against the Firebase emulator and exporting the emulator state + +### 2. Running the E2E tests +The CI workflow performs the following steps: +1. Start the Firebase emulator using the `start-emulator` action (which loads the predefined data) +2. Run the Android instrumentation tests in the `e2eTest` module against the emulator + +## Managing test data + +Since the Android app relies on specific survey structures, changes to the survey schema may require updating the test data + +1. Clone `ground-platform` and set up the project (see [documentation](https://github.com/google/ground-platform)) +2. Run the following command to launch the local Firebase emulator with test data: + ```bash + nx start-android-test-data + ``` +3. Manually set up or update the survey (via the web UI) to match the scenarios expected by the Android `e2eTest` module +4. Verify that all tests pass locally using the `localDebug` build variant +5. Export the updated emulator data to persist changes: + ```bash + firebase emulators:export data/test-android --project demo-local + ``` + *Note: This overwrites the data in `data/test-android`.* + +## Limitations +This setup does not fully prevent data drift between the web and Android apps. Any structural changes in surveys require manual updates to the predefined test data. + +This could be improved by implementing web E2E tests that generate Firestore test data on each run and trigger the Android E2E tests. Optionally, the web tests could also verify the final persisted state. \ No newline at end of file From e6b279db153732ac04e0017ee4cfd669ceb6dbc5 Mon Sep 17 00:00:00 2001 From: andreia Date: Mon, 19 Jan 2026 18:03:37 +0100 Subject: [PATCH 06/16] Use espresso intents to mock camera in order to reduce flakiness --- e2eTest/build.gradle | 1 + e2eTest/src/main/assets/e2e_test_photo.webp | Bin 0 -> 594 bytes .../android/e2etest/TestConfig.kt | 1 + .../e2etest/drivers/AndroidTestDriver.kt | 38 ++++++++++++------ .../e2etest/robots/DataCollectionRobot.kt | 1 - .../e2etest/tests/CompleteAllTaskTypesTest.kt | 15 ++++++- gradle/libs.versions.toml | 1 + 7 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 e2eTest/src/main/assets/e2e_test_photo.webp diff --git a/e2eTest/build.gradle b/e2eTest/build.gradle index c710a8dd37..f76fbe1d9f 100644 --- a/e2eTest/build.gradle +++ b/e2eTest/build.gradle @@ -69,6 +69,7 @@ dependencies { implementation libs.androidx.appcompat implementation libs.androidx.core.ktx implementation libs.androidx.espresso.core + implementation libs.androidx.espresso.intents implementation libs.androidx.junit implementation libs.androidx.rules implementation libs.androidx.uiautomator diff --git a/e2eTest/src/main/assets/e2e_test_photo.webp b/e2eTest/src/main/assets/e2e_test_photo.webp new file mode 100644 index 0000000000000000000000000000000000000000..45449aa284b71a33530b0e22a48d398b2ef5b954 GIT binary patch literal 594 zcmV-Y0&AYlUt7(l`W0gJ~kzw7{HS7q0+XX3})|I^ap z%0{sN14>r|8QBy22B=I>{Ke`~ + intent.getParcelableExtra(MediaStore.EXTRA_OUTPUT)?.let { photoUri -> + val testContext = InstrumentationRegistry.getInstrumentation().context + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + + testContext.assets.open(TEST_PHOTO_FILE).use { input -> + appContext.contentResolver.openOutputStream(photoUri)?.use { output -> + input.copyTo(output) + } ?: error("Failed to open output stream for $photoUri") + } + } ?: error("photoUri is null") + Instrumentation.ActivityResult(Activity.RESULT_OK, Intent()) + } + + click(TestDriver.Target.ViewId(R.id.btn_camera)) } override fun setDate() { diff --git a/e2eTest/src/main/java/org/groundplatform/android/e2etest/robots/DataCollectionRobot.kt b/e2eTest/src/main/java/org/groundplatform/android/e2etest/robots/DataCollectionRobot.kt index 86605e8932..3ed98d4672 100644 --- a/e2eTest/src/main/java/org/groundplatform/android/e2etest/robots/DataCollectionRobot.kt +++ b/e2eTest/src/main/java/org/groundplatform/android/e2etest/robots/DataCollectionRobot.kt @@ -124,7 +124,6 @@ class DataCollectionRobot(override val testDriver: TestDriver) : Robot Date: Tue, 20 Jan 2026 17:54:42 +0100 Subject: [PATCH 07/16] Update action files with latest working version --- .../action.yml | 79 +++++++++---------- .github/workflows/ci.yml | 6 ++ .github/workflows/test-e2e.yml | 54 +++++++++---- .github/workflows/test-integration.yml | 41 ++++++++++ 4 files changed, 125 insertions(+), 55 deletions(-) rename .github/actions/{run-automation-tests => submit-survey}/action.yml (65%) create mode 100644 .github/workflows/test-integration.yml diff --git a/.github/actions/run-automation-tests/action.yml b/.github/actions/submit-survey/action.yml similarity index 65% rename from .github/actions/run-automation-tests/action.yml rename to .github/actions/submit-survey/action.yml index deffe41d99..0685c6113f 100644 --- a/.github/actions/run-automation-tests/action.yml +++ b/.github/actions/submit-survey/action.yml @@ -32,6 +32,7 @@ runs: uses: actions/checkout@v6 with: repository: ${{ inputs.android-repository }} + clean: false - name: Check Firebase emulator connection shell: bash @@ -44,7 +45,7 @@ runs: exit 1 fi - - name: Validate MAPS_API_KEY + - name: Validate and setup MAPS_API_KEY env: MAPS_API_KEY: ${{ inputs.google-maps-key }} shell: bash @@ -54,12 +55,7 @@ runs: exit 1 fi echo "MAPS_API_KEY is set" - - - name: Set up JDK 21 - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '21' + echo "MAPS_API_KEY=${{ secrets.MAPS_API_KEY }}" > secrets.properties - name: Enable KVM group perms shell: bash @@ -68,48 +64,32 @@ runs: sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm - - name: Gradle cache - uses: gradle/actions/setup-gradle@v3 - - - name: AVD cache - uses: actions/cache@v4 - id: avd-cache + - name: Setup JDK 17 + uses: actions/setup-java@v5 with: - path: | - ~/.android/avd/* - ~/.android/adb* - key: avd-35-google_apis_playstore-x86_64-v1 - restore-keys: avd-35-google_apis_playstore-x86_64- + distribution: 'temurin' + java-version: 17 - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 35 - target: google_apis_playstore - arch: x86_64 - force-avd-creation: true - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' - disable-animations: true - script: | - echo "Generated AVD snapshot for caching." + - name: Gradle cache + uses: gradle/actions/setup-gradle@v5 - name: Run tests uses: reactivecircus/android-emulator-runner@v2 with: - api-level: 35 - target: google_apis_playstore + api-level: 30 + target: google_apis arch: x86_64 - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back emulated -logcat '*:e' + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none disable-animations: true script: | - echo "MAPS_API_KEY=${{ inputs.google-maps-key }}" > secrets.properties - ./gradlew :e2eTest:connectedLocalDebugAndroidTest --stacktrace + adb wait-for-device + adb emu geo fix -122.084 37.422 + sleep 2 + ./gradlew connectedLocalDebugAndroidTest --stacktrace - name: Upload test reports - if: ${{ inputs.upload-artifacts == 'true' }} - uses: actions/upload-artifact@v4 + if: always() + uses: actions/upload-artifact@v6 with: name: test-reports path: '**/build/reports/androidTests' @@ -117,10 +97,27 @@ runs: if-no-files-found: warn - name: Upload test screenshots - if: ${{ inputs.upload-artifacts == 'true' }} - uses: actions/upload-artifact@v4 + if: always() + uses: actions/upload-artifact@v6 with: name: test-screenshots path: '**/build/outputs/connected_android_test_additional_output' retention-days: 7 - if-no-files-found: warn \ No newline at end of file + if-no-files-found: ignore + + - name: Export Firebase emulator data + if: always() + working-directory: ground-platform + shell: bash + run: | + echo "Exporting emulator data..." + npx firebase emulators:export ${{ github.workspace }}/test-android-result --project demo-local --force + + - name: Upload Firebase emulator data + if: always() && inputs.upload-artifacts == 'true' + uses: actions/upload-artifact@v6 + with: + name: firebase-emulator-data + path: ${{ github.workspace }}/test-android-result + retention-days: 7 + if-no-files-found: warn diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cae4d3de85..8386d2c24b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,3 +54,9 @@ jobs: curl -Os https://uploader.codecov.io/latest/linux/codecov chmod +x codecov ./codecov --verbose upload-process --fail-on-error -t ${{ secrets.CODECOV_TOKEN }} -n 'service'-${{ github.run_id }} -F service -f app/build/reports/jacoco/jacocoLocalDebugUnitTestReport/jacocoLocalDebugUnitTestReport.xml + + instrumentation-tests: + needs: build + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + uses: ./.github/workflows/test-integration.yml + secrets: inherit diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 99730633a0..b18210be95 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -14,27 +14,53 @@ name: End to End Test on: - push: - branches: - - master + issue_comment: + types: [created] -# See docs/e2e-testing-doc.md for details jobs: e2eTest: runs-on: ubuntu-latest - timeout-minutes: 45 - env: - FIREBASE_CLI_EXPERIMENTS: webframeworks + timeout-minutes: 15 + if: github.event.issue.pull_request && contains(github.event.comment.body, '/e2eTest') steps: - - name: Checkout repository - uses: actions/checkout@v6 + - name: Start test + run: | + echo "Begin end to end test" - - name: Start Firebase emulator - uses: google/ground-platform/.github/actions/start-emulator@master - - name: Run E2E Tests - uses: google/ground-android/.github/actions/run-automation-tests@master + createTest: + needs: e2eTest + name: Create a new survey + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Run create-test + uses: google/ground-platform/.github/actions/create-test@master + with: + upload-artifacts: true + + submitTest: + needs: createTest + name: Submit to survey + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Run submit-test + uses: ./.github/actions/submit-test with: android-repository: ${{ github.repository }} - google-maps-key: ${{ secrets.MAPS_API_KEY }} + google-maps-key: ${{ secrets.GOOGLE_MAPS_KEY }} + use-repo-data: false upload-artifacts: true + + + verifyTest: + needs: submitTest + name: Verify survey submissions + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Run verify-test + uses: google/ground-platform/.github/actions/verify-test@master + with: + use-repo-data: false \ No newline at end of file diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml new file mode 100644 index 0000000000..db7d1dce7d --- /dev/null +++ b/.github/workflows/test-integration.yml @@ -0,0 +1,41 @@ +# Copyright 2026 The Ground Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +name: Run integration tests + +on: + workflow_dispatch: + workflow_call: + +jobs: + run-instrumentation-tests: + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + FIREBASE_CLI_EXPERIMENTS: webframeworks + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Start Firebase emulator + uses: google/ground-platform/.github/actions/start-emulator@master + + - name: Run Android tests on e2eTest module + uses: google/ground-android/.github/actions/submit-survey@master + with: + android-repository: ${{ github.repository }} + upload-artifacts: true + google-maps-key: ${{ secrets.MAPS_API_KEY }} + + From dba9dfe4676d2d284b138a1dec97a992bdac19b1 Mon Sep 17 00:00:00 2001 From: andreia Date: Tue, 20 Jan 2026 17:56:59 +0100 Subject: [PATCH 08/16] Remove flaky draw area test --- .../e2etest/tests/CompleteAllTaskTypesTest.kt | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/e2eTest/src/main/java/org/groundplatform/android/e2etest/tests/CompleteAllTaskTypesTest.kt b/e2eTest/src/main/java/org/groundplatform/android/e2etest/tests/CompleteAllTaskTypesTest.kt index 9d45145803..1baa1b276a 100644 --- a/e2eTest/src/main/java/org/groundplatform/android/e2etest/tests/CompleteAllTaskTypesTest.kt +++ b/e2eTest/src/main/java/org/groundplatform/android/e2etest/tests/CompleteAllTaskTypesTest.kt @@ -19,7 +19,6 @@ import org.groundplatform.android.e2etest.robots.SignInRobot import org.groundplatform.android.e2etest.robots.SurveySelectorRobot import org.groundplatform.android.e2etest.robots.TermsOfServiceRobot import org.groundplatform.android.ui.main.MainActivity -import org.groundplatform.android.ui.map.gms.features.TEST_MARKER_TAG import org.junit.After import org.junit.Before import org.junit.Rule @@ -91,18 +90,6 @@ class CompleteAllTaskTypesTest { dismissInstructions() runTasks(TestConfig.TEST_LIST_ALL_TASK_TYPES_EXCEPT_DRAW_AREA) } - // Remove previous LOI and add new one to test DRAW_AREA - with(HomeScreenRobot(testDriver)) { - moveMap() - recenter() - deleteLoi(TEST_MARKER_TAG) - addLoi() - selectJob(TestConfig.TEST_JOB_DRAW_AREA) - } - with(DataCollectionRobot(testDriver)) { - dismissInstructions() - runTasks(TestConfig.TEST_LIST_DRAW_AREA) - } } private fun captureScreenshot() { From 2af8867ae846446e338effef4180542ddb16c3c4 Mon Sep 17 00:00:00 2001 From: andreia Date: Tue, 20 Jan 2026 18:58:47 +0100 Subject: [PATCH 09/16] rename files and update docs --- .github/workflows/ci.yml | 2 +- .github/workflows/test-e2e.yml | 56 ++++----------- .github/workflows/test-integration.yml | 41 ----------- docs/e2e-testing-doc.md | 69 +++++++++++-------- .../android/e2etest/TestConfig.kt | 7 ++ 5 files changed, 65 insertions(+), 110 deletions(-) delete mode 100644 .github/workflows/test-integration.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8386d2c24b..45f8af387c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,5 +58,5 @@ jobs: instrumentation-tests: needs: build if: github.event_name == 'push' && github.ref == 'refs/heads/master' - uses: ./.github/workflows/test-integration.yml + uses: ./.github/workflows/test-e2e.yml secrets: inherit diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index b18210be95..27c27376e2 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -14,53 +14,27 @@ name: End to End Test on: - issue_comment: - types: [created] + workflow_dispatch: + workflow_call: jobs: - e2eTest: + run-instrumentation-tests: runs-on: ubuntu-latest - timeout-minutes: 15 - if: github.event.issue.pull_request && contains(github.event.comment.body, '/e2eTest') - steps: - - name: Start test - run: | - echo "Begin end to end test" - + timeout-minutes: 30 + env: + FIREBASE_CLI_EXPERIMENTS: webframeworks - createTest: - needs: e2eTest - name: Create a new survey - runs-on: ubuntu-latest - timeout-minutes: 10 + # See docs/e2e-testing-doc.md for details on how this is setup steps: - - name: Run create-test - uses: google/ground-platform/.github/actions/create-test@master - with: - upload-artifacts: true + - name: Checkout repository + uses: actions/checkout@v6 - submitTest: - needs: createTest - name: Submit to survey - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Run submit-test - uses: ./.github/actions/submit-test + - name: Start Firebase emulator + uses: google/ground-platform/.github/actions/start-emulator@master + + - name: Run Android tests on e2eTest module + uses: google/ground-android/.github/actions/submit-survey@master with: android-repository: ${{ github.repository }} - google-maps-key: ${{ secrets.GOOGLE_MAPS_KEY }} - use-repo-data: false upload-artifacts: true - - - verifyTest: - needs: submitTest - name: Verify survey submissions - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Run verify-test - uses: google/ground-platform/.github/actions/verify-test@master - with: - use-repo-data: false \ No newline at end of file + google-maps-key: ${{ secrets.MAPS_API_KEY }} \ No newline at end of file diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml deleted file mode 100644 index db7d1dce7d..0000000000 --- a/.github/workflows/test-integration.yml +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2026 The Ground Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -name: Run integration tests - -on: - workflow_dispatch: - workflow_call: - -jobs: - run-instrumentation-tests: - runs-on: ubuntu-latest - timeout-minutes: 30 - env: - FIREBASE_CLI_EXPERIMENTS: webframeworks - - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Start Firebase emulator - uses: google/ground-platform/.github/actions/start-emulator@master - - - name: Run Android tests on e2eTest module - uses: google/ground-android/.github/actions/submit-survey@master - with: - android-repository: ${{ github.repository }} - upload-artifacts: true - google-maps-key: ${{ secrets.MAPS_API_KEY }} - - diff --git a/docs/e2e-testing-doc.md b/docs/e2e-testing-doc.md index d69c72907b..adc93c1c66 100644 --- a/docs/e2e-testing-doc.md +++ b/docs/e2e-testing-doc.md @@ -1,35 +1,50 @@ -# End to end testing on Android +# End-to-End (E2E) testing on Android ## Current setup -The Android E2E tests rely on a predefined test survey created by the web application and stored in the Firebase emulator data +The Android E2E tests rely on a predefined test survey created by the web application and stored in +the Firebase emulator data ### 1. Predefined test survey -The test data was originally generated by running the web application locally against the Firebase emulator and exporting the emulator state - -### 2. Running the E2E tests -The CI workflow performs the following steps: -1. Start the Firebase emulator using the `start-emulator` action (which loads the predefined data) -2. Run the Android instrumentation tests in the `e2eTest` module against the emulator - -## Managing test data - -Since the Android app relies on specific survey structures, changes to the survey schema may require updating the test data - -1. Clone `ground-platform` and set up the project (see [documentation](https://github.com/google/ground-platform)) -2. Run the following command to launch the local Firebase emulator with test data: - ```bash - nx start-android-test-data - ``` -3. Manually set up or update the survey (via the web UI) to match the scenarios expected by the Android `e2eTest` module -4. Verify that all tests pass locally using the `localDebug` build variant -5. Export the updated emulator data to persist changes: - ```bash - firebase emulators:export data/test-android --project demo-local - ``` - *Note: This overwrites the data in `data/test-android`.* + +The test data was originally generated by running the web application locally against the Firebase +emulator and exporting the emulator state. This ensures a consistent starting state for tests + +### 2. Test Execution Flow + +The CI workflow (and local execution) follows these steps: + +1. **Start Firebase Emulator**: Loads the predefined data +2. **Run Tests**: Executes Android instrumentation tests in the `e2eTest` module against the + emulator + +## Managing test data and local testing + +### Running tests locally +1. Clone `ground-platform` and set up the project according to the [documentation](https://github.com/google/ground-platform) +2. Run the following command to launch the local Firebase emulator with test data: + ```bash + # From the ground-platform directory + nx start-android-test-data + ``` +3. Run all tests on `e2eTest` module using the `localDebug` build variant + +### Updating test data +Since the Android app relies on specific survey structures, changes to the survey schema may require +updating the test data. Follow the steps in "Running tests locally" above, then: +1. Manually set up or update the survey (via the web UI) to match the scenarios expected by the Android `e2eTest` module. +2. Verify that all tests pass locally using the `localDebug` build variant +3. Export the updated emulator data to persist changes: + ```bash + firebase emulators:export data/test-android --project demo-local + ``` + *Note: This overwrites the data in `data/test-android`.* ## Limitations -This setup does not fully prevent data drift between the web and Android apps. Any structural changes in surveys require manual updates to the predefined test data. -This could be improved by implementing web E2E tests that generate Firestore test data on each run and trigger the Android E2E tests. Optionally, the web tests could also verify the final persisted state. \ No newline at end of file +This setup does not fully prevent data drift between the web and Android apps. Any structural +changes in surveys require manual updates to the predefined test data. + +This could be improved by implementing web E2E tests that generate Firestore test data on each run +and trigger the Android E2E tests. Optionally, the web tests could also verify the final persisted +state. \ No newline at end of file diff --git a/e2eTest/src/main/java/org/groundplatform/android/e2etest/TestConfig.kt b/e2eTest/src/main/java/org/groundplatform/android/e2etest/TestConfig.kt index fa9fae9b37..60b31f7554 100644 --- a/e2eTest/src/main/java/org/groundplatform/android/e2etest/TestConfig.kt +++ b/e2eTest/src/main/java/org/groundplatform/android/e2etest/TestConfig.kt @@ -17,6 +17,13 @@ package org.groundplatform.android.e2etest import org.groundplatform.android.model.task.Task +/** + * This file contains configuration constants and test data for the E2E tests. All surveys, jobs, + * tasks, and other test data here must match the corresponding entries in the local Firebase + * emulator. Mismatched values may cause E2E tests to fail. + * + * For more details on how E2E tests work see: docs/e2e-testing-doc.md + */ object TestConfig { const val DEFAULT_TIMEOUT = 10000L const val SURVEY_NAME = "Ground app E2E test" From 1ce4fbcb96fe8934cd25c74f7be50202ec648c52 Mon Sep 17 00:00:00 2001 From: andreia Date: Tue, 20 Jan 2026 19:16:19 +0100 Subject: [PATCH 10/16] fix namings --- .github/actions/{submit-survey => submit-test}/action.yml | 4 ++-- .github/workflows/test-e2e.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename .github/actions/{submit-survey => submit-test}/action.yml (97%) diff --git a/.github/actions/submit-survey/action.yml b/.github/actions/submit-test/action.yml similarity index 97% rename from .github/actions/submit-survey/action.yml rename to .github/actions/submit-test/action.yml index 0685c6113f..5d1e7d3250 100644 --- a/.github/actions/submit-survey/action.yml +++ b/.github/actions/submit-test/action.yml @@ -1,4 +1,4 @@ -# Copyright 2025 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -name: Run all automated tests in the e2eTeest module +name: Run all tests in the e2eTest module inputs: android-repository: diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 27c27376e2..2a87e0bd55 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -33,7 +33,7 @@ jobs: uses: google/ground-platform/.github/actions/start-emulator@master - name: Run Android tests on e2eTest module - uses: google/ground-android/.github/actions/submit-survey@master + uses: google/ground-android/.github/actions/submit-test@master with: android-repository: ${{ github.repository }} upload-artifacts: true From 3c12a8d544ccabe780feba04d6313753dc4e8ed1 Mon Sep 17 00:00:00 2001 From: andreia Date: Tue, 20 Jan 2026 20:01:14 +0100 Subject: [PATCH 11/16] add workflow permissions --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45f8af387c..7297025c53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,3 +60,5 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/master' uses: ./.github/workflows/test-e2e.yml secrets: inherit + permissions: + contents: read From b322ea3f962044765b3c64ac093a9cfb86f1f202 Mon Sep 17 00:00:00 2001 From: andreia Date: Wed, 21 Jan 2026 12:20:35 +0100 Subject: [PATCH 12/16] update permissions in the workflow --- .github/workflows/ci.yml | 5 ++--- .github/workflows/test-e2e.yml | 7 +++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7297025c53..70abb4fa3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,5 @@ jobs: needs: build if: github.event_name == 'push' && github.ref == 'refs/heads/master' uses: ./.github/workflows/test-e2e.yml - secrets: inherit - permissions: - contents: read + secrets: + MAPS_API_KEY: ${{ secrets.MAPS_API_KEY }} diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 2a87e0bd55..4c47727ef2 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -16,6 +16,13 @@ name: End to End Test on: workflow_dispatch: workflow_call: + secrets: + MAPS_API_KEY: + required: true + +permissions: + contents: read + actions: write jobs: run-instrumentation-tests: From cdecec5c642a6807901b5d1747a7136f81adb700 Mon Sep 17 00:00:00 2001 From: andreia Date: Wed, 21 Jan 2026 13:33:10 +0100 Subject: [PATCH 13/16] remove uneeded actions:write --- .github/workflows/test-e2e.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 4c47727ef2..eb1f45b459 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -22,7 +22,6 @@ on: permissions: contents: read - actions: write jobs: run-instrumentation-tests: From 563ec59e11b70f5a2380ac1ee71ee696abdcb497 Mon Sep 17 00:00:00 2001 From: andreia Date: Wed, 21 Jan 2026 17:46:34 +0100 Subject: [PATCH 14/16] remove working directory --- .github/actions/submit-test/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/actions/submit-test/action.yml b/.github/actions/submit-test/action.yml index 5d1e7d3250..c4b1b078cd 100644 --- a/.github/actions/submit-test/action.yml +++ b/.github/actions/submit-test/action.yml @@ -107,7 +107,6 @@ runs: - name: Export Firebase emulator data if: always() - working-directory: ground-platform shell: bash run: | echo "Exporting emulator data..." From 82acca04079d78c47b1aa525ae5ebe6179fe34ea Mon Sep 17 00:00:00 2001 From: andreia Date: Thu, 22 Jan 2026 10:28:38 +0100 Subject: [PATCH 15/16] update firebase export command --- .github/actions/submit-test/action.yml | 2 +- .github/workflows/ci.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/submit-test/action.yml b/.github/actions/submit-test/action.yml index c4b1b078cd..636958c051 100644 --- a/.github/actions/submit-test/action.yml +++ b/.github/actions/submit-test/action.yml @@ -110,7 +110,7 @@ runs: shell: bash run: | echo "Exporting emulator data..." - npx firebase emulators:export ${{ github.workspace }}/test-android-result --project demo-local --force + npx -y -p firebase-tools firebase emulators:export ${{ github.workspace }}/test-android-result --project demo-local --force - name: Upload Firebase emulator data if: always() && inputs.upload-artifacts == 'true' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70abb4fa3d..ef580d9247 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,3 +61,5 @@ jobs: uses: ./.github/workflows/test-e2e.yml secrets: MAPS_API_KEY: ${{ secrets.MAPS_API_KEY }} + permissions: + contents: read From 050029a3944610132dc50571cfceac58564301ad Mon Sep 17 00:00:00 2001 From: andreia Date: Fri, 23 Jan 2026 11:28:39 +0100 Subject: [PATCH 16/16] minor text adjustments --- .gitignore | 1 - docs/e2e-testing-doc.md | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index e6dda87116..7d9736a185 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ secrets.properties !app/src/debug/local/google-services.json !.gitignore !gradle/ -!.github/ # Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore # diff --git a/docs/e2e-testing-doc.md b/docs/e2e-testing-doc.md index adc93c1c66..b810fcc27d 100644 --- a/docs/e2e-testing-doc.md +++ b/docs/e2e-testing-doc.md @@ -32,13 +32,13 @@ The CI workflow (and local execution) follows these steps: ### Updating test data Since the Android app relies on specific survey structures, changes to the survey schema may require updating the test data. Follow the steps in "Running tests locally" above, then: -1. Manually set up or update the survey (via the web UI) to match the scenarios expected by the Android `e2eTest` module. +1. Manually set up or update the survey to match the scenarios expected by the Android `e2eTest` module 2. Verify that all tests pass locally using the `localDebug` build variant 3. Export the updated emulator data to persist changes: ```bash firebase emulators:export data/test-android --project demo-local ``` - *Note: This overwrites the data in `data/test-android`.* + *Note: This overwrites the data in `data/test-android`* ## Limitations