From 142c6b8174e38992a4a8dabad78f4997f9c63677 Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 11:41:00 +0900 Subject: [PATCH 01/13] Add deleteOldScreenshots option --- .../roborazzi/RoborazziGradleProject.kt | 8 ++++++++ .../takahirom/roborazzi/RoborazziPlugin.kt | 20 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) 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 c3667a3bd..1b17f18a4 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 @@ -300,6 +300,14 @@ dependencies { """.trimIndent() ) } + buildFile.appendText( + """ + + roborazzi { + deleteOldScreenshots = true + } + """.trimIndent() + ) } } 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 b6542cb22..9ab1f6a63 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 @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetWithTests import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeBinaryTestRun import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest +import java.io.File import java.io.FileNotFoundException import java.util.Locale import javax.inject.Inject @@ -45,6 +46,9 @@ private const val DEFAULT_TEMP_DIR = "intermediates/roborazzi" open class RoborazziExtension @Inject constructor(objects: ObjectFactory) { val outputDir: DirectoryProperty = objects.directoryProperty() + @ExperimentalRoborazziApi + val deleteOldScreenshots: Property = objects.property(Boolean::class.java) + .convention(false) @ExperimentalRoborazziApi val generateComposePreviewRobolectricTests: GenerateComposePreviewRobolectricTestsExtension = @@ -77,7 +81,7 @@ abstract class RoborazziPlugin : Plugin { else -> throw IllegalStateException("Unsupported test task type: $this") } - @OptIn(InternalRoborazziApi::class) + @OptIn(InternalRoborazziApi::class, ExperimentalRoborazziApi::class) override fun apply(project: Project) { val extension = project.extensions.create("roborazzi", RoborazziExtension::class.java) @@ -292,6 +296,20 @@ abstract class RoborazziPlugin : Plugin { val roborazziResults = CaptureResults.from(results) finalizeTestTask.infoln("Roborazzi: Save result to ${resultsSummaryFile.absolutePath} with results:${results.size} summary:${roborazziResults.resultSummary}") + if (extension.deleteOldScreenshots.get()) { + // Remove all files not in the results + val removingFiles: MutableList = outputDir.get().asFile + .listFiles()?.toList().orEmpty().toMutableList() + roborazziResults.captureResults.forEach { result -> + removingFiles.removeIf { file -> + file.name == result.actualFile || file.name == result.compareFile || file.name == result.goldenFile + } + } + removingFiles.forEach { file -> + file.delete() + } + } + val jsonResult = roborazziResults.toJson() resultsSummaryFile.parentFile.mkdirs() resultsSummaryFile.writeText(jsonResult) From 84166d2d3efa6b47f9d42986ba312371623608de Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 13:02:32 +0900 Subject: [PATCH 02/13] Use file path --- .../io/github/takahirom/roborazzi/RoborazziPlugin.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 9ab1f6a63..52bb775e8 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 @@ -302,9 +302,17 @@ abstract class RoborazziPlugin : Plugin { .listFiles()?.toList().orEmpty().toMutableList() roborazziResults.captureResults.forEach { result -> removingFiles.removeIf { file -> - file.name == result.actualFile || file.name == result.compareFile || file.name == result.goldenFile + val files = listOfNotNull( + result.actualFile, + result.compareFile, + result.goldenFile + ) + .map { File(it) } + .map { it.absolutePath } + files.contains(file.absolutePath) } } + finalizeTestTask.infoln("Roborazzi: Remove old files $removingFiles") removingFiles.forEach { file -> file.delete() } From f65e2f4ff5c17e3a6e4eb016ffa18f46d3ca03ed Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 14:43:01 +0900 Subject: [PATCH 03/13] Fix file path --- .../roborazzi/RoborazziGradleProjectTest.kt | 2 ++ .../takahirom/roborazzi/RoborazziPlugin.kt | 28 ++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) 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 b207e37cb..f6e2e70ca 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 @@ -6,6 +6,8 @@ import org.junit.rules.TemporaryFolder /** * Run this test with `cd include-build` and `./gradlew roborazzi-gradle-plugin:check` + * You can also run this test with the following command: + * ./gradlew roborazzi-gradle-plugin:integrationTest --tests "*RoborazziGradleProjectTest.record" */ class RoborazziGradleProjectTest { 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 52bb775e8..f2a11068d 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 @@ -46,6 +46,7 @@ private const val DEFAULT_TEMP_DIR = "intermediates/roborazzi" open class RoborazziExtension @Inject constructor(objects: ObjectFactory) { val outputDir: DirectoryProperty = objects.directoryProperty() + @ExperimentalRoborazziApi val deleteOldScreenshots: Property = objects.property(Boolean::class.java) .convention(false) @@ -298,23 +299,24 @@ abstract class RoborazziPlugin : Plugin { if (extension.deleteOldScreenshots.get()) { // Remove all files not in the results - val removingFiles: MutableList = outputDir.get().asFile - .listFiles()?.toList().orEmpty().toMutableList() + val removingFiles: MutableSet = outputDir.get().asFile + .listFiles() + ?.toList() + .orEmpty() + .filter { it.isFile } + .map { it.absolutePath } + .toMutableSet() roborazziResults.captureResults.forEach { result -> - removingFiles.removeIf { file -> - val files = listOfNotNull( - result.actualFile, - result.compareFile, - result.goldenFile - ) - .map { File(it) } - .map { it.absolutePath } - files.contains(file.absolutePath) - } + val latestFiles = listOfNotNull( + result.actualFile, + result.compareFile, + result.goldenFile + ).map { File(it).absolutePath } + removingFiles.removeAll(latestFiles) } finalizeTestTask.infoln("Roborazzi: Remove old files $removingFiles") removingFiles.forEach { file -> - file.delete() + File(file).delete() } } From f38732a3b59a64bae33abd00ca0ff464d803483e Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 15:02:28 +0900 Subject: [PATCH 04/13] Use gradle.properties and add test --- .../roborazzi/RoborazziGradleProject.kt | 29 ++++++++++++------- .../roborazzi/RoborazziGradleProjectTest.kt | 15 ++++++++++ .../takahirom/roborazzi/RoborazziPlugin.kt | 7 +---- 3 files changed, 34 insertions(+), 17 deletions(-) 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 1b17f18a4..dd7c894ce 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 @@ -18,7 +18,11 @@ class RoborazziGradleRootProject(val testProjectDir: TemporaryFolder) { val appModule = AppModule(this, testProjectDir) val previewModule = PreviewModule(this, testProjectDir) - fun runTask(task: String, buildType: BuildType, additionalParameters: Array): BuildResult { + fun runTask( + task: String, + buildType: BuildType, + additionalParameters: Array + ): BuildResult { val buildResult = GradleRunner.create() .withProjectDir(testProjectDir.root) .withArguments( @@ -60,6 +64,11 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir: return runTask(task) } + fun recordWithDeleteOldScreenshots(): BuildResult { + val task = "recordRoborazziDebug" + return runTask(task, additionalParameters = arrayOf("-Proborazzi.deleteOldScreenshots=true")) + } + fun recordWithFilter1(): BuildResult { val task = "recordRoborazziDebug" return runTask( @@ -136,6 +145,11 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir: return runTask(task) } + fun compareWithDeleteOldScreenshots(): BuildResult { + val task = "compareRoborazziDebug" + return runTask(task, additionalParameters = arrayOf("-Proborazzi.deleteOldScreenshots=true")) + } + fun clear(): BuildResult { val task = "clearRoborazziDebug" return runTask(task) @@ -181,7 +195,7 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir: buildGradle.addIncludeBuild() val buildResult = rootProject.runTask( - "app:"+task, + "app:" + task, buildType, additionalParameters ) @@ -192,8 +206,9 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir: private val PATH = "app/build.gradle.kts" var removeOutputDirBeforeTestTypeTask = false var customOutputDirPath: String? = null + init { - addIncludeBuild() + addIncludeBuild() } fun addIncludeBuild() { @@ -300,14 +315,6 @@ dependencies { """.trimIndent() ) } - buildFile.appendText( - """ - - roborazzi { - deleteOldScreenshots = true - } - """.trimIndent() - ) } } 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 f6e2e70ca..a80e69a0b 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 @@ -394,6 +394,21 @@ class RoborazziGradleProjectTest { } } + @Test + fun compareWithDeleteOldScreenshot() { + RoborazziGradleRootProject(testProjectDir).appModule.apply { + recordWithDeleteOldScreenshots() + changeScreen() + compareWithDeleteOldScreenshots() + + checkResultsSummaryFileExists() + checkRecordedFileExists("$screenshotAndName.testCapture.png") + checkResultFileExists(resultFileSuffix) + checkRecordedFileExists("$screenshotAndName.testCapture_compare.png") + checkRecordedFileExists("$screenshotAndName.testCapture_actual.png") + } + } + @Test fun compareWithSystemParameter() { println("start compareWithSystemParameter") 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 f2a11068d..720f3f5e9 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 @@ -46,11 +46,6 @@ private const val DEFAULT_TEMP_DIR = "intermediates/roborazzi" open class RoborazziExtension @Inject constructor(objects: ObjectFactory) { val outputDir: DirectoryProperty = objects.directoryProperty() - - @ExperimentalRoborazziApi - val deleteOldScreenshots: Property = objects.property(Boolean::class.java) - .convention(false) - @ExperimentalRoborazziApi val generateComposePreviewRobolectricTests: GenerateComposePreviewRobolectricTestsExtension = objects.newInstance(GenerateComposePreviewRobolectricTestsExtension::class.java) @@ -297,7 +292,7 @@ abstract class RoborazziPlugin : Plugin { val roborazziResults = CaptureResults.from(results) finalizeTestTask.infoln("Roborazzi: Save result to ${resultsSummaryFile.absolutePath} with results:${results.size} summary:${roborazziResults.resultSummary}") - if (extension.deleteOldScreenshots.get()) { + if (roborazziProperties["roborazzi.deleteOldScreenshots"] == true) { // Remove all files not in the results val removingFiles: MutableSet = outputDir.get().asFile .listFiles() From 55fa3587d667fc1946ec577321567b9e314a1b33 Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 15:36:00 +0900 Subject: [PATCH 05/13] Add test and fix bug --- .../roborazzi/RoborazziGradleProjectTest.kt | 15 +++++++ .../takahirom/roborazzi/RoborazziPlugin.kt | 43 ++++++++++--------- 2 files changed, 38 insertions(+), 20 deletions(-) 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 a80e69a0b..1f338ac27 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 @@ -437,6 +437,21 @@ class RoborazziGradleProjectTest { } } + @Test + fun ifWeUseDeleteOldScreenshotsTheScreenshotsShouldNotExitOldScreenshot() { + RoborazziGradleRootProject(testProjectDir).appModule.apply { + recordWithDeleteOldScreenshots() + removeTests() + addTestCaptureWithCustomPathTest() + recordWithDeleteOldScreenshots() + + checkResultsSummaryFileExists() + checkRecordedFileNotExists("$screenshotAndName.testCapture.png") + checkRecordedFileExists("$customReferenceScreenshotAndName.png") + checkRecordedFileExists("app/build/outputs/roborazzi/custom_outputDirectoryPath_from_rule/custom_outputFileProvider-com.github.takahirom.integration_test_project.RoborazziTest.testCaptureWithCustomPath.png") + } + } + @Test fun compareWithCustomPath() { RoborazziGradleRootProject(testProjectDir).appModule.apply { 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 720f3f5e9..9ca398efc 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 @@ -46,6 +46,7 @@ private const val DEFAULT_TEMP_DIR = "intermediates/roborazzi" open class RoborazziExtension @Inject constructor(objects: ObjectFactory) { val outputDir: DirectoryProperty = objects.directoryProperty() + @ExperimentalRoborazziApi val generateComposePreviewRobolectricTests: GenerateComposePreviewRobolectricTestsExtension = objects.newInstance(GenerateComposePreviewRobolectricTestsExtension::class.java) @@ -56,6 +57,7 @@ open class RoborazziExtension @Inject constructor(objects: ObjectFactory) { } } +val KnownImageFileExtensions: Array = arrayOf("png", "gif", "jpg", "jpeg", "webp") @Suppress("unused") // From Paparazzi: https://github.com/cashapp/paparazzi/blob/a76702744a7f380480f323ffda124e845f2733aa/paparazzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt @@ -153,7 +155,7 @@ abstract class RoborazziPlugin : Plugin { val outputDirFile = outputDir.get().asFile if (outputDirFile.exists()) { outputDirFile.walkTopDown().forEach { file -> - if (file.name.endsWith(".png") || file.name.endsWith(".gif")) { + if (KnownImageFileExtensions.contains(file.extension)) { file.delete() } } @@ -162,7 +164,7 @@ abstract class RoborazziPlugin : Plugin { val intermediateDirFile = intermediateDirForEachVariant.get().asFile if (intermediateDirFile.exists()) { intermediateDirFile.walkTopDown().forEach { file -> - if (file.name.endsWith(".png") || file.name.endsWith(".gif")) { + if (KnownImageFileExtensions.contains(file.extension)) { file.delete() } } @@ -292,13 +294,29 @@ abstract class RoborazziPlugin : Plugin { val roborazziResults = CaptureResults.from(results) finalizeTestTask.infoln("Roborazzi: Save result to ${resultsSummaryFile.absolutePath} with results:${results.size} summary:${roborazziResults.resultSummary}") - if (roborazziProperties["roborazzi.deleteOldScreenshots"] == true) { + val jsonResult = roborazziResults.toJson() + resultsSummaryFile.parentFile.mkdirs() + resultsSummaryFile.writeText(jsonResult) + val reportFile = reportFileProperty.get().asFile + + reportFile.parentFile.mkdirs() + WebAssets.create().writeToRoborazziReportsDir(reportFile.parentFile) + val reportHtml = readIndexHtmlFile() + ?: throw FileNotFoundException("index.html not found in resources/META-INF folder") + reportFile.writeText( + reportHtml.replace( + oldValue = "REPORT_TEMPLATE_BODY", + newValue = roborazziResults.toHtml(reportFile.parentFile.absolutePath) + ) + ) + + if (roborazziProperties["roborazzi.deleteOldScreenshots"] == "true") { // Remove all files not in the results val removingFiles: MutableSet = outputDir.get().asFile .listFiles() ?.toList() .orEmpty() - .filter { it.isFile } + .filter { it.isFile && KnownImageFileExtensions.contains(it.extension) } .map { it.absolutePath } .toMutableSet() roborazziResults.captureResults.forEach { result -> @@ -309,27 +327,12 @@ abstract class RoborazziPlugin : Plugin { ).map { File(it).absolutePath } removingFiles.removeAll(latestFiles) } - finalizeTestTask.infoln("Roborazzi: Remove old files $removingFiles") + finalizeTestTask.infoln("Roborazzi: Delete old files $removingFiles") removingFiles.forEach { file -> File(file).delete() } } - val jsonResult = roborazziResults.toJson() - resultsSummaryFile.parentFile.mkdirs() - resultsSummaryFile.writeText(jsonResult) - val reportFile = reportFileProperty.get().asFile - - reportFile.parentFile.mkdirs() - WebAssets.create().writeToRoborazziReportsDir(reportFile.parentFile) - val reportHtml = readIndexHtmlFile() - ?: throw FileNotFoundException("index.html not found in resources/META-INF folder") - reportFile.writeText( - reportHtml.replace( - oldValue = "REPORT_TEMPLATE_BODY", - newValue = roborazziResults.toHtml(reportFile.parentFile.absolutePath) - ) - ) } } }) From 268a5627839baa52c2b82c34f9851ab99563c48e Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 15:53:44 +0900 Subject: [PATCH 06/13] Add log --- .../takahirom/roborazzi/RoborazziGradleProjectTest.kt | 8 ++++++++ 1 file changed, 8 insertions(+) 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 1f338ac27..5b38aafeb 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 @@ -3,6 +3,7 @@ package io.github.takahirom.roborazzi import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder +import org.junit.rules.TestWatcher /** * Run this test with `cd include-build` and `./gradlew roborazzi-gradle-plugin:check` @@ -14,6 +15,13 @@ class RoborazziGradleProjectTest { @get:Rule val testProjectDir = TemporaryFolder() + @get:Rule + val testNameOutputRule = object : TestWatcher() { + override fun starting(description: org.junit.runner.Description?) { + println("Test: ${description?.methodName}") + } + } + private val className = "com.github.takahirom.integration_test_project.RoborazziTest" private var defaultBuildDir = "build" From 680508c8639e0021bb555a50d31907c5baf2ebd9 Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 16:49:12 +0900 Subject: [PATCH 07/13] Fix test report generation timing --- .../roborazzi/RoborazziGradleProjectTest.kt | 2 +- .../takahirom/roborazzi/RoborazziPlugin.kt | 111 +++++++++--------- 2 files changed, 56 insertions(+), 57 deletions(-) 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 5b38aafeb..4c9785736 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 @@ -18,7 +18,7 @@ class RoborazziGradleProjectTest { @get:Rule val testNameOutputRule = object : TestWatcher() { override fun starting(description: org.junit.runner.Description?) { - println("Test: ${description?.methodName}") + println("RoborazziGradleProjectTest.${description?.methodName} started") } } 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 9ca398efc..a92998786 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 @@ -57,7 +57,7 @@ open class RoborazziExtension @Inject constructor(objects: ObjectFactory) { } } -val KnownImageFileExtensions: Array = arrayOf("png", "gif", "jpg", "jpeg", "webp") +val KnownImageFileExtensions: Set = setOf("png", "gif", "jpg", "jpeg", "webp") @Suppress("unused") // From Paparazzi: https://github.com/cashapp/paparazzi/blob/a76702744a7f380480f323ffda124e845f2733aa/paparazzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt @@ -281,58 +281,6 @@ abstract class RoborazziPlugin : Plugin { overwrite = true ) finalizeTestTask.infoln("Roborazzi: finalizeTestRoborazziTask Copy files from ${intermediateDir.get()} to ${outputDir.get()} end ${System.currentTimeMillis() - startCopy}ms") - - val results: List = resultDirFileTree.get().mapNotNull { - if (it.name.endsWith(".json")) { - CaptureResult.fromJsonFile(it.path) - } else { - null - } - } - val resultsSummaryFile = resultSummaryFileProperty.get().asFile - - val roborazziResults = CaptureResults.from(results) - finalizeTestTask.infoln("Roborazzi: Save result to ${resultsSummaryFile.absolutePath} with results:${results.size} summary:${roborazziResults.resultSummary}") - - val jsonResult = roborazziResults.toJson() - resultsSummaryFile.parentFile.mkdirs() - resultsSummaryFile.writeText(jsonResult) - val reportFile = reportFileProperty.get().asFile - - reportFile.parentFile.mkdirs() - WebAssets.create().writeToRoborazziReportsDir(reportFile.parentFile) - val reportHtml = readIndexHtmlFile() - ?: throw FileNotFoundException("index.html not found in resources/META-INF folder") - reportFile.writeText( - reportHtml.replace( - oldValue = "REPORT_TEMPLATE_BODY", - newValue = roborazziResults.toHtml(reportFile.parentFile.absolutePath) - ) - ) - - if (roborazziProperties["roborazzi.deleteOldScreenshots"] == "true") { - // Remove all files not in the results - val removingFiles: MutableSet = outputDir.get().asFile - .listFiles() - ?.toList() - .orEmpty() - .filter { it.isFile && KnownImageFileExtensions.contains(it.extension) } - .map { it.absolutePath } - .toMutableSet() - roborazziResults.captureResults.forEach { result -> - val latestFiles = listOfNotNull( - result.actualFile, - result.compareFile, - result.goldenFile - ).map { File(it).absolutePath } - removingFiles.removeAll(latestFiles) - } - finalizeTestTask.infoln("Roborazzi: Delete old files $removingFiles") - removingFiles.forEach { file -> - File(file).delete() - } - } - } } }) @@ -372,15 +320,15 @@ abstract class RoborazziPlugin : Plugin { test.infoln("Roborazzi: Set output dir $it to test task") it }) - test.outputs.dir(resultDirFileProperty.let { + test.outputs.dir(resultDirFileProperty.map { test.infoln("Roborazzi: Set output dir $it to test task") it }) - test.outputs.file(resultSummaryFileProperty.let { + test.outputs.file(resultSummaryFileProperty.map { test.infoln("Roborazzi: Set output file $it to test task") it }) - test.outputs.file(reportFileProperty.let { + test.outputs.file(reportFileProperty.map { test.infoln("Roborazzi: Set output file $it to test task") it }) @@ -457,6 +405,57 @@ abstract class RoborazziPlugin : Plugin { target = intermediateDir.get().asFile, overwrite = true ) + + val results: List = resultDirFileTree.get().mapNotNull { + if (it.name.endsWith(".json")) { + CaptureResult.fromJsonFile(it.path) + } else { + null + } + } + val resultsSummaryFile = resultSummaryFileProperty.get().asFile + + val roborazziResults = CaptureResults.from(results) + test.infoln("Roborazzi: Save result to ${resultsSummaryFile.absolutePath} with results:${results.size} summary:${roborazziResults.resultSummary}") + + val jsonResult = roborazziResults.toJson() + resultsSummaryFile.parentFile.mkdirs() + resultsSummaryFile.writeText(jsonResult) + val reportFile = reportFileProperty.get().asFile + + reportFile.parentFile.mkdirs() + WebAssets.create().writeToRoborazziReportsDir(reportFile.parentFile) + val reportHtml = readIndexHtmlFile() + ?: throw FileNotFoundException("index.html not found in resources/META-INF folder") + reportFile.writeText( + reportHtml.replace( + oldValue = "REPORT_TEMPLATE_BODY", + newValue = roborazziResults.toHtml(reportFile.parentFile.absolutePath) + ) + ) + + if (roborazziProperties["roborazzi.deleteOldScreenshots"] == "true") { + // Remove all files not in the results + val removingFiles: MutableSet = outputDir.get().asFile + .listFiles() + ?.toList() + .orEmpty() + .filter { it.isFile && KnownImageFileExtensions.contains(it.extension) } + .map { it.absolutePath } + .toMutableSet() + roborazziResults.captureResults.forEach { result -> + val latestFiles = listOfNotNull( + result.actualFile, + result.compareFile, + result.goldenFile + ).map { File(it).absolutePath } + removingFiles.removeAll(latestFiles) + } + test.infoln("Roborazzi: Delete old files $removingFiles") + removingFiles.forEach { file -> + File(file).delete() + } + } } override fun beforeTest(testDescriptor: TestDescriptor?) { From a42223d72560547f14af2083b71a7c2ff086c010 Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 16:58:56 +0900 Subject: [PATCH 08/13] Refactor --- .../takahirom/roborazzi/RoborazziPlugin.kt | 110 +++++++++++------- 1 file changed, 71 insertions(+), 39 deletions(-) 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 a92998786..52001f5b4 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 @@ -15,8 +15,10 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.Optional import org.gradle.api.tasks.OutputDirectory @@ -416,46 +418,20 @@ abstract class RoborazziPlugin : Plugin { val resultsSummaryFile = resultSummaryFileProperty.get().asFile val roborazziResults = CaptureResults.from(results) - test.infoln("Roborazzi: Save result to ${resultsSummaryFile.absolutePath} with results:${results.size} summary:${roborazziResults.resultSummary}") - - val jsonResult = roborazziResults.toJson() - resultsSummaryFile.parentFile.mkdirs() - resultsSummaryFile.writeText(jsonResult) - val reportFile = reportFileProperty.get().asFile - - reportFile.parentFile.mkdirs() - WebAssets.create().writeToRoborazziReportsDir(reportFile.parentFile) - val reportHtml = readIndexHtmlFile() - ?: throw FileNotFoundException("index.html not found in resources/META-INF folder") - reportFile.writeText( - reportHtml.replace( - oldValue = "REPORT_TEMPLATE_BODY", - newValue = roborazziResults.toHtml(reportFile.parentFile.absolutePath) - ) + saveResults( + test = test, + resultsSummaryFile = resultsSummaryFile, + results = results, + roborazziResults = roborazziResults, + reportFileProperty = reportFileProperty + ) + // The reason why we do this in afterSuite() is that we want to change the tasks' output in the task execution phase. + deleteOldScreenshotsIfNeeded( + test = test, + roborazziProperties = roborazziProperties, + outputDir = outputDir, + roborazziResults = roborazziResults, ) - - if (roborazziProperties["roborazzi.deleteOldScreenshots"] == "true") { - // Remove all files not in the results - val removingFiles: MutableSet = outputDir.get().asFile - .listFiles() - ?.toList() - .orEmpty() - .filter { it.isFile && KnownImageFileExtensions.contains(it.extension) } - .map { it.absolutePath } - .toMutableSet() - roborazziResults.captureResults.forEach { result -> - val latestFiles = listOfNotNull( - result.actualFile, - result.compareFile, - result.goldenFile - ).map { File(it).absolutePath } - removingFiles.removeAll(latestFiles) - } - test.infoln("Roborazzi: Delete old files $removingFiles") - removingFiles.forEach { file -> - File(file).delete() - } - } } override fun beforeTest(testDescriptor: TestDescriptor?) { @@ -551,6 +527,62 @@ abstract class RoborazziPlugin : Plugin { } } + private fun saveResults( + test: AbstractTestTask, + resultsSummaryFile: File, + results: List, + roborazziResults: CaptureResults, + reportFileProperty: Provider + ) { + test.infoln("Roborazzi: Save result to ${resultsSummaryFile.absolutePath} with results:${results.size} summary:${roborazziResults.resultSummary}") + + val jsonResult = roborazziResults.toJson() + resultsSummaryFile.parentFile.mkdirs() + resultsSummaryFile.writeText(jsonResult) + val reportFile = reportFileProperty.get().asFile + + reportFile.parentFile.mkdirs() + WebAssets.create().writeToRoborazziReportsDir(reportFile.parentFile) + val reportHtml = readIndexHtmlFile() + ?: throw FileNotFoundException("index.html not found in resources/META-INF folder") + reportFile.writeText( + reportHtml.replace( + oldValue = "REPORT_TEMPLATE_BODY", + newValue = roborazziResults.toHtml(reportFile.parentFile.absolutePath) + ) + ) + } + + private fun deleteOldScreenshotsIfNeeded( + test: AbstractTestTask, + roborazziProperties: Map, + outputDir: DirectoryProperty, + roborazziResults: CaptureResults, + ) { + if (roborazziProperties["roborazzi.deleteOldScreenshots"] == "true") { + // Remove all files not in the results + val removingFiles: MutableSet = outputDir.get().asFile + .listFiles() + ?.toList() + .orEmpty() + .filter { it.isFile && KnownImageFileExtensions.contains(it.extension) } + .map { it.absolutePath } + .toMutableSet() + roborazziResults.captureResults.forEach { result -> + val latestFiles = listOfNotNull( + result.actualFile, + result.compareFile, + result.goldenFile + ).map { File(it).absolutePath } + removingFiles.removeAll(latestFiles) + } + test.infoln("Roborazzi: Delete old files $removingFiles") + removingFiles.forEach { file -> + File(file).delete() + } + } + } + private fun readIndexHtmlFile(): String? { return this::class.java.classLoader.getResource("META-INF/index.html")?.readText() } From acfc5d50d560f55a57f507bfa58b938035ea906e Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 17:14:52 +0900 Subject: [PATCH 09/13] Fix order of copy --- .../roborazzi/RoborazziGradleProjectTest.kt | 2 +- .../takahirom/roborazzi/RoborazziPlugin.kt | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) 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 4c9785736..01a7200db 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 @@ -446,7 +446,7 @@ class RoborazziGradleProjectTest { } @Test - fun ifWeUseDeleteOldScreenshotsTheScreenshotsShouldNotExitOldScreenshot() { + fun ifWeUseDeleteOldScreenshotsTheOldScreenshotsShouldNotExit() { RoborazziGradleRootProject(testProjectDir).appModule.apply { recordWithDeleteOldScreenshots() removeTests() 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 52001f5b4..f5d2957d4 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 @@ -396,17 +396,6 @@ abstract class RoborazziPlugin : Plugin { // Run only root suite return } - // Copy all files from outputDir to intermediateDir - // so that we can use Gradle's output caching - test.infoln("Roborazzi: test.doLast Copy files from ${outputDir.get()} to ${intermediateDir.get()}") - // outputDir.get().asFileTree.forEach { - // println("Copy file ${finalizeTask.absolutePath} to ${intermediateDir.get()}") - // } - outputDir.get().asFile.mkdirs() - outputDir.get().asFile.copyRecursively( - target = intermediateDir.get().asFile, - overwrite = true - ) val results: List = resultDirFileTree.get().mapNotNull { if (it.name.endsWith(".json")) { @@ -432,6 +421,18 @@ abstract class RoborazziPlugin : Plugin { outputDir = outputDir, roborazziResults = roborazziResults, ) + + // Copy all files from outputDir to intermediateDir + // so that we can use Gradle's output caching + test.infoln("Roborazzi: test.doLast Copy files from ${outputDir.get()} to ${intermediateDir.get()}") + // outputDir.get().asFileTree.forEach { + // println("Copy file ${finalizeTask.absolutePath} to ${intermediateDir.get()}") + // } + outputDir.get().asFile.mkdirs() + outputDir.get().asFile.copyRecursively( + target = intermediateDir.get().asFile, + overwrite = true + ) } override fun beforeTest(testDescriptor: TestDescriptor?) { From 4918281e4682a91f7560a801ef20d019978cb4d7 Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 17:27:29 +0900 Subject: [PATCH 10/13] Remove intermediate dir when roborazzi.deleteOldScreenshots --- .../io/github/takahirom/roborazzi/RoborazziPlugin.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 f5d2957d4..735c6f287 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 @@ -419,6 +419,7 @@ abstract class RoborazziPlugin : Plugin { test = test, roborazziProperties = roborazziProperties, outputDir = outputDir, + intermediateDir = intermediateDir, roborazziResults = roborazziResults, ) @@ -558,10 +559,18 @@ abstract class RoborazziPlugin : Plugin { test: AbstractTestTask, roborazziProperties: Map, outputDir: DirectoryProperty, + intermediateDir: DirectoryProperty, roborazziResults: CaptureResults, ) { if (roborazziProperties["roborazzi.deleteOldScreenshots"] == "true") { - // Remove all files not in the results + // Delete all images from the intermediateDir + intermediateDir.get().asFile.walkTopDown().forEach { file -> + if (KnownImageFileExtensions.contains(file.extension)) { + file.delete() + } + } + + // Remove all files not in the results from the outputDir val removingFiles: MutableSet = outputDir.get().asFile .listFiles() ?.toList() From 57f88bdac6cc59d91af112fbdbc69b30c48119bf Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 17:37:05 +0900 Subject: [PATCH 11/13] Fix not to run Roborazzi implementation when it is normal unit test --- .../github/takahirom/roborazzi/RoborazziGradleProjectTest.kt | 3 +-- .../java/io/github/takahirom/roborazzi/RoborazziPlugin.kt | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) 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 01a7200db..c4b4ec5ef 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 @@ -318,8 +318,7 @@ class RoborazziGradleProjectTest { removeTests() record() - // Summary file will be generated even if no test files - checkResultsSummaryFileExists() + checkResultsSummaryFileNotExists() // Test will be skipped when no source so no output checkResultFileNotExists(resultFileSuffix) } 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 735c6f287..0f3011498 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 @@ -396,6 +396,11 @@ abstract class RoborazziPlugin : Plugin { // Run only root suite return } + if (doesRoborazziRunProvider.get()) { + test.infoln("Roborazzi: test.afterSuite ${test.name}") + } else { + return + } val results: List = resultDirFileTree.get().mapNotNull { if (it.name.endsWith(".json")) { From 963d544f102e4c49103b017f686b5a3992f1bbf6 Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 18:35:25 +0900 Subject: [PATCH 12/13] Rename option to cleanupOldScreenshots --- .../takahirom/roborazzi/RoborazziGradleProject.kt | 8 ++++---- .../takahirom/roborazzi/RoborazziGradleProjectTest.kt | 10 +++++----- .../io/github/takahirom/roborazzi/RoborazziPlugin.kt | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) 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 dd7c894ce..7a107a9f4 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 @@ -64,9 +64,9 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir: return runTask(task) } - fun recordWithDeleteOldScreenshots(): BuildResult { + fun recordWithCleanupOldScreenshots(): BuildResult { val task = "recordRoborazziDebug" - return runTask(task, additionalParameters = arrayOf("-Proborazzi.deleteOldScreenshots=true")) + return runTask(task, additionalParameters = arrayOf("-Proborazzi.cleanupOldScreenshots=true")) } fun recordWithFilter1(): BuildResult { @@ -145,9 +145,9 @@ class AppModule(val rootProject: RoborazziGradleRootProject, val testProjectDir: return runTask(task) } - fun compareWithDeleteOldScreenshots(): BuildResult { + fun compareWithCleanupOldScreenshots(): BuildResult { val task = "compareRoborazziDebug" - return runTask(task, additionalParameters = arrayOf("-Proborazzi.deleteOldScreenshots=true")) + return runTask(task, additionalParameters = arrayOf("-Proborazzi.cleanupOldScreenshots=true")) } fun clear(): BuildResult { 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 c4b4ec5ef..fa1b27bcb 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 @@ -404,9 +404,9 @@ class RoborazziGradleProjectTest { @Test fun compareWithDeleteOldScreenshot() { RoborazziGradleRootProject(testProjectDir).appModule.apply { - recordWithDeleteOldScreenshots() + recordWithCleanupOldScreenshots() changeScreen() - compareWithDeleteOldScreenshots() + compareWithCleanupOldScreenshots() checkResultsSummaryFileExists() checkRecordedFileExists("$screenshotAndName.testCapture.png") @@ -445,12 +445,12 @@ class RoborazziGradleProjectTest { } @Test - fun ifWeUseDeleteOldScreenshotsTheOldScreenshotsShouldNotExit() { + fun ifWeUseCleanupOldScreenshotsTheOldScreenshotsShouldNotExit() { RoborazziGradleRootProject(testProjectDir).appModule.apply { - recordWithDeleteOldScreenshots() + recordWithCleanupOldScreenshots() removeTests() addTestCaptureWithCustomPathTest() - recordWithDeleteOldScreenshots() + recordWithCleanupOldScreenshots() checkResultsSummaryFileExists() checkRecordedFileNotExists("$screenshotAndName.testCapture.png") 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 0f3011498..b8ece69eb 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 @@ -420,7 +420,7 @@ abstract class RoborazziPlugin : Plugin { reportFileProperty = reportFileProperty ) // The reason why we do this in afterSuite() is that we want to change the tasks' output in the task execution phase. - deleteOldScreenshotsIfNeeded( + cleanupOldScreenshotsIfNeeded( test = test, roborazziProperties = roborazziProperties, outputDir = outputDir, @@ -560,14 +560,14 @@ abstract class RoborazziPlugin : Plugin { ) } - private fun deleteOldScreenshotsIfNeeded( + private fun cleanupOldScreenshotsIfNeeded( test: AbstractTestTask, roborazziProperties: Map, outputDir: DirectoryProperty, intermediateDir: DirectoryProperty, roborazziResults: CaptureResults, ) { - if (roborazziProperties["roborazzi.deleteOldScreenshots"] == "true") { + if (roborazziProperties["roborazzi.cleanupOldScreenshots"] == "true") { // Delete all images from the intermediateDir intermediateDir.get().asFile.walkTopDown().forEach { file -> if (KnownImageFileExtensions.contains(file.extension)) { @@ -591,7 +591,7 @@ abstract class RoborazziPlugin : Plugin { ).map { File(it).absolutePath } removingFiles.removeAll(latestFiles) } - test.infoln("Roborazzi: Delete old files $removingFiles") + test.infoln("Roborazzi: Cleanup old files $removingFiles") removingFiles.forEach { file -> File(file).delete() } From bdc2ca0cf8f04099ced6c837bc460158df6fa80a Mon Sep 17 00:00:00 2001 From: takahirom Date: Mon, 4 Nov 2024 19:22:56 +0900 Subject: [PATCH 13/13] Add roborazzi.cleanupOldScreenshots section --- README.md | 12 +++++++++++- docs/topics/ai_powered_image_assertion.md | 2 ++ docs/topics/gradle_properties_options.md | 12 +++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 36fd3c338..5371e5262 100644 --- a/README.md +++ b/README.md @@ -1391,7 +1391,8 @@ The sample image # Roborazzi gradle.properties Options and Recommendations -You can configure the following options in your `gradle.properties` file: +You can configure the following options in your `gradle.properties` file. +You can also use `-P` to set the options in the command line. For example, `./gradlew test -Proborazzi.test.record=true`. ## roborazzi.test @@ -1434,6 +1435,15 @@ This option enables you to define the naming strategy for the recorded image. Th roborazzi.record.namingStrategy=testClassAndMethod ``` +## roborazzi.cleanupOldScreenshots + +This option allows you to clean up old screenshots. By default, this option is set to false. +The reason why Roborazzi does not delete old screenshots by default is that Roborazzi doesn't know if you are running filtered tests or not. If you are running filtered tests, Roborazzi will delete the screenshots that are not related to the current test run. + +``` +roborazzi.cleanupOldScreenshots=true +``` + ## Robolectric Options ### robolectric.pixelCopyRenderMode diff --git a/docs/topics/ai_powered_image_assertion.md b/docs/topics/ai_powered_image_assertion.md index 9e708b840..87c62b6bb 100644 --- a/docs/topics/ai_powered_image_assertion.md +++ b/docs/topics/ai_powered_image_assertion.md @@ -19,6 +19,8 @@ val roborazziRule = RoborazziRule( compareOptions = RoborazziOptions.CompareOptions( aiAssertionOptions = AiAssertionOptions( aiAssertionModel = GeminiAiAssertionModel( + // DO NOT HARDCODE your API key in your code. + // This is an example passing API Key through unitTests.all{ environment(key, value) } apiKey = System.getenv("gemini_api_key") ?: "" ), ) diff --git a/docs/topics/gradle_properties_options.md b/docs/topics/gradle_properties_options.md index a209c9648..2146e2b73 100644 --- a/docs/topics/gradle_properties_options.md +++ b/docs/topics/gradle_properties_options.md @@ -1,6 +1,7 @@ # Roborazzi gradle.properties Options and Recommendations -You can configure the following options in your `gradle.properties` file: +You can configure the following options in your `gradle.properties` file. +You can also use `-P` to set the options in the command line. For example, `./gradlew test -Proborazzi.test.record=true`. ## roborazzi.test @@ -43,6 +44,15 @@ This option enables you to define the naming strategy for the recorded image. Th roborazzi.record.namingStrategy=testClassAndMethod ``` +## roborazzi.cleanupOldScreenshots + +This option allows you to clean up old screenshots. By default, this option is set to false. +The reason why Roborazzi does not delete old screenshots by default is that Roborazzi doesn't know if you are running filtered tests or not. If you are running filtered tests, Roborazzi will delete the screenshots that are not related to the current test run. + +``` +roborazzi.cleanupOldScreenshots=true +``` + ## Robolectric Options ### robolectric.pixelCopyRenderMode