diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 089913c972..b16444183f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,7 @@ jobs: - name: Checkout Repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} submodules: 'recursive' - name: Setup Java Version @@ -44,6 +45,18 @@ jobs: - name: Run Tests with coverage and Lint run: make preMerge + - name: Install Sentry CLI + run: curl -sL https://sentry.io/get-cli/ | bash + + - name: Upload Snapshots to Sentry + run: | + sentry-cli build snapshots ./sentry-android-core/build/test-snapshots \ + --app-id sentry-android-core + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: sentry-sdks + SENTRY_PROJECT: sentry-android + - name: Upload coverage to Codecov uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # pin@v4 with: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 50d415c212..8b7cbee370 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -247,4 +247,4 @@ msgpack = { module = "org.msgpack:msgpack-core", version = "0.9.8" } okhttp-mockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "okhttp" } okio = { module = "com.squareup.okio:okio", version = "1.13.0" } roboelectric = { module = "org.robolectric:robolectric", version = "4.14" } -dropbox-differ = { module = "com.dropbox.differ:differ-jvm", version = "0.3.0" } + diff --git a/sentry-android-core/build.gradle.kts b/sentry-android-core/build.gradle.kts index ffd42c7d4d..f61cec8926 100644 --- a/sentry-android-core/build.gradle.kts +++ b/sentry-android-core/build.gradle.kts @@ -108,7 +108,7 @@ dependencies { testImplementation(projects.sentryAndroidReplay) testImplementation(projects.sentryCompose) testImplementation(projects.sentryAndroidNdk) - testImplementation(libs.dropbox.differ) + testImplementation(libs.androidx.activity.compose) testImplementation(libs.androidx.compose.ui) testImplementation(libs.androidx.compose.foundation) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt index 300936153f..b8e223f08e 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt @@ -2,8 +2,6 @@ package io.sentry.android.core import android.app.Activity import android.content.Context -import android.graphics.Bitmap -import android.graphics.BitmapFactory import android.graphics.Canvas import android.graphics.Color import android.graphics.drawable.Drawable @@ -31,9 +29,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.dropbox.differ.Color as DifferColor -import com.dropbox.differ.Image -import com.dropbox.differ.SimpleImageComparator import io.sentry.Attachment import io.sentry.Hint import io.sentry.MainEventProcessor @@ -66,17 +61,8 @@ import org.robolectric.shadows.ShadowPixelCopy class ScreenshotEventProcessorTest { companion object { - /** - * Set to `true` to record/update golden images for snapshot tests. When `true`, screenshots - * will be saved to src/test/resources/snapshots/{testName}.png. Set back to `false` after - * recording to run comparison tests. - */ - private const val RECORD_SNAPSHOTS = false - private val SNAPSHOTS_DIR = - File("src/test/resources/snapshots/ScreenshotEventProcessorTest").also { - if (RECORD_SNAPSHOTS) it.mkdirs() - } + File("build/test-snapshots/ScreenshotEventProcessorTest").also { it.mkdirs() } } private class Fixture { @@ -507,17 +493,6 @@ class ScreenshotEventProcessorTest { private fun getEvent(): SentryEvent = SentryEvent(Throwable("Throwable")) - /** - * Helper method for snapshot testing. Processes an event and captures a screenshot, then either - * saves it as a golden image (when RECORD_SNAPSHOTS=true) or compares it against an existing - * golden image. - * - * @param testName The name used for the golden image file (without extension) - * @param attachScreenshot Whether to enable screenshot attachment - * @param isReplayAvailable Whether the replay module is available (enables masking) - * @param configureOptions Lambda to configure additional options before processing - * @return The captured screenshot bytes, or null if no screenshot was captured - */ private fun processEventForSnapshots( testName: String, attachScreenshot: Boolean = true, @@ -536,38 +511,10 @@ class ScreenshotEventProcessorTest { val screenshot = hint.screenshot ?: return null val bytes = screenshot.bytes ?: screenshot.byteProvider?.call() ?: return null - val snapshotFile = File(SNAPSHOTS_DIR, "$testName.png") - if (RECORD_SNAPSHOTS) { - snapshotFile.writeBytes(bytes) - println("Recorded snapshot: ${snapshotFile.absolutePath}") - } else if (snapshotFile.exists()) { - val expectedBitmap = BitmapFactory.decodeFile(snapshotFile.absolutePath) - val actualBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) - - val result = - SimpleImageComparator(maxDistance = 0.01f) - .compare(BitmapImage(expectedBitmap), BitmapImage(actualBitmap)) - assertEquals( - 0, - result.pixelDifferences, - "Screenshot does not match golden image: ${snapshotFile.absolutePath}. " + - "Pixel differences: ${result.pixelDifferences}", - ) - } + File(SNAPSHOTS_DIR, "$testName.png").writeBytes(bytes) return bytes } - - /** Adapter to wrap Android Bitmap for use with dropbox/differ library */ - private class BitmapImage(private val bitmap: Bitmap) : Image { - override val height: Int - get() = bitmap.height - - override val width: Int - get() = bitmap.width - - override fun getPixel(x: Int, y: Int): DifferColor = DifferColor(bitmap.getPixel(x, y)) - } } private class CustomView(context: Context) : View(context) { diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_all.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_all.png deleted file mode 100644 index aa1ec41ee0..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_all.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_custom_view.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_custom_view.png deleted file mode 100644 index 217c73490c..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_custom_view.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_compose_masked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_compose_masked.png deleted file mode 100644 index 53e5a236c3..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_compose_masked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_compose_unmasked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_compose_unmasked.png deleted file mode 100644 index efc2304c4f..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_compose_unmasked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_view_masked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_view_masked.png deleted file mode 100644 index 1530d58fd9..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_view_masked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_view_unmasked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_view_unmasked.png deleted file mode 100644 index 57b4bfa8f4..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_ellipsized_view_unmasked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_images.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_images.png deleted file mode 100644 index bd4378a994..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_images.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_text.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_text.png deleted file mode 100644 index 6ffbe1e07f..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_mask_text.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_compose_masked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_compose_masked.png deleted file mode 100644 index fb8f816218..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_compose_masked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_compose_unmasked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_compose_unmasked.png deleted file mode 100644 index dc4beee80a..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_compose_unmasked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_view_masked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_view_masked.png deleted file mode 100644 index 373752de30..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_view_masked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_view_unmasked.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_view_unmasked.png deleted file mode 100644 index df051c6371..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_multiline_view_unmasked.png and /dev/null differ diff --git a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_no_masking.png b/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_no_masking.png deleted file mode 100644 index edf883f9a4..0000000000 Binary files a/sentry-android-core/src/test/resources/snapshots/ScreenshotEventProcessorTest/screenshot_no_masking.png and /dev/null differ