Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement generateRobolectricPreviewTests prototype #416

Merged
merged 24 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0d763a0
Implement autoPreviewScreenshots
takahirom Jun 26, 2024
887de83
Fix test dependency
takahirom Jun 26, 2024
ba06ac5
Fix plugin version const problem
takahirom Jun 26, 2024
f862534
Fix timing of accessing VersionCatalogsExtension
takahirom Jun 26, 2024
d38cbaf
Fix configuration cache
takahirom Jun 26, 2024
b4a21cf
Fix file name
takahirom Jun 26, 2024
73f5509
Add comments and options
takahirom Jun 26, 2024
82ff15d
Rename scanPackages to scanPackageTrees
takahirom Jun 26, 2024
affca18
Prioritize user input for filePathStrategy and pixelCopyRenderMode
takahirom Jun 26, 2024
2e96e1f
Divide functions for readability
takahirom Jun 26, 2024
04e2aa7
Fix function name
takahirom Jun 26, 2024
9f2e1f7
Make AutoPreviewScreenshotsExtension version customizable
takahirom Jun 27, 2024
f7d4d57
Fix nullable
takahirom Jun 27, 2024
5b04f57
Use AndroidPreviewScreenshotIdBuilder
takahirom Jun 27, 2024
9c5c433
Rename file name
takahirom Jun 27, 2024
cdd2b32
Add ignoreClassName
takahirom Jun 27, 2024
3d3a48e
Adjust preview sample
takahirom Jun 27, 2024
d90078c
Change automaticPreviewScreenshots to androidSetup
takahirom Jun 28, 2024
ef12f3b
Prototype base and advanced API
takahirom Jun 30, 2024
12c92b9
Use error and warning-based approach instead of manipulating user con…
takahirom Jul 2, 2024
5560e72
Add import com.github.takahirom.roborazzi.* and use roborazziSystemPr…
takahirom Jul 2, 2024
c2b9b27
Fix outdated comments
takahirom Jul 3, 2024
a7984d0
Add (Robolectric 4.12.2+) to the warning text recommending 'robolectr…
takahirom Jul 9, 2024
6622443
Add roborazzi-compose-preview-scanner-support module to handle previe…
takahirom Jul 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,77 @@ If you are having trouble debugging your test, try Dump mode as follows.

![image](https://user-images.githubusercontent.com/1386930/226364158-a07a0fb0-d8e7-46b7-a495-8dd217faaadb.png)

</div>
<div name="topic_preview_support">

<!-- Generated by docs/topics/preview_support.md. Do not edit this file. -->
# Compose Preview Support

Roborazzi provides support for generating screenshot tests and easy setup for Jetpack Compose Preview.
This support uses [ComposePreviewScanner](https://github.com/sergio-sastre/ComposablePreviewScanner) to scan the Composable Previews in your project.

## Generate Compose Preview screenshot tests

You first need to add the Roborazzi plugin to your project. Please refer to the [setup guide](https://takahirom.github.io/roborazzi/build-setup.html) for more information.
Then you can enable the Compose Preview screenshot test generation feature by adding the following configuration to your `build.gradle.kts` file:

```kotlin
roborazzi {
generateComposePreviewRobolectricTests {
enable = true
}
}
```

The plugin will not automatically change your settings or add dependencies to prevent conflicts with your existing setup. However, it will provide instructions on what to do next, such as adding dependencies and required code.

After that, you can run the `recordRoborazziDebug` task to generate screenshots using the generated tests, as described in the [setup guide](https://takahirom.github.io/roborazzi/build-setup.html).

### Customizing the Preview screenshot test

You can customize the generated test by adding the following configuration to your `build.gradle` file:

```kotlin
roborazzi {
generateComposePreviewRobolectricTests {
enable = true
// The package names to scan for Composable Previews.
packages = listOf("com.example")
// The fully qualified class name of the custom test class that implements [com.github.takahirom.roborazzi.RobolectricPreviewTest].
customTestQualifiedClassName = "com.example.MyCustomRobolectricPreviewTest"
// robolectricConfig will be passed to Robolectric's @Config annotation in the generated test class.
// See https://robolectric.org/configuring/ for more information.
robolectricConfig = mapOf(
"sdk" to "[32]",
"qualifiers" to "RobolectricDeviceQualifiers.Pixel5",
)
}
}
```

## Manually adding Compose Preview screenshot tests

Roborazzi provides a helper function for ComposePreviewScanner.
You can add the following dependency to your project to use the helper function:

`testImplementation("io.github.takahirom.roborazzi:roborazzi-compose-preview-scanner-support:[version]")`

Then you can use the `ComposablePreview<AndroidPreviewInfo>.captureRoboImage()` function to capture the Composable Preview using the settings in Preview annotations.
To obtain the `ComposablePreview` object, please refer to [ComposePreviewScanner](https://github.com/sergio-sastre/ComposablePreviewScanner).

```kotlin
fun ComposablePreview<AndroidPreviewInfo>.captureRoboImage(
filePath: String,
roborazziOptions: RoborazziOptions
)
```

### The supported `@Preview` annotation options

Currently, we don't support all the annotation options provided by the Compose Preview.
You can check the supported annotations in the [source code](https://github.com/takahirom/roborazzi/blob/main/roborazzi-compose-preview-scanner-support/src/main/java/com/github/takahirom/roborazzi/RobolectricPreviewInfosApplier.kt).
We are looking forward to your contributions to support more annotation options.

</div>
<div name="topic_idea_plugin">

Expand Down
2 changes: 2 additions & 0 deletions README.template.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
</div>
<div name="topic_how_to_use">
</div>
<div name="topic_preview_support">
</div>
<div name="topic_idea_plugin">
</div>
<div name="topic_compose_multiplatform">
Expand Down
10 changes: 9 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ allprojects {
def javaTargetVersion = JavaVersion.toVersion(javaVersion)
def jvmTargetVersion = org.jetbrains.kotlin.gradle.dsl.JvmTarget.@Companion.fromTarget(javaVersion)

plugins.withId("java") {
plugins.withId("java") {
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(toolchainVersion))
Expand Down Expand Up @@ -83,6 +83,14 @@ allprojects {
}
}
}

configurations.all {
resolutionStrategy {
dependencySubstitution {
substitute(module("io.github.takahirom.roborazzi:roborazzi-compose-preview-scanner-support")).using(project(":roborazzi-compose-preview-scanner-support"))
}
}
}
}

class Topic {
Expand Down
1 change: 1 addition & 0 deletions docs/roborazzi-docs.tree
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<toc-element topic="try_it_out.md"/>
<toc-element topic="build_setup.md"/>
<toc-element topic="how_to_use.md"/>
<toc-element topic="preview_support.md"/>
<toc-element topic="idea_plugin.md"/>
<toc-element topic="compose_multiplatform.md"/>
<toc-element topic="gradle_properties_options.md"/>
Expand Down
66 changes: 66 additions & 0 deletions docs/topics/preview_support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Compose Preview Support

Roborazzi provides support for generating screenshot tests and easy setup for Jetpack Compose Preview.
This support uses [ComposePreviewScanner](https://github.com/sergio-sastre/ComposablePreviewScanner) to scan the Composable Previews in your project.

## Generate Compose Preview screenshot tests

You first need to add the Roborazzi plugin to your project. Please refer to the [setup guide](https://takahirom.github.io/roborazzi/build-setup.html) for more information.
Then you can enable the Compose Preview screenshot test generation feature by adding the following configuration to your `build.gradle.kts` file:

```kotlin
roborazzi {
generateComposePreviewRobolectricTests {
enable = true
}
}
```

The plugin will not automatically change your settings or add dependencies to prevent conflicts with your existing setup. However, it will provide instructions on what to do next, such as adding dependencies and required code.

After that, you can run the `recordRoborazziDebug` task to generate screenshots using the generated tests, as described in the [setup guide](https://takahirom.github.io/roborazzi/build-setup.html).

### Customizing the Preview screenshot test

You can customize the generated test by adding the following configuration to your `build.gradle` file:

```kotlin
roborazzi {
generateComposePreviewRobolectricTests {
enable = true
// The package names to scan for Composable Previews.
packages = listOf("com.example")
// The fully qualified class name of the custom test class that implements [com.github.takahirom.roborazzi.RobolectricPreviewTest].
customTestQualifiedClassName = "com.example.MyCustomRobolectricPreviewTest"
// robolectricConfig will be passed to Robolectric's @Config annotation in the generated test class.
// See https://robolectric.org/configuring/ for more information.
robolectricConfig = mapOf(
"sdk" to "[32]",
"qualifiers" to "RobolectricDeviceQualifiers.Pixel5",
)
}
}
```

## Manually adding Compose Preview screenshot tests

Roborazzi provides a helper function for ComposePreviewScanner.
You can add the following dependency to your project to use the helper function:

`testImplementation("io.github.takahirom.roborazzi:roborazzi-compose-preview-scanner-support:[version]")`

Then you can use the `ComposablePreview<AndroidPreviewInfo>.captureRoboImage()` function to capture the Composable Preview using the settings in Preview annotations.
To obtain the `ComposablePreview` object, please refer to [ComposePreviewScanner](https://github.com/sergio-sastre/ComposablePreviewScanner).

```kotlin
fun ComposablePreview<AndroidPreviewInfo>.captureRoboImage(
filePath: String,
roborazziOptions: RoborazziOptions
)
```

### The supported `@Preview` annotation options

Currently, we don't support all the annotation options provided by the Compose Preview.
You can check the supported annotations in the [source code](https://github.com/takahirom/roborazzi/blob/main/roborazzi-compose-preview-scanner-support/src/main/java/com/github/takahirom/roborazzi/RobolectricPreviewInfosApplier.kt).
We are looking forward to your contributions to support more annotation options.
5 changes: 5 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ webjar-material-design-icons = "4.0.0"
webjar-materialize = "1.0.0"
webjars-locator-lite = "0.0.4"

composable-preview-scanner = "0.1.2"

[libraries]
roborazzi = { module = "io.github.takahirom.roborazzi:roborazzi", version.ref = "roborazzi-for-replacing-by-include-build" }
roborazzi-junit-rule = { module = "io.github.takahirom.roborazzi:roborazzi-junit-rule", version.ref = "roborazzi-for-replacing-by-include-build" }
Expand All @@ -53,6 +55,9 @@ kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test" }
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit" }

# for sample
composable-preview-scanner = { module = "com.github.sergio-sastre.ComposablePreviewScanner:android", version.ref = "composable-preview-scanner" }

androidx-activity = { module = "androidx.activity:activity", version.ref = "androidx-activity" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ object DefaultFileNameGenerator {
EscapedTestPackageAndClassAndMethod("escapedTestPackageAndClassAndMethod"),
TestClassAndMethod("testClassAndMethod");

@ExperimentalRoborazziApi
fun generateOutputName(className: String, methodName: String?): String {
return when (this) {
TestPackageAndClassAndMethod -> "$className.$methodName"
EscapedTestPackageAndClassAndMethod -> className.replace(
".",
"_"
) + "." + methodName

TestClassAndMethod -> className.substringAfterLast(".") + "." + methodName
}
}

companion object {
fun fromOptionName(optionName: String): DefaultNamingStrategy {
return values().firstOrNull { it.optionName == optionName } ?: TestPackageAndClassAndMethod
Expand Down Expand Up @@ -89,7 +102,7 @@ object DefaultFileNameGenerator {
}
?: throw IllegalArgumentException("Roborazzi can't find method of test. Please specify file name or use Rule")
val testName =
generateOutputName(stackTraceElement.className, stackTraceElement.methodName)
defaultNamingStrategy.generateOutputName(stackTraceElement.className, stackTraceElement.methodName)
return testName
}

Expand All @@ -112,19 +125,8 @@ object DefaultFileNameGenerator {
internal fun generateOutputNameWithDescription(description: Description): String {
val className = description.className
val methodName = description.methodName
val testName = generateOutputName(className, methodName)
val testName = defaultNamingStrategy.generateOutputName(className, methodName)
return testName
}

private fun generateOutputName(className: String, methodName: String?): String {
return when (defaultNamingStrategy) {
DefaultNamingStrategy.TestPackageAndClassAndMethod -> "$className.$methodName"
DefaultNamingStrategy.EscapedTestPackageAndClassAndMethod -> className.replace(
".",
"_"
) + "." + methodName

DefaultNamingStrategy.TestClassAndMethod -> className.substringAfterLast(".") + "." + methodName
}
}
}
Loading
Loading