Skip to content

Conversation

@runningcode
Copy link
Contributor

@runningcode runningcode commented Dec 15, 2025

This adds paparazzi and the compose snapshots preview library to scan and find compose previews for paparazzi.

Paparazzi + compose snapshots preview folder is in android/paparazzi-preview-scanner-plugin

Comment on lines 38 to 40
val previewInfo = preview.previewInfo
preview()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The previewInfo variable is extracted but unused. The preview() object is invoked directly, which likely ignores the intended preview configuration for the snapshot test.
Severity: HIGH | Confidence: High

🔍 Detailed Analysis

In the snapshot test, the previewInfo variable is extracted from the preview object but is never used. Instead, the preview() object is invoked directly. According to the library's documentation, the composable function should be invoked via the previewInfo object (e.g., previewInfo.previewComposable.invoke()). This discrepancy means that important configuration metadata from the @Preview annotation, such as device settings, locale, and theme, is likely being ignored. As a result, the generated snapshots may not reflect the intended configuration, leading to incorrect or failing tests.

💡 Suggested Fix

Replace the direct invocation preview() with the invocation from the previewInfo object, such as previewInfo.previewComposable.invoke(). This will ensure the composable is rendered with the correct configuration specified in its @Preview annotation.

🤖 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:
android/app/src/test/kotlin/com/emergetools/hackernews/ComposePreviewScanner.kt#L38-L40

Potential issue: In the snapshot test, the `previewInfo` variable is extracted from the
`preview` object but is never used. Instead, the `preview()` object is invoked directly.
According to the library's documentation, the composable function should be invoked via
the `previewInfo` object (e.g., `previewInfo.previewComposable.invoke()`). This
discrepancy means that important configuration metadata from the `@Preview` annotation,
such as device settings, locale, and theme, is likely being ignored. As a result, the
generated snapshots may not reflect the intended configuration, leading to incorrect or
failing tests.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 7526923

@emerge-tools
Copy link

emerge-tools bot commented Dec 15, 2025

🛰️ Build Distribution

Build available for installation

App Name App ID Platform Version Tag Install Page
Hacker News com.emergetools.hackernews android 1.0.6 release 🔗 Install Build

🛸 Powered by Emerge Tools

@emerge-tools
Copy link

emerge-tools bot commented Dec 15, 2025

⏱ Performance Analysis

Hacker News

Head build: Hacker News 1.0.6 (17)
Base build: Hacker News 1.0.6 (17)

Name Change Comparison
Startup (com.emerge.universaltests.EmergeUniversalStartupTest) ⬇️ -6.37% 🛸 View

🛸 Powered by Emerge Tools

@emerge-tools
Copy link

emerge-tools bot commented Dec 19, 2025

📸 Snapshot Test

8 added, 84 unchanged

Name Added Removed Modified Renamed Unchanged Errored Approval
Hacker News
com.emergetools.hackernews.debug
8 0 0 0 84 0 ⏳ Needs approval

🛸 Powered by Emerge Tools

runningcode and others added 8 commits December 22, 2025 15:37
Restored BookmarksScreenComposeTest.kt and StoryRowComposeTest.kt
from git history to maintain test coverage for Compose UI components.
…r test

Ensures the output directory is cleaned before generating new preview scanner
test files to prevent stale generated files from accumulating.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
… configuration

Update the Paparazzi preview scanner plugin to generate more sophisticated tests with comprehensive device configuration and preview parameter handling.

Changes:
- Update ComposablePreviewScanner library from 0.7.2 to 0.8.1
- Add includePrivatePreviews configuration option
- Generate tests with DeviceConfigBuilder for proper device configuration (screen size, density, orientation, locale, night mode)
- Add PaparazziPreviewRule.createFor() to create per-preview configured Paparazzi instances with dynamic API level support
- Support custom rendering modes (NORMAL, FULL_EXPAND, SHRINK)
- Add custom snapshot handlers (PreviewSnapshotVerifier, PreviewHtmlReportWriter)
- Add SystemUiSize and PreviewBackground composables to handle showSystemUi, showBackground, and backgroundColor parameters
- Use encodeUnsafeCharacters() in screenshot ID builder for proper character handling
- Remove build artifacts from git tracking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
runningcode and others added 4 commits December 22, 2025 16:04
Add baseline snapshot images generated by the enhanced Paparazzi preview scanner for visual regression testing.

Changes:
- Add new snapshot images with improved naming convention using encoded screenshot IDs
- Remove old snapshot images that used numbered naming
- Update gradle/libs.versions.toml:
  - Pin AGP version to 8.13.2
  - Remove composable-preview-scanner library (now auto-injected by plugin)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove old numbered snapshot files from ui-components module. The new snapshots with improved naming were already committed in the previous change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Bundle the Paparazzi Gradle plugin as a dependency of the preview scanner plugin, so users no longer need to explicitly apply it.

Changes:
- Add Paparazzi Gradle plugin as implementation dependency in plugin build.gradle.kts
- Add warning comment about potential version conflicts
- Remove explicit Paparazzi plugin application from app and ui-components modules
- Update plugin source with clarifying comment about plugin application
- Users now only need to apply the preview-scanner plugin to get full functionality

This simplifies setup by reducing it to a single plugin application instead of two.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The Paparazzi preview scanner now filters out previews from dependency
modules, ensuring each module only generates snapshots for its own
previews. This prevents duplicate/conflicting snapshots and improves
build performance.

Implementation uses Gradle's variant source directories to accurately
determine which previews belong to the current module, supporting
all Android project structures including product flavors and custom
source sets.

- Query actual source directories from Android variant configuration
- Filter previews by checking source file existence in module directories
- Handle Kotlin file-level functions (Kt suffix removal)
- Remove bundled Paparazzi dependency from plugin (users apply manually)
- Add proper Gradle task input annotations for correct caching

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove redundant comments and improve code clarity.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@runningcode runningcode changed the title Add paparazzi and compose snapshots preview [DNM] Add paparazzi and compose snapshots preview Dec 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants