diff options
3 files changed, 78 insertions, 4 deletions
diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 78584dc..701b6c4 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v4 - + - name: Set up JDK 17 uses: actions/setup-java@v4 with: @@ -24,7 +24,7 @@ jobs: run: chmod +x android-app/gradlew - name: Build with Gradle - run: ./gradlew assembleDebug + run: ./gradlew assembleDebug assembleDebugAndroidTest working-directory: android-app - name: Upload artifact @@ -41,3 +41,36 @@ jobs: serviceCredentialsFileContent: ${{ secrets.CREDENTIAL_FILE_CONTENT }} groups: testers file: android-app/app/build/outputs/apk/debug/app-debug.apk + + smoke-test: + runs-on: ubuntu-latest + # Run after build succeeds so we don't spin up an emulator for a broken build + needs: build + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x android-app/gradlew + + - name: Enable KVM (faster emulator) + 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: Run smoke tests on emulator + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 30 + arch: x86_64 + profile: pixel_3a + script: ./gradlew connectedDebugAndroidTest + working-directory: android-app diff --git a/android-app/app/src/androidTest/kotlin/org/terst/nav/MainActivitySmokeTest.kt b/android-app/app/src/androidTest/kotlin/org/terst/nav/MainActivitySmokeTest.kt new file mode 100644 index 0000000..fec571a --- /dev/null +++ b/android-app/app/src/androidTest/kotlin/org/terst/nav/MainActivitySmokeTest.kt @@ -0,0 +1,29 @@ +package org.terst.nav + +import androidx.test.core.app.ActivityScenario +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Smoke test: verifies MainActivity launches without crashing. + * + * Run on an emulator/device via: + * ./gradlew connectedDebugAndroidTest + * + * In CI, requires an emulator step before the Gradle task. + */ +@RunWith(AndroidJUnit4::class) +class MainActivitySmokeTest { + + @Test + fun mainActivity_launches_withoutCrash() { + ActivityScenario.launch(MainActivity::class.java).use { scenario -> + // If we reach this line the activity started without throwing. + // onActivity lets us assert it is in a resumed state. + scenario.onActivity { activity -> + assert(!activity.isFinishing) { "MainActivity finished immediately after launch" } + } + } + } +} diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt index a6c063b..aa35914 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt @@ -2,6 +2,8 @@ package org.terst.nav import android.Manifest import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.graphics.Canvas import android.graphics.BitmapFactory import android.location.Location import android.media.MediaPlayer @@ -516,8 +518,18 @@ class MainActivity : AppCompatActivity() { } private fun setupTidalCurrentMapLayers(style: Style) { - // Add tidal arrow icon - style.addImage(TIDAL_ARROW_ICON_ID, BitmapFactory.decodeResource(resources, R.drawable.ic_tidal_arrow)) + // Add tidal arrow icon (vector drawable — must rasterise manually; BitmapFactory returns null for VDs) + val tidalArrowDrawable = ContextCompat.getDrawable(this, R.drawable.ic_tidal_arrow) ?: return + val tidalArrowBitmap = Bitmap.createBitmap( + tidalArrowDrawable.intrinsicWidth.coerceAtLeast(24), + tidalArrowDrawable.intrinsicHeight.coerceAtLeast(24), + Bitmap.Config.ARGB_8888 + ) + Canvas(tidalArrowBitmap).also { canvas -> + tidalArrowDrawable.setBounds(0, 0, canvas.width, canvas.height) + tidalArrowDrawable.draw(canvas) + } + style.addImage(TIDAL_ARROW_ICON_ID, tidalArrowBitmap) // Create source tidalCurrentSource = GeoJsonSource(TIDAL_CURRENT_SOURCE_ID) |
