diff --git a/build.gradle.kts b/build.gradle.kts index 7985a55486..60045e073f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -70,7 +70,8 @@ apiValidation { "sentry-uitest-android-benchmark", "test-app-plain", "test-app-sentry", - "sentry-samples-netflix-dgs" + "sentry-samples-netflix-dgs", + "sentry-uitest-android-critical" ) ) } diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/.gitignore b/sentry-android-integration-tests/sentry-uitest-android-critical/.gitignore new file mode 100644 index 0000000000..48fc28dcf5 --- /dev/null +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/.gitignore @@ -0,0 +1,2 @@ +/build +/maestro-logs diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts b/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts new file mode 100644 index 0000000000..48e57835e3 --- /dev/null +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts @@ -0,0 +1,58 @@ +import io.gitlab.arturbosch.detekt.Detekt + +plugins { + id("com.android.application") + kotlin("android") +} + +android { + compileSdk = Config.Android.compileSdkVersion + namespace = "io.sentry.uitest.android.critical" + + defaultConfig { + applicationId = "io.sentry.uitest.android.critical" + minSdk = 21 + targetSdk = Config.Android.targetSdkVersion + versionCode = 1 + versionName = "1.0" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = Config.androidComposeCompilerVersion + } +} + +dependencies { + implementation(kotlin(Config.kotlinStdLib, org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION)) + implementation(Config.Libs.androidxCore) + implementation(Config.Libs.composeActivity) + implementation(Config.Libs.composeFoundation) + implementation(Config.Libs.composeMaterial) + implementation(Config.Libs.constraintLayout) + implementation(projects.sentryAndroidCore) +} + +tasks.withType { + // Target version of the generated JVM bytecode. It is used for type resolution. + jvmTarget = JavaVersion.VERSION_1_8.toString() +} + +kotlin { + explicitApi() +} + diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/maestro/corruptEnvelope.yaml b/sentry-android-integration-tests/sentry-uitest-android-critical/maestro/corruptEnvelope.yaml new file mode 100644 index 0000000000..dec889731b --- /dev/null +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/maestro/corruptEnvelope.yaml @@ -0,0 +1,11 @@ +appId: io.sentry.uitest.android.critical +--- +- launchApp +- tapOn: "Write Corrupted Envelope" +# The close here ensures the next corrupted envelope +# will be present on the next app launch +- tapOn: "Close SDK" +- tapOn: "Write Corrupted Envelope" +- stopApp +- launchApp +- assertVisible: "Welcome!" diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/maestro/crash.yaml b/sentry-android-integration-tests/sentry-uitest-android-critical/maestro/crash.yaml new file mode 100644 index 0000000000..f9543f365c --- /dev/null +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/maestro/crash.yaml @@ -0,0 +1,6 @@ +appId: io.sentry.uitest.android.critical +--- +- launchApp +- tapOn: "Crash" +- launchApp +- assertVisible: "Welcome!" diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/src/main/AndroidManifest.xml b/sentry-android-integration-tests/sentry-uitest-android-critical/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..0ab5e6052d --- /dev/null +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/src/main/java/io/sentry/uitest/android/critical/MainActivity.kt b/sentry-android-integration-tests/sentry-uitest-android-critical/src/main/java/io/sentry/uitest/android/critical/MainActivity.kt new file mode 100644 index 0000000000..8802f3dca2 --- /dev/null +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/src/main/java/io/sentry/uitest/android/critical/MainActivity.kt @@ -0,0 +1,51 @@ +package io.sentry.uitest.android.critical + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import io.sentry.Sentry +import java.io.File + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val outboxPath = Sentry.getCurrentHub().options.outboxPath + ?: throw RuntimeException("Outbox path is not set.") + + setContent { + MaterialTheme { + Surface() { + Column() { + Text(text = "Welcome!") + Button(onClick = { + throw RuntimeException("Crash the test app.") + }) { + Text("Crash") + } + Button(onClick = { + Sentry.close() + }) { + Text("Close SDK") + } + Button(onClick = { + val file = File(outboxPath, "corrupted.envelope") + val corruptedEnvelopeContent = """ + {"event_id":"1990b5bc31904b7395fd07feb72daf1c","sdk":{"name":"sentry.java.android","version":"7.21.0"}} + {"type":"test","length":50} + """.trimIndent() + file.writeText(corruptedEnvelopeContent) + println("Wrote corrupted envelope to: ${file.absolutePath}") + }) { + Text("Write Corrupted Envelope") + } + } + } + } + } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 760c6e6905..77b3be021d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -61,6 +61,7 @@ include( "sentry-samples:sentry-samples-spring-boot-webflux", "sentry-samples:sentry-samples-spring-boot-webflux-jakarta", "sentry-samples:sentry-samples-netflix-dgs", + "sentry-android-integration-tests:sentry-uitest-android-critical", "sentry-android-integration-tests:sentry-uitest-android-benchmark", "sentry-android-integration-tests:sentry-uitest-android", "sentry-android-integration-tests:test-app-plain",