Repository: takahirom/roborazzi
Pull request #435 (2024-07-15 02:57:34)

Fix GenerateRobolectricComposePreviewTests to support KMP

github-actions[bot]: Snapshot diff report
| File name | Image |
|-------|-------|
| [com.github.takahirom<br>.preview.tests.Previ<br>ewsKt.PreviewNormal_<br>compare.png](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewNormal_compare.png) | ![](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewNormal_compare.png?raw=true) |
| [com.github.takahirom<br>.preview.tests.Previ<br>ewsKt.PreviewWithPro<br>perties2.WITH_SYSTEM<br>_UI_WITH_BACKGROUND_<br>BG_COLOR_4278190335_<br>NIGHT_NEXUS_5_WALLPA<br>PER_GREEN_DOMINATED_<br>compare.png](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewWithProperties2.WITH_SYSTEM_UI_WITH_BACKGROUND_BG_COLOR_4278190335_NIGHT_NEXUS_5_WALLPAPER_GREEN_DOMINATED_compare.png) | ![](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewWithProperties2.WITH_SYSTEM_UI_WITH_BACKGROUND_BG_COLOR_4278190335_NIGHT_NEXUS_5_WALLPAPER_GREEN_DOMINATED_compare.png?raw=true) |
| [com.github.takahirom<br>.preview.tests.Previ<br>ewsKt.PreviewDarkMod<br>e.NIGHT_compare.png](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewDarkMode.NIGHT_compare.png) | ![](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewDarkMode.NIGHT_compare.png?raw=true) |
| [com.github.takahirom<br>.preview.tests.Previ<br>ewsKt.PreviewWithPro<br>perties1.Preview_Nam<br>e_Preview_Group_API_<br>LEVEL_30_W320dp_H640<br>dp_ja-rJP_FONT_1_5f_<br>compare.png](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewWithProperties1.Preview_Name_Preview_Group_API_LEVEL_30_W320dp_H640dp_ja-rJP_FONT_1_5f_compare.png) | ![](https://github.com/takahirom/roborazzi/blob/companion_takahirom/fix-kmp-module/2024-07-15/./screenshot-diff/sample-generate-preview-tests/build/outputs/roborazzi/com.github.takahirom.preview.tests.PreviewsKt.PreviewWithProperties1.Preview_Name_Preview_Group_API_LEVEL_30_W320dp_H640dp_ja-rJP_FONT_1_5f_compare.png?raw=true) |

Patch:
diff --git a/gradle.properties b/gradle.properties
index 50659a2b..0d67baf7 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-VERSION_NAME=1.22.1
+VERSION_NAME=1.22.0
 GROUP=io.github.takahirom.roborazzi
 # Project-wide Gradle settings.
 
diff --git a/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/RoborazziPlugin.kt b/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/RoborazziPlugin.kt
index 004a5caa..3392aaf2 100644
--- a/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/RoborazziPlugin.kt
+++ b/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/RoborazziPlugin.kt
@@ -436,7 +436,6 @@ abstract class RoborazziPlugin : Plugin<Project> {
           project = project,
           variant = variant,
           extension = extension.generateComposePreviewRobolectricTests,
-          androidExtension = project.extensions.getByType(TestedExtension::class.java),
           testTaskProvider = findTestTaskProvider(Test::class, testTaskName)
         )
 
@@ -451,10 +450,20 @@ abstract class RoborazziPlugin : Plugin<Project> {
     project.pluginManager.withPlugin("com.android.application") {
       project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java)
         .configureComponents()
+      verifyGenerateRobolectricPreviewTests(
+        project = project,
+        androidExtension = project.extensions.getByType(TestedExtension::class.java),
+        extension = extension.generateComposePreviewRobolectricTests
+      )
     }
     project.pluginManager.withPlugin("com.android.library") {
       project.extensions.getByType(LibraryAndroidComponentsExtension::class.java)
         .configureComponents()
+      verifyGenerateRobolectricPreviewTests(
+        project = project,
+        androidExtension = project.extensions.getByType(TestedExtension::class.java),
+        extension = extension.generateComposePreviewRobolectricTests
+      )
     }
     project.pluginManager.withPlugin("org.jetbrains.kotlin.jvm") {
       // e.g. test -> recordRoborazziJvm


Test patch:
diff --git a/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/PreviewGenerateTest.kt b/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/PreviewGenerateTest.kt
index ad73ac7e..d9d70b7b 100644
--- a/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/PreviewGenerateTest.kt
+++ b/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/PreviewGenerateTest.kt
@@ -14,6 +14,15 @@ class GeneratePreviewTestTest {
     RoborazziGradleRootProject(testProjectDir).previewModule.apply {
       record()
 
+      checkHasImages()
+    }
+  }
+  @Test
+  fun whenKmpModuleAndRecordRunImagesShouldBeRecorded() {
+    RoborazziGradleRootProject(testProjectDir).previewModule.apply {
+      buildGradle.isKmp = true
+      record()
+
       checkHasImages()
     }
   }
@@ -23,7 +32,152 @@ class PreviewModule(
   val rootProject: RoborazziGradleRootProject,
   val testProjectDir: TemporaryFolder
 ) {
-  val moduleName = "sample-generate-preview-tests"
+  companion object {
+    val moduleName = "sample-generate-preview-tests"
+  }
+  val buildGradle = BuildGradle(testProjectDir)
+
+  class BuildGradle(private val projectFolder: TemporaryFolder) {
+    private val PATH = moduleName + "/build.gradle.kts"
+    var isKmp = false
+    fun write() {
+      val file =
+        projectFolder.root.resolve(PATH)
+      file.parentFile.mkdirs()
+      val androidBlock = """
+          android {
+            namespace = "com.github.takahirom.preview.tests"
+            compileSdk = 34
+
+            defaultConfig {
+              minSdk = 24
+
+              testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+            }
+            buildFeatures {
+              compose = true
+            }
+            composeOptions {
+              kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
+            }
+
+            buildTypes {
+              release {
+                isMinifyEnabled = false
+                proguardFiles(
+                  getDefaultProguardFile("proguard-android-optimize.txt"),
+                  "proguard-rules.pro"
+                )
+              }
+            }
+            testOptions {
+              unitTests {
+                isIncludeAndroidResources = true
+                all {
+                  it.systemProperties["robolectric.pixelCopyRenderMode"] = "hardware"
+                }
+              }
+            }
+          }
+
+      """.trimIndent()
+      val buildGradleText = if(isKmp)
+        """
+          plugins {
+              kotlin("multiplatform")
+              id("com.android.library")
+              id("org.jetbrains.compose")
+              id("io.github.takahirom.roborazzi")
+          }
+
+          kotlin {
+              androidTarget()
+              
+              sourceSets {
+                  val androidMain by getting {
+                      dependencies {
+                          implementation(compose.material3)
+                          implementation(compose.ui)
+                          implementation(compose.uiTooling)
+                          implementation(compose.runtime)
+                      }
+                  }
+                  
+                  val androidUnitTest by getting {
+                      dependencies {
+                          implementation("io.github.takahirom.roborazzi:roborazzi-compose-preview-scanner-support:0.1.0")
+                          implementation(libs.junit)
+                          implementation(libs.robolectric)
+                          implementation(libs.composable.preview.scanner)
+                      }
+                  }
+                  
+                  val androidInstrumentedTest by getting {
+                      dependencies {
+                          implementation(libs.androidx.test.ext.junit)
+                          implementation(libs.androidx.test.espresso.core)
+                      }
+                  }
+              }
+          }
+
+          $androidBlock
+
+          roborazzi {
+              generateComposePreviewRobolectricTests {
+                  enable = true
+                  packages = listOf("com.github.takahirom.preview.tests")
+              }
+          }
+
+          repositories {
+              mavenCentral()
+              google()
+              maven { url = uri("https://jitpack.io") }
+          }
+        """.trimIndent()
+        else """
+  plugins {
+    id("com.android.application")
+  //  id("com.android.library")
+    id("org.jetbrains.kotlin.android")
+    id("io.github.takahirom.roborazzi")
+  }
+
+  roborazzi {
+    generateComposePreviewRobolectricTests {
+      enable = true
+      packages = listOf("com.github.takahirom.preview.tests")
+    }
+  }
+
+  repositories {
+    mavenCentral()
+    google()
+    maven { url = uri("https://jitpack.io") }
+  }
+  $androidBlock
+
+  dependencies {
+    implementation(libs.androidx.compose.material3)
+    implementation(libs.androidx.compose.ui)
+    implementation(libs.androidx.compose.ui.tooling)
+    implementation(libs.androidx.compose.runtime)
+
+    // replaced by dependency substitution
+    testImplementation("io.github.takahirom.roborazzi:roborazzi-compose-preview-scanner-support:0.1.0")
+    testImplementation(libs.junit)
+    testImplementation(libs.robolectric)
+    testImplementation(libs.composable.preview.scanner)
+    androidTestImplementation(libs.androidx.test.ext.junit)
+    androidTestImplementation(libs.androidx.test.espresso.core)
+  }
+"""
+      file.writeText(
+        buildGradleText.trimIndent()
+      )
+    }
+  }
 
   fun record() {
     runTask("recordRoborazziDebug")
@@ -34,6 +188,7 @@ class PreviewModule(
     buildType: BuildType = BuildType.Build,
     additionalParameters: Array<String> = arrayOf()
   ): BuildResult {
+    buildGradle.write()
     val buildResult = rootProject.runTask(
       ":$moduleName:" + task,
       buildType,
diff --git a/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProject.kt b/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProject.kt
index 82e81e88..9e1bbcfb 100644
--- a/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProject.kt
+++ b/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProject.kt
@@ -173,7 +173,7 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir:
     buildType: BuildType = BuildType.Build,
     additionalParameters: Array<String> = arrayOf()
   ): BuildResult {
-    appBuildFile.addIncludeBuild()
+    buildGradle.addIncludeBuild()
 
     val buildResult = rootProject.runTask(
       "app:"+task,
@@ -183,7 +183,7 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir:
     return buildResult
   }
 
-  class AppBuildFile(private val folder: TemporaryFolder) {
+  class BuildGradle(private val folder: TemporaryFolder) {
     private val PATH = "app/build.gradle.kts"
     var removeOutputDirBeforeTestTypeTask = false
     var customOutputDirPath: String? = null
@@ -644,5 +644,5 @@ class RoborazziTest {
     )
   }
 
-  val appBuildFile = AppBuildFile(testProjectDir)
+  val buildGradle = BuildGradle(testProjectDir)
 }
diff --git a/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProjectTest.kt b/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProjectTest.kt
index 82a78724..436410ce 100644
--- a/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProjectTest.kt
+++ b/include-build/roborazzi-gradle-plugin/src/integrationTest/java/io/github/takahirom/roborazzi/RoborazziGradleProjectTest.kt
@@ -119,7 +119,7 @@ class RoborazziGradleProjectTest {
   fun recordWhenRunTwiceWithGradleCustomOutput() {
     RoborazziGradleRootProject(testProjectDir).appModule.apply {
       val customDirFromGradle = "src/screenshots/roborazzi_customdir_from_gradle"
-      appBuildFile.customOutputDirPath = customDirFromGradle
+      buildGradle.customOutputDirPath = customDirFromGradle
       val output1 = record().output
       assertNotSkipped(output1)
       val output2 = record().output
@@ -178,7 +178,7 @@ class RoborazziGradleProjectTest {
   @Test
   fun canRecordWhenRemoveOutputDirBeforeTests() {
     RoborazziGradleRootProject(testProjectDir).appModule.apply {
-      appBuildFile.removeOutputDirBeforeTestTypeTask = true
+      buildGradle.removeOutputDirBeforeTestTypeTask = true
       record()
     }
   }
diff --git a/include-build/roborazzi-gradle-plugin/src/integrationTest/projects/build.gradle.kts b/include-build/roborazzi-gradle-plugin/src/integrationTest/projects/build.gradle.kts
index 78227c3e..9f020739 100644
--- a/include-build/roborazzi-gradle-plugin/src/integrationTest/projects/build.gradle.kts
+++ b/include-build/roborazzi-gradle-plugin/src/integrationTest/projects/build.gradle.kts
@@ -23,11 +23,23 @@ allprojects {
     }
   }
 
-  plugins.withType(com.android.build.gradle.BasePlugin::class.java).configureEach {
-    configure<com.android.build.gradle.internal.dsl.BaseAppModuleExtension> {
-      compileOptions {
-        sourceCompatibility = javaTargetVersion
-        targetCompatibility = javaTargetVersion
+  fun configureAndroid(extension: com.android.build.gradle.BaseExtension) {
+    extension.compileOptions {
+      sourceCompatibility = javaTargetVersion
+      targetCompatibility = javaTargetVersion
+    }
+  }
+  plugins.withType<com.android.build.gradle.BasePlugin>().configureEach {
+    when (this) {
+      is com.android.build.gradle.AppPlugin -> {
+        extensions.configure<com.android.build.gradle.internal.dsl.BaseAppModuleExtension> {
+          configureAndroid(this)
+        }
+      }
+      is com.android.build.gradle.LibraryPlugin -> {
+        extensions.configure<com.android.build.gradle.LibraryExtension> {
+          configureAndroid(this)
+        }
       }
     }
   }
diff --git a/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/GenerateRobolectricComposePreviewTestsExtension.kt b/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/GenerateRobolectricComposePreviewTestsExtension.kt
index 2b909a3f..83657b50 100644
--- a/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/GenerateRobolectricComposePreviewTestsExtension.kt
+++ b/include-build/roborazzi-gradle-plugin/src/main/java/io/github/takahirom/roborazzi/GenerateRobolectricComposePreviewTestsExtension.kt
@@ -4,7 +4,6 @@ import com.android.build.api.variant.Variant
 import com.android.build.gradle.TestedExtension
 import org.gradle.api.DefaultTask
 import org.gradle.api.Project
-import org.gradle.api.artifacts.Configuration
 import org.gradle.api.artifacts.repositories.MavenArtifactRepository
 import org.gradle.api.file.DirectoryProperty
 import org.gradle.api.logging.Logger
@@ -55,7 +54,6 @@ fun generateRobolectricPreviewTestsIfNeeded(
   project: Project,
   variant: Variant,
   extension: GenerateComposePreviewRobolectricTestsExtension,
-  androidExtension: TestedExtension,
   testTaskProvider: TaskCollection<Test>
 ) {
   if ((extension.enable.orNull) != true) {
@@ -74,9 +72,7 @@ fun generateRobolectricPreviewTestsIfNeeded(
     check(variant.unitTest != null) {
       "Roborazzi: Please enable unit tests for the variant '${variant.name}' in the 'build.gradle' file."
     }
-    verifyMavenRepository(project)
-    verifyLibraryDependencies(project.configurations.getByName("testImplementation"))
-    verifyTestConfig(testTaskProvider, androidExtension, logger)
+    verifyTestConfig(testTaskProvider, logger)
   }
 }
 
@@ -111,6 +107,101 @@ private fun setupGeneratePreviewTestsTask(
   )
 }
 
+abstract class GeneratePreviewScreenshotTestsTask : DefaultTask() {
+  @get:OutputDirectory
+  abstract val outputDir: DirectoryProperty
+
+  @get:Input
+  var scanPackageTrees: ListProperty<String> = project.objects.listProperty(String::class.java)
+
+  @get:Input
+  abstract val customTestQualifiedClassName: Property<String>
+
+  @get:Input
+  abstract val robolectricConfig: MapProperty<String, String>
+
+  @TaskAction
+  fun generateTests() {
+    val testDir = outputDir.get().asFile
+    testDir.mkdirs()
+
+    val packagesExpr = scanPackageTrees.get().joinToString(", ") { "\"$it\"" }
+
+    val generatedClassFQDN = "com.github.takahirom.roborazzi.RoborazziPreviewParameterizedTests"
+    val packageName = generatedClassFQDN.substringBeforeLast(".")
+    val className = generatedClassFQDN.substringAfterLast(".")
+    val directory = File(testDir, packageName.replace(".", "/"))
+    directory.mkdirs()
+    val robolectricConfigString =
+      "@Config(" + robolectricConfig.get().entries.joinToString(", ") { (key, value) ->
+        "$key = $value"
+      } + ")"
+    val customTestQualifiedClassNameString = customTestQualifiedClassName.get()
+    File(directory, "$className.kt").writeText(
+      """
+            package $packageName
+            import org.junit.Test
+            import org.junit.runner.RunWith
+            import org.robolectric.ParameterizedRobolectricTestRunner
+            import org.robolectric.annotation.Config
+            import org.robolectric.annotation.GraphicsMode
+            import com.github.takahirom.roborazzi.*
+            import sergio.sastre.composable.preview.scanner.core.preview.ComposablePreview
+            import sergio.sastre.composable.preview.scanner.android.AndroidPreviewInfo
+            import sergio.sastre.composable.preview.scanner.android.AndroidComposablePreviewScanner
+            import sergio.sastre.composable.preview.scanner.android.screenshotid.AndroidPreviewScreenshotIdBuilder
+
+
+            @RunWith(ParameterizedRobolectricTestRunner::class)
+            @OptIn(InternalRoborazziApi::class)
+            @GraphicsMode(GraphicsMode.Mode.NATIVE)
+            class $className(
+                private val preview: ComposablePreview<AndroidPreviewInfo>,
+            ) {
+
+                companion object {
+                    // lazy for performance
+                    val previews: List<ComposablePreview<AndroidPreviewInfo>> by lazy {
+                        getRobolectricPreviewTest("$customTestQualifiedClassNameString").previews(
+                            $packagesExpr
+                        )
+                    }
+                    @JvmStatic
+                    @ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
+                    fun values(): List<ComposablePreview<AndroidPreviewInfo>> =
+                        previews
+                }
+                
+                
+                @GraphicsMode(GraphicsMode.Mode.NATIVE)
+                $robolectricConfigString
+                @Test
+                fun test() {
+                    getRobolectricPreviewTest("$customTestQualifiedClassNameString").test(preview)
+                }
+
+            }
+        """.trimIndent()
+    )
+  }
+}
+
+fun verifyGenerateRobolectricPreviewTests(
+  project: Project,
+  androidExtension: TestedExtension,
+  extension: GenerateComposePreviewRobolectricTestsExtension
+) {
+  if ((extension.enable.orNull) != true) {
+    return
+  }
+  val logger = project.logger
+  project.afterEvaluate {
+    verifyMavenRepository(project)
+    verifyLibraryDependencies(project)
+    verifyAndroidConfig(androidExtension, logger)
+  }
+}
+
 private fun verifyMavenRepository(project: Project) {
   // Check if the jitpack repository is added.
   val hasJitpackRepo = project.repositories.any {
@@ -140,15 +231,8 @@ private fun verifyMavenRepository(project: Project) {
 
 private fun verifyTestConfig(
   testTaskProvider: TaskCollection<Test>,
-  androidExtension: TestedExtension,
   logger: Logger
 ) {
-  if (!androidExtension.testOptions.unitTests.isIncludeAndroidResources) {
-    logger.warn(
-      "Roborazzi: Please set 'android.testOptions.unitTests.isIncludeAndroidResources = true' in the 'build.gradle' file. " +
-        "This is advisable to avoid issues with ActivityNotFoundException."
-    )
-  }
   testTaskProvider.configureEach { testTask ->
     if (testTask.systemProperties["roborazzi.record.filePathStrategy"] != "relativePathFromRoborazziContextOutputDirectory") {
       logger.info(
@@ -181,15 +265,33 @@ private fun verifyTestConfig(
 }
 
 private fun verifyLibraryDependencies(
-  runtimeConfiguration: Configuration,
+  project: Project
 ) {
-  val dependencies = runtimeConfiguration.dependencies
-    .map { dependency -> dependency.group to dependency.name }
+  val dependencies: Set<Pair<String?, String>> = project.configurations.flatMap { it.dependencies }
+    .map { it.group to it.name }
+    .toSet()
+  verifyLibraryDependencies(dependencies)
+}
+
+private fun verifyAndroidConfig(androidExtension: TestedExtension, logger: Logger) {
+  if (!androidExtension.testOptions.unitTests.isIncludeAndroidResources) {
+    logger.warn(
+      "Roborazzi: Please set 'android.testOptions.unitTests.isIncludeAndroidResources = true' in the 'build.gradle' file. " +
+        "This is advisable to avoid issues with ActivityNotFoundException."
+    )
+  }
+}
 
-  fun checkExists(libraryName: String) {
-    if (!dependencies.contains(libraryName.split(":").let { it[0] to it[1] })) {
+private fun verifyLibraryDependencies(
+  allDependencies: Set<Pair<String?, String>>
+) {
+  fun Set<Pair<String?, String>>.checkExists(libraryName: String) {
+    val dependencies = this
+    val libNameArray = libraryName.split(":")
+    if (!dependencies.contains(libNameArray[0] to libNameArray[1])) {
+      val configurationNames = "'testImplementation'"
       error(
-        "Roborazzi: Please add the following 'testImplementation' dependency to the 'dependencies' block in the 'build.gradle' file: '$libraryName' for the '${runtimeConfiguration.name}' configuration.\n" +
+        "Roborazzi: Please add the following $configurationNames dependency to the 'dependencies' block in the 'build.gradle' file: '$libraryName' for the $configurationNames configuration.\n" +
           "For your convenience, visit https://www.google.com/search?q=" + URLEncoder.encode(
           "$libraryName version",
           "UTF-8"
@@ -205,83 +307,5 @@ private fun verifyLibraryDependencies(
     "org.robolectric:robolectric",
     "com.github.sergio-sastre.ComposablePreviewScanner:android",
   )
-  requiredLibraries.forEach { checkExists(it) }
+  requiredLibraries.forEach { allDependencies.checkExists(it) }
 }
-
-abstract class GeneratePreviewScreenshotTestsTask : DefaultTask() {
-  @get:OutputDirectory
-  abstract val outputDir: DirectoryProperty
-
-  @get:Input
-  var scanPackageTrees: ListProperty<String> = project.objects.listProperty(String::class.java)
-
-  @get:Input
-  abstract val customTestQualifiedClassName: Property<String>
-
-  @get:Input
-  abstract val robolectricConfig: MapProperty<String, String>
-
-  @TaskAction
-  fun generateTests() {
-    val testDir = outputDir.get().asFile
-    testDir.mkdirs()
-
-    val packagesExpr = scanPackageTrees.get().joinToString(", ") { "\"$it\"" }
-
-    val generatedClassFQDN = "com.github.takahirom.roborazzi.RoborazziPreviewParameterizedTests"
-    val packageName = generatedClassFQDN.substringBeforeLast(".")
-    val className = generatedClassFQDN.substringAfterLast(".")
-    val directory = File(testDir, packageName.replace(".", "/"))
-    directory.mkdirs()
-    val robolectricConfigString =
-      "@Config(" + robolectricConfig.get().entries.joinToString(", ") { (key, value) ->
-        "$key = $value"
-      } + ")"
-    val customTestQualifiedClassNameString = customTestQualifiedClassName.get()
-    File(directory, "$className.kt").writeText(
-      """
-            package $packageName
-            import org.junit.Test
-            import org.junit.runner.RunWith
-            import org.robolectric.ParameterizedRobolectricTestRunner
-            import org.robolectric.annotation.Config
-            import org.robolectric.annotation.GraphicsMode
-            import com.github.takahirom.roborazzi.*
-            import sergio.sastre.composable.preview.scanner.core.preview.ComposablePreview
-            import sergio.sastre.composable.preview.scanner.android.AndroidPreviewInfo
-            import sergio.sastre.composable.preview.scanner.android.AndroidComposablePreviewScanner
-            import sergio.sastre.composable.preview.scanner.android.screenshotid.AndroidPreviewScreenshotIdBuilder
-
-
-            @RunWith(ParameterizedRobolectricTestRunner::class)
-            @GraphicsMode(GraphicsMode.Mode.NATIVE)
-            class $className(
-                private val preview: ComposablePreview<AndroidPreviewInfo>,
-            ) {
-
-                companion object {
-                    // lazy for performance
-                    val previews: List<ComposablePreview<AndroidPreviewInfo>> by lazy {
-                        getRobolectricPreviewTest("$customTestQualifiedClassNameString").previews(
-                            $packagesExpr
-                        )
-                    }
-                    @JvmStatic
-                    @ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
-                    fun values(): List<ComposablePreview<AndroidPreviewInfo>> =
-                        previews
-                }
-                
-                
-                @GraphicsMode(GraphicsMode.Mode.NATIVE)
-                $robolectricConfigString
-                @Test
-                fun test() {
-                    getRobolectricPreviewTest("$customTestQualifiedClassNameString").test(preview)
-                }
-
-            }
-        """.trimIndent()
-    )
-  }
-}
\ No newline at end of file