feat(examples): Add Paparazzi snapshot setup to instrumentation sample#1145
feat(examples): Add Paparazzi snapshot setup to instrumentation sample#1145runningcode wants to merge 5 commits intomainfrom
Conversation
Enable the Sentry snapshot integration in the android-instrumentation-sample by applying the Paparazzi plugin and adding @Preview composables. The CI pre-merge workflow now records and uploads snapshots when SENTRY_AUTH_TOKEN is available. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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. |
|
|
|
||
| - name: Record and upload snapshots | ||
| if: env.SENTRY_AUTH_TOKEN != '' | ||
| run: ./gradlew :examples:android-instrumentation-sample:sentryUploadSnapshotsStagingDebug |
There was a problem hiding this comment.
Snapshot upload runs redundantly on all three OS matrices
Medium Severity
The new "Record and upload snapshots" step runs on all three matrix OSes (ubuntu-latest, macos-latest, windows-latest) since it only guards on SENTRY_AUTH_TOKEN. Paparazzi snapshot rendering can produce platform-dependent output (e.g., font rendering differences), so uploading from all three OSes can result in non-deterministic snapshots overwriting each other in Sentry. This likely needs a runner.os condition (similar to the existing preMerge step) to restrict it to a single OS.
Reviewed by Cursor Bugbot for commit c0d0a21. Configure here.
Keep the original composable signatures non-nullable by passing a dummy NavController from rememberNavController() in the preview functions instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| @Preview | ||
| @Composable | ||
| fun HomeTextPreview() { |
There was a problem hiding this comment.
Bug: Calling rememberNavController() inside @Preview composables will crash Paparazzi snapshot tests because a ViewModelStoreOwner is not available in the test environment.
Severity: HIGH
Suggested Fix
To prevent the crash, do not call rememberNavController() directly within @Preview functions. Instead, create and pass a mock NavController to the composable under test. For example: HomeText(navController = NavController(LocalContext.current), ...). Alternatively, you can wrap the preview composable with a CompositionLocalProvider to supply a fake ViewModelStoreOwner for the test environment.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location:
examples/android-instrumentation-sample/src/main/java/io/sentry/samples/instrumentation/ui/ComposeActivity.kt#L66-L68
Potential issue: The `@Preview` composables `HomeTextPreview` and `DetailsTextPreview`
directly invoke `rememberNavController()`. This function internally depends on
`LocalViewModelStoreOwner.current` to get a `ViewModelStoreOwner`. The Paparazzi
snapshot testing environment, which runs on a JVM, does not provide this context by
default. As a result, attempting to generate snapshots for these previews will cause a
runtime crash, likely an `IllegalStateException`. This crash will cause the
`recordPaparazziStagingDebug` Gradle task to fail, which in turn will block the CI
workflow step `sentryUploadSnapshotsStagingDebug` from completing.
Did we get this right? 👍 / 👎 to inform future reviews.
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.
Reviewed by Cursor Bugbot for commit 951e483. Configure here.
| @Composable | ||
| fun HomeTextPreview() { | ||
| HomeText(rememberNavController(), RoundedCornerShape(50)) | ||
| } |
There was a problem hiding this comment.
Preview composables may crash in Paparazzi rendering context
Medium Severity
HomeTextPreview and DetailsTextPreview call rememberNavController(), which internally uses checkNotNull(LocalViewModelStoreOwner.current). Paparazzi's rendering context may not provide LocalViewModelStoreOwner, causing an IllegalStateException at snapshot recording time. This is a known class of issues with navigation components in Paparazzi (cashapp/paparazzi#635). Simpler preview-safe composables that don't require NavController would avoid this risk.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 951e483. Configure here.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
|
||
| - name: Record and upload snapshots | ||
| if: env.SENTRY_AUTH_TOKEN != '' | ||
| run: ./gradlew :examples:android-instrumentation-sample:sentryUploadSnapshotsStagingDebug |
There was a problem hiding this comment.
Bug: The use of .first() to find the Paparazzi snapshots directory is unsafe and will throw an exception if the directory is not found in the test task's outputs.
Severity: MEDIUM
Suggested Fix
Replace the unsafe .first() call with .firstOrNull(). This allows for checking if the directory exists and throwing a more informative GradleException if it is not found, preventing unexpected build failures.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: .github/workflows/pre-merge.yaml#L49-L52
Potential issue: The code uses `.first { file -> file.name == "snapshots" }` to find a
snapshots directory within a test task's output files. This will throw a
`NoSuchElementException` if no file with that name is found, causing the build to fail.
Standard test tasks do not typically produce a "snapshots" directory in their output,
and while the Paparazzi library might configure this, it's an undocumented behavior.
This makes the code fragile and reliant on a specific, unconfirmed output structure of
an alpha version of a library.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>


Summary
app.cash.paparazzi2.0.0-alpha04 to theandroid-instrumentation-sampleand enablesentry { snapshots { enabled.set(true) } }@Previewcomposables (HomeTextPreview,DetailsTextPreview) so the snapshot scanner has something to discoverSENTRY_AUTH_TOKENis available#skip-changelog
🤖 Generated with Claude Code