feat(snapshot): Add io.sentry.android.snapshot Gradle plugin#1112
feat(snapshot): Add io.sentry.android.snapshot Gradle plugin#1112runningcode merged 6 commits intomainfrom
Conversation
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. This PR will not appear in the changelog. 🤖 This preview updates automatically when you update the PR. |
|
| import org.gradle.api.provider.ListProperty | ||
| import org.gradle.api.provider.Property | ||
|
|
||
| abstract class SentrySnapshotExtension(objects: ObjectFactory) { |
There was a problem hiding this comment.
for now im keeping this independent of the rest of the extensions so that this plugin is independent but we will eventually merge this with the rest of the sentry configuration.
plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Autofix Details
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Generated code passes invalid parameter to HtmlReportWriter
- Removed the invalid maxPercentDifference parameter from HtmlReportWriter constructor call, which only accepts runName, rootDirectory, and snapshotRootDirectory.
- ✅ Fixed: Regex recompiled for every configured task
- Extracted the regex pattern to a class member variable to compile it once and reuse across all task configurations.
Or push these changes by commenting:
@cursor push 2cf75cdb03
Preview (2cf75cdb03)
diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
--- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
+++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
@@ -209,7 +209,7 @@
private class PreviewHtmlReportWriter(
maxPercentDifference: Double,
) : SnapshotHandler {
- private val delegate = HtmlReportWriter(maxPercentDifference = maxPercentDifference)
+ private val delegate = HtmlReportWriter()
override fun newFrameHandler(
snapshot: Snapshot,
diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/SentrySnapshotPlugin.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/SentrySnapshotPlugin.kt
--- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/SentrySnapshotPlugin.kt
+++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/SentrySnapshotPlugin.kt
@@ -6,6 +6,8 @@
class SentrySnapshotPlugin : Plugin<Project> {
+ private val unitTestKotlinRegex = Regex("(compile|ksp).*UnitTestKotlin")
+
override fun apply(project: Project) {
val extension =
project.extensions.create(
@@ -29,7 +31,7 @@
android.sourceSets.getByName("test").kotlin.srcDir(generateTask.flatMap { it.outputDir })
project.tasks.configureEach { task ->
- if (task.name.matches(Regex("(compile|ksp).*UnitTestKotlin"))) {
+ if (task.name.matches(unitTestKotlinRegex)) {
task.dependsOn(generateTask)
}
}This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
Outdated
Show resolved
Hide resolved
| android.sourceSets.getByName("test").kotlin.srcDir(generateTask.flatMap { it.outputDir }) | ||
|
|
||
| project.tasks.configureEach { task -> | ||
| if (task.name.matches(Regex("(compile|ksp).*UnitTestKotlin"))) { |
There was a problem hiding this comment.
Regex recompiled for every configured task
Low Severity
A new Regex object is compiled inside the configureEach lambda, meaning a fresh regex is compiled for every task that gets realized in the project. Extracting this to a val outside the lambda avoids redundant regex compilations across potentially hundreds of tasks.
plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
Outdated
Show resolved
Hide resolved
plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
Show resolved
Hide resolved
Add a new Gradle plugin that generates Paparazzi screenshot tests for all Compose @Preview composables. When applied to an app module alongside Paparazzi, it registers a `generateSnapshotTests` task that produces a parameterized JUnit 4 test class using ComposablePreviewScanner to discover previews at test runtime. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace PreviewSnapshotVerifier and PreviewHtmlReportWriter with a single TestNameOverrideHandler that wraps any SnapshotHandler delegate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
93e3a7c to
a61a207
Compare
android.namespace is always non-null, so packageTrees can never be empty after the fallback. Remove the dead scanAllPackages branch and fail the build if Paparazzi is not applied instead of just warning. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt
Outdated
Show resolved
Hide resolved
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>



Summary
io.sentry.android.snapshotGradle plugin that generates Paparazzi screenshot tests for all Compose@PreviewcomposablesgenerateSnapshotTeststask that produces a parameterized JUnit 4 test using ComposablePreviewScanner for preview discoverysentrySnapshotextension (packageTrees,includePrivatePreviews)Usage
plugins { id("com.android.application") id("app.cash.paparazzi") id("io.sentry.android.snapshot") } sentrySnapshot { // optional — defaults to android.namespace packageTrees.set(listOf("com.example.app")) includePrivatePreviews.set(true) }#skip-changelog
🤖 Generated with Claude Code