summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/android.yml37
-rw-r--r--android-app/app/src/androidTest/kotlin/org/terst/nav/MainActivitySmokeTest.kt29
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt16
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)