airbnb / Showkase

🔦 Showkase is an annotation-processor based Android library that helps you organize, discover, search and visualize Jetpack Compose UI elements
https://medium.com/airbnb-engineering/introducing-showkase-a-library-to-organize-discover-and-visualize-your-jetpack-compose-elements-d5c34ef01095
Apache License 2.0
2.1k stars 107 forks source link

[Request] Per-module metadata #299

Open jd565 opened 1 year ago

jd565 commented 1 year ago

We have a multi-module project where we want to use showkase with paparazzi for screenshot testing of previews. Right now the generated metadata from showkase contains a single list of all the showkase previews inside project, with that metadata only available from the root project, meaning that all the screenshot tests have to be run from the root module, or another module that depends on root.

We would find it very useful if each module could have a generated metadata file listing the showkase components in that module, then the root module can aggregate all of them. With this change, each module could contain the screenshot tests for that module, enabling developers to run the screenshot tests in module they have changed while excluding testing modules that haven't changed.

For example:

In a multi-module project e.g.

App | -> A | -> B | -> C

Would have a Showkase.getMetadata() function in App (root module), as well as generating a AppModuleShowkaseMetadata, AModuleShowkaseMetadata, BModuleShowkaseMetadata, CModuleShowkaseMetadata.

I did investigate using the ShowkaseMetadata_x generated file (which has a list of annotated functions), but those annotations are BINARY retention so can't be used for reflection. This is also generated on a per-file basis while a per-module aggregated file would be useful here.

jd565 commented 1 year ago

Is there anything wrong with defining multiple showkase roots? So far I've been doing this so I can access the metadata within that module, and then filter out components from other modules (e.g. if A depends on B then the generated metadata for A has all the composables for A and B, so my test is then filtering out the components from B)

I took a brief look at the generation code and it doesn't seem like a super difficult change, so would be happy to try putting together a PR to enable this behaviour, if this is a reasonable change to make.

iamutkarshtiwari commented 1 year ago

@jd565 Thank you for raising this. I have the same requirement where multiple teams would be working in the same repo but in different modules and we want to have separate screenshot test (showkase + paparazzi synergy) coverage for each team. We don't want one team's regression to leak into other team's workflow. But as of now, it's not possible because Showkase aggregates everything from the project. I'd really nice to have this feature!

vinaygaba commented 1 year ago

@jd565 @iamutkarshtiwari In theory, your project can have multiple ShowkaseRoot implementations and that's supported already. This allows you to also have multiple screenshot tests, each focused on a different tree of submodules. I feel like using that setup should solve this use case. What do y'all think? Happy to explain it a bit more if what I said wasn't making sense.

jd565 commented 1 year ago

@vinaygaba We do this in the setup right now so each module has it's own ShowkaseRoot that is used, and it works, but the ShowkaseRoot in module B includes all previews from module A if B depends on A, so each test has some filtering to only include the previews that start with a specific package name to filter out previews from another module

ss0930 commented 4 months ago

@vinaygaba We do this in the setup right now so each module has it's own ShowkaseRoot that is used, and it works, but the ShowkaseRoot in module B includes all previews from module A if B depends on A, so each test has some filtering to only include the previews that start with a specific package name to filter out previews from another module

@jd565 I am using showkase-screenshot-testing-paparazzi artifact https://github.com/airbnb/Showkase/pull/294 and running into this issue. How do you filter out the previews from another module?

vinaygaba commented 2 months ago

@jd565 Started implementing some functionality that will address this. Take a look if you have thoughts and would like to shape the API - https://github.com/airbnb/Showkase/pull/392