sergio-sastre / ComposablePreviewScanner

A library to help auto-generate screenshot tests from Composable Previews with any screenshot testing library: JVM-based (i.e. Paparazzi, Roborazzi) as well as Instrumentation-based (i.e. Shot, Dropshots, Android-Testify, etc.)
MIT License
132 stars 1 forks source link

Consider support for `org.jetbrains.compose.ui.tooling.preview.Preview` #19

Closed takahirom closed 1 month ago

takahirom commented 1 month ago

Compose Multiplatform provides the "org.jetbrains.compose.ui.tooling.preview.Preview" annotation.

To parse this Preview annotation, we need to use the ComposablePreviewScanner abstract class instead of JvmAnnotationScanner, as the getPreviews function returns JvmAnnotationScanner.DesktopPreviewInfo.

Given that org.jetbrains.compose.ui.tooling.preview.Preview could become a standard, it would be beneficial to support this annotation.

sergio-sastre commented 1 month ago

I’m afraid is unfortunately not possible due to the way ClassGraph works. Check this: https://github.com/sergio-sastre/ComposablePreviewScanner?tab=readme-ov-file#how-it-works

Android Preview annotations has AnnotationRetention.BINARY, however, Jetbrains Preview annotations have AnnotationRetention.SOURCE

Unit tests happen at build time, and the source annotations are gone at that point.

I believe there are only 2 options:

sergio-sastre commented 1 month ago

However, I’ll ask the author of ClassGraph if there is a way to get annotations with AnotationRetention.SOURCE

takahirom commented 1 month ago

Oh, I understand 😭. I'll take a closer look.

takahirom commented 1 month ago

It appears that Android's Preview annotation has been changed to Binary retention to allow reuse of multiple preview annotations for libraries. https://cs.android.com/androidx/platform/frameworks/support/+/3af7d25215d569d477e97fb3c7353e8664371fd6 https://issuetracker.google.com/issues/233511976

sergio-sastre commented 1 month ago

Exactly, that’s why Android Previews work with ClassGraph. Ideally we can create a similar issue in JetBrains issue tracker and if solved it would work out of the box. The reasoning is the same: make it work with libraries 😉

sergio-sastre commented 1 month ago

@takahirom I've created an issue on Jetbrains issue tracker https://youtrack.jetbrains.com/issue/CMP-5675/Change-AnnotationRetention-of-Preview-Annotations-from-SOURCE-to-BINARY

takahirom commented 1 month ago

@sergio-sastre I discovered that the Preview of CMP appears to already be in BINARY format. 👀 https://github.com/JetBrains/compose-multiplatform/blob/master/components/ui-tooling-preview/library/src/commonMain/kotlin/org/jetbrains/compose/ui/tooling/preview/Preview.kt#L26C1-L26C31

sergio-sastre commented 1 month ago

@takahirom That’s great news! Then it should work with jvmAnnotationScanner.

JvmAnnotationScanner.DesktopPreviewInfo is a bad naming, it should be JvmAnnotationScanner.PreviewWithoutInfo. what is important is that it is a Preview without arguments, the same as the Desktop Preview. I should definitely change that.

have you tried it out? Also consider this open issue #3 If It does not work, I can take a deeper look into it 😊

Anyway, the Desktop Preview is SOURCE: https://developer.android.com/reference/kotlin/androidx/compose/desktop/ui/tooling/preview/Preview

so the open issue ticket still makes sense 😊

Thanks for your research!

takahirom commented 1 month ago

For the KMP library problem, I think you can just add a dependency on JetBrains Compose Runtime. I believe Android Runtime is used for the Android platform. However, I'd use 'compileOnly' for Compose Runtime because the Compose Gradle Plugin will verify to add the runtime.

image

https://repo1.maven.org/maven2/org/jetbrains/compose/runtime/runtime/1.7.0-alpha01/runtime-1.7.0-alpha01.module

Regarding the Preview parse problem, I haven't verified it personally, but it appears we might be able to obtain the Annotation.

image
takahirom commented 1 month ago

Speaking of dependencies, one problem I faced when introducing ComposablePreviewScanner is that this library depends on the Compose BOM and accidentally updated our Compose version. Roborazzi used to have the Compose BOM dependency as well. However, some users reported that our Material 3 or other components were broken. So I removed the BOM dependency. But managing the versions is difficult, so it's understandable to have the Compose BOM in the dependencies. It's your choice.

takahirom commented 1 month ago

I'm considering adding a custom tester class for KMP Preview, once the org.jetbrains.compose.ui.tooling.preview.Preview is supported on ComposablePreviewScanner. https://github.com/takahirom/roborazzi/pull/438/files#diff-f6ff740542c0a174dfdfa38787df90819591636e705d2bac9f08ae2dbbf10376R21

sergio-sastre commented 1 month ago

I'm considering adding a custom tester class for KMP Preview, once the org.jetbrains.compose.ui.tooling.preview.Preview is supported on ComposablePreviewScanner. https://github.com/takahirom/roborazzi/pull/438/files#diff-f6ff740542c0a174dfdfa38787df90819591636e705d2bac9f08ae2dbbf10376R21

I believe I won’t work on it this week, already many things going on, but I could try to get it working before the end of next week. The only problem I faced was the runtime in the jvm and core module and I hope it’ll work with your tip 😊

sergio-sastre commented 1 month ago

@takahirom I've fixed the problem with the :jvm and :core modules, what means, this should be possible now.

I've also added support for this annotation but I'd need to configure a project where I could test it, what is time consuming.

Do you have any project where you could test it with Roborazzi? You should just add testImplementation("com.github.sergio-sastre.ComposablePreviewScanner:jvm:dad7c50") (it is a snapshot version of the commit)

and use CommonMainComposablePreviewScanner()

sergio-sastre commented 1 month ago

Should be solved in 0.2.0