SkillAgentSearch skills...

ComposablePreviewScanner

A library to help auto-generate screenshot tests from Composable Previews (e.g. Android, Glance & Compose Multiplatform) with any screenshot testing library: JVM-based (i.e. Paparazzi, Roborazzi) as well as Instrumentation-based (i.e. Shot, Dropshots, Android-Testify, etc.)

Install / Use

/learn @sergio-sastre/ComposablePreviewScanner
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

</br>

<a href="https://androidweekly.net/issues/issue-628"> <img src="https://androidweekly.net/issues/issue-628/badge"> </a></br> <a href="https://jetc.dev/issues/221.html"><img src="https://img.shields.io/badge/As_Seen_In-jetc.dev_Newsletter_Issue_%23221-blue?logo=Jetpack+Compose&amp;logoColor=white" alt="As Seen In - jetc.dev Newsletter Issue #221"></a>

<p align="center">Composable Preview Scanner</p>

<p align="center"> <img width="400" src="https://github.com/sergio-sastre/ComposablePreviewScanner/assets/6097181/63d9676d-22c4-4bd1-8680-3fcf1a72e001"> </p>

A library to help auto-generate screenshot tests from Composable Previews (e.g. Android, Glance & Compose Multiplatform) with any screenshot testing library: JVM-based (i.e. Paparazzi, Roborazzi) as well as Instrumentation-based (i.e. Shot, Dropshots, Android-Testify, etc.)

composable_preview_scanner_overview.png

[!NOTE]

  1. Support for Wear OS Tile @Previews is under evaluation</br>
  2. common and desktop previews are deprecated in favour of the android preview (androidx.compose.ui.tooling.preview.Preview), which can be used in common and JVM-based source sets like desktop since Compose Multiplatform 1.10.0-beta-02</br>

Provide anonymous feedback

Already using ComposablePreviewScanner?</br> I'd love to hear your thoughts!</br> Help shape its future by taking this quick survey

Comparison with other solutions

| | Composable Preview Scanner | Showkase | Compose Preview Screenshot Testing | |------------------------------------------------------|------------------------------------------------------------------------|-----------------------------------------------------------------|-----------------------------------------------| | Independent of AGP version | ✅ | ✅ | ❌ | | Library-agnostic solution | ✅ | ✅ | ❌<sup>1</sup> | | Scans previews in different sources sets<sup>2</sup> | ✅ main<br/>✅ screenshotTest<br/>✅ androidTest | ✅ main<br/>❌ screenshotTest<br/>❌ androidTest | ❌ main<br/>✅ screenshotTest<br/>❌ androidTest | | Preview Infos available | ✅ | ❌<sup>3</sup> | ✅ | | Specific Config (e.g. for Libs) available | ✅<sup>4</sup> | ❌ | ⚠️<sup>5</sup> | | Supported Preview types | ✅ Android</br> ✅ Glance</br> ✅ Compose Multiplatform <sup>6</sup></br> | ✅ Android</br> ❌Glance</br> ❌Compose Multiplatform <sup>7</sup> | ✅ Android</br> ❌ Glance</br> ❌ Compose Multiplatform |

<sup>1</sup> Compose Preview Screenshot Testing is a standalone solution based on LayoutLib, whereas ComposablePreviewScanner and Showkase provide Composables' infos so you can run screenshot tests with your favourite screenshot testing library.</br></br> <sup>2</sup> From version 0.5.0, ComposablePreviewScanner can scan previews in any source set. Compose Preview Screenshot Testing requires to put the previews in a brand-new "screenshotTest" source.</br></br> <sup>3</sup> Showkase components only hold information about the Composable, but not about the Preview Info (i.e. ApiLevel, Locale, UiMode, FontScale...).</br></br> <sup>4</sup> ComposablePreviewScanner supports adding extra lib-config (e.g. Paparazzi's Rendering Mode or Roborazzi's compare options) in the form of annotations that are additionally added to the preview. You can check how in the examples below in Jvm Screenshot Tests and Instrumentation Screenshot Tests respectively.</br></br> <sup>5</sup> Compose Preview Screenshot Testing supports only general tolerance via gradle plugin from version 0.0.1-alpha06</br></br> <sup>6</sup> Desktop Previews (which are deprecated since Compose Multiplatform 1.10.0-beta02) are supported with a workaround</br></br> <sup>7</sup> Showkase: Compose Multiplatform Support </br></br></br> ComposablePreviewScanner also works with:

  • @PreviewParameters (for Compose Multiplatform since 0.6.0+)
  • Multi-Previews, including @PreviewScreenSizes, @PreviewFontScales, @PreviewLightDark, and @PreviewDynamicColors as well as custom multi-previews.
  • private @Previews (from version 0.1.3+)
  • @Previews inside public classes<sup>1</sup> (from version 0.3.0+), not nested classes though
  • @Previews located in any source set, like "main", "screenshotTest" and "androidTest" (from version 0.5.0+)
  • @Previews with default-parameters (from version 0.5.1+)

<sup>1</sup> The Compose Preview Screenshot Testing tool from Google requires you to put your @Previews inside a class.

How to set up

[!WARNING]
Beware the prefixes:</br> Maven Central -> io.github</br> JitPack -> com.github</br>

Maven Central (since 0.3.2)

dependencies {
    // android previews (androidx.compose.ui.tooling.preview.Preview)
    // supported in jvm targets e.g. android & desktop
    testImplementation("io.github.sergio-sastre.ComposablePreviewScanner:android:<version>")

    // glance previews (androidx.glance.preview.Preview)
    // supported since 0.7.0+ in android target
    testImplementation("io.github.sergio-sastre.ComposablePreviewScanner:glance:<version>")
    
    // common previews (org.jetbrains.compose.ui.tooling.preview.Preview)
    // supported in jvm targets e.g. android & desktop
    testImplementation("io.github.sergio-sastre.ComposablePreviewScanner:common:<version>")

    // desktop previews (androidx.compose.desktop.ui.tooling.preview.Preview) via custom annotation
    // supported in jvm targets e.g. android & desktop
    testImplementation("io.github.sergio-sastre.ComposablePreviewScanner:jvm:<version>")
}

JitPack

Add JitPack to your root build.gradle file:

allprojects {
   repositories {
      maven { url = uri('https://jitpack.io') }
   }
}
dependencies {
    // android previews (androidx.compose.ui.tooling.preview.Preview)
    // supported in jvm targets e.g. android & desktop
    testImplementation("com.github.sergio-sastre.ComposablePreviewScanner:android:<version>")

    // glance previews (androidx.glance.preview.Preview)
    // supported since 0.7.0+ in android target
    testImplementation("com.github.sergio-sastre.ComposablePreviewScanner:glance:<version>")

    // common previews (org.jetbrains.compose.ui.tooling.preview.Preview)
    // supported in jvm targets e.g. android & desktop
    testImplementation("com.github.sergio-sastre.ComposablePreviewScanner:common:<version>")

    // desktop previews (androidx.compose.desktop.ui.tooling.preview.Preview) via custom annotation
    // supported in jvm targets e.g. android & desktop
    testImplementation("com.github.sergio-sastre.ComposablePreviewScanner:jvm:<version>")
}

How to use

Examples with Screenshot Testing Libraries (Android target)

  1. JVM Screenshot Tests</br> 1.1 Paparazzi</br> 1.2 Roborazzi</br>
  2. Instrumentation Screenshot Tests

If you encounter any issues when executing the screenshot tests, take a look at the Troubleshooting section.

[!NOTE] Roborazzi has integrated ComposablePreviewScanner in its plugin since version 1.22

Related

  1. Glance Previews Support
  2. Compose Multiplatform Support

API

AndroidComposablePreviewScanner, GlanceComposablePreviewScanner, CommonComposablePreviewScanner, and JvmAnnotationScanner have the same API. The API is pretty simple:

AndroidComposablePreviewScanner()
    // Optional to log scanning info like scanning time or amount of previews found
    .enableScanningLogs()
    // Optional to scan previews in compiled classes of other source sets, like "screenshotTest" or "androidTest"
    // If omitted, it scans previews in 'main' at build time
    .setTargetSourceSet(
       Classpath(SourceSet.SCREENSHOT_TEST) // scan previews under "screenshotTest"
    )
    // Required: define where to scan for Previews.
    // See 'Scanning Source Options (packages, files, inputStreams)'
    .scanPackageTrees(
        include = listOf("your.package", "your.package2"),
        exclude = listOf("your.package.subpackage1", "your.package2.subpackage1")
    )
    // Optional to filter out scanned previews with any of the given annota

Related Skills

View on GitHub
GitHub Stars322
CategoryDevelopment
Updated9h ago
Forks9

Languages

Kotlin

Security Score

100/100

Audited on Mar 26, 2026

No findings