Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions .github/workflows/demo-smoke-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Copyright 2026 Google LLC
#
# 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
#
# http://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.

# Opens every ApiDemos demo on an emulator and checks that it starts, its map or panorama loads,
# and it survives a zoom and a configuration change. The tests live in the `smoke` package of each
# app's androidTest sources and are excluded from the instrumentation workflow.
#
# Like the instrumentation workflow, this needs the ACTIONS_API_KEY secret and is skipped
# without it.
name: Demo smoke test

on:
pull_request:
branches-ignore: ['gh-pages']
workflow_dispatch:

permissions:
contents: read

jobs:
# secrets cannot be referenced from a job-level `if`, so the presence of the
# key is resolved here and published as an output the emulator job gates on.
check-api-key:
runs-on: ubuntu-latest
outputs:
has-key: ${{ steps.check.outputs.has-key }}
steps:
- name: Check for Maps API key
id: check
env:
MAPS_API_KEY: ${{ secrets.ACTIONS_API_KEY }}
run: |
if [ -n "$MAPS_API_KEY" ]; then
echo "has-key=true" >> "$GITHUB_OUTPUT"
else
echo "has-key=false" >> "$GITHUB_OUTPUT"
echo "::notice::ACTIONS_API_KEY is not set; skipping the demo smoke test."
fi

demo-smoke-test:
needs: check-api-key
if: needs.check-api-key.outputs.has-key == 'true'
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- module: ':ApiDemos:java-app'
path: ApiDemos/project/java-app
smoke-package: com.example.mapdemo.smoke
- module: ':ApiDemos:kotlin-app'
path: ApiDemos/project/kotlin-app
smoke-package: com.example.kotlindemos.smoke

steps:
- name: Checkout Repo
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up JDK 21
uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0

- name: Enable KVM
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: Inject Maps API key
env:
MAPS_API_KEY: ${{ secrets.ACTIONS_API_KEY }}
run: echo "MAPS_API_KEY=$MAPS_API_KEY" >> ./secrets.properties

- name: Build demo and test APKs
run: ./gradlew ${{ matrix.module }}:assembleDebug ${{ matrix.module }}:assembleDebugAndroidTest --stacktrace

- name: Run demo smoke test
uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2.38.0
with:
# Emulators never update Google Play services, so the image's bundled version is what
# the maps run on. Older images bundle a version where adding advanced markers crashes
# inside Play services. API 36 images bundle 25.26, which works.
api-level: 36
target: google_apis
arch: x86_64
disable-animations: true
script: >-
./gradlew ${{ matrix.module }}:connectedDebugAndroidTest --stacktrace
-Pandroid.testInstrumentationRunnerArguments.package=${{ matrix.smoke-package }}
-Pandroid.testInstrumentationRunnerArguments.requireMapLoaded=true

- name: Upload test reports
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: demo-smoke-test-reports-${{ strategy.job-index }}
path: |
${{ matrix.path }}/build/reports/androidTests
${{ matrix.path }}/build/outputs/androidTest-results
if-no-files-found: warn
13 changes: 9 additions & 4 deletions .github/workflows/instrumentation-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ jobs:
strategy:
fail-fast: false
matrix:
module:
- ':ApiDemos:java-app'
- ':ApiDemos:kotlin-app'
include:
- module: ':ApiDemos:java-app'
smoke-package: com.example.mapdemo.smoke
- module: ':ApiDemos:kotlin-app'
smoke-package: com.example.kotlindemos.smoke

steps:
- name: Checkout Repo
Expand Down Expand Up @@ -100,7 +102,10 @@ jobs:
target: google_apis
arch: x86
disable-animations: true
script: ./gradlew ${{ matrix.module }}:connectedDebugAndroidTest --stacktrace
# The demo smoke tests run in their own workflow on a newer emulator image.
script: >-
./gradlew ${{ matrix.module }}:connectedDebugAndroidTest --stacktrace
-Pandroid.testInstrumentationRunnerArguments.notPackage=${{ matrix.smoke-package }}

- name: Upload test reports
if: always()
Expand Down
11 changes: 11 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ demonstrate the same features and must stay in sync.
python3 scripts/update_docs_versions.py --check # verify doc snippet versions match version catalog
```

- **ApiDemos smoke test** (emulator, needs a real API key): opens every demo activity and checks
that its map loads and that it survives a zoom and a configuration change. New demos are picked
up from the manifest automatically.
```bash
./gradlew :ApiDemos:kotlin-app:connectedDebugAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.package=com.example.kotlindemos.smoke \
-Pandroid.testInstrumentationRunnerArguments.requireMapLoaded=true
```
For the Java app use `:ApiDemos:java-app` and `com.example.mapdemo.smoke`. Demos that need a
map ID are skipped unless `MAP_ID` is set.

Snippet modules do not contain unit tests; they are verified through successful compilation (`assembleDebug`), Android lint (`lintDebug`), and doc version synchronization.

Running the apps requires a Maps API key: copy the keys named in
Expand Down
9 changes: 9 additions & 0 deletions ApiDemos/project/java-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ android {
versionName = libs.versions.versionName.get()
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// Start every instrumented test from a clean app state.
testInstrumentationRunnerArguments["clearPackageData"] = "true"
}

buildFeatures {
Expand All @@ -55,6 +57,11 @@ android {

namespace = "com.example.mapdemo"

testOptions {
// Each test runs in its own process, so a crashing demo does not abort the rest of the run.
execution = "ANDROIDX_TEST_ORCHESTRATOR"
}

lint {
disable += setOf("MissingInflatedId")
sarifOutput = layout.buildDirectory.file("reports/lint-results-debug.sarif").get().asFile
Expand All @@ -79,6 +86,8 @@ dependencies {
androidTestImplementation(libs.junit)
androidTestImplementation(libs.espresso.core)
androidTestImplementation(libs.truth)
androidTestImplementation(libs.androidx.test.rules)
androidTestUtil(libs.androidx.test.orchestrator)
androidTestImplementation(libs.ext.junit)
}

Expand Down
Loading
Loading