From 7728629a64a5eec88d3b8c09f920c7ba3ebb59ad Mon Sep 17 00:00:00 2001 From: Nikita Evdokimov Date: Mon, 18 Nov 2024 10:59:28 +0300 Subject: [PATCH] TECH: Fix destination path; add documentation --- kaspresso/build.gradle.kts | 3 ++- .../device/screenshots/ScreenshotsImpl.kt | 10 +++++++--- .../files/resources/ResourcesDirsProvider.kt | 2 +- .../impl/DefaultResourcesDirsProvider.kt | 9 +++++++-- .../visual/DefaultVisualTestWatcher.kt | 7 ++++++- .../kaspresso/kaspresso/Kaspresso.kt | 1 + .../kaspresso/visual/VisualTestParams.kt | 19 +++++++++++++++++++ .../customdirectory/FlatDirectoryProvider.kt | 9 +++++++-- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/kaspresso/build.gradle.kts b/kaspresso/build.gradle.kts index 679ec613a..a2215e00a 100644 --- a/kaspresso/build.gradle.kts +++ b/kaspresso/build.gradle.kts @@ -9,7 +9,8 @@ android { namespace = "com.kaspersky.kaspresso" defaultConfig { - buildConfigField("String", "VISUAL_TEST_TYPE", System.getenv("VISUAL_TEST_TYPE") ?: property("kaspresso.visualTestType").toString()) // [Record, Compare] + buildConfigField("String", "VISUAL_TEST_TYPE", System.getenv("VISUAL_TEST_TYPE") + ?: property("kaspresso.visualTestType")?.toString() ?: "Record") // [Record, Compare] } } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/screenshots/ScreenshotsImpl.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/screenshots/ScreenshotsImpl.kt index d647b945b..8510a92ff 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/screenshots/ScreenshotsImpl.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/screenshots/ScreenshotsImpl.kt @@ -6,6 +6,8 @@ import com.kaspersky.kaspresso.files.dirs.DirsProvider import com.kaspersky.kaspresso.files.extensions.FileExtension import com.kaspersky.kaspresso.files.resources.ResourceFileNamesProvider import com.kaspersky.kaspresso.files.resources.ResourceFilesProvider +import com.kaspersky.kaspresso.files.resources.ResourcesDirNameProvider +import com.kaspersky.kaspresso.files.resources.ResourcesDirsProvider import com.kaspersky.kaspresso.logger.UiTestLogger import com.kaspersky.kaspresso.visual.ScreenshotsComparator import com.kaspersky.kaspresso.visual.VisualTestParams @@ -23,6 +25,7 @@ class ScreenshotsImpl( private val visualTestParams: VisualTestParams, private val dirsProvider: DirsProvider, private val resourceFileNamesProvider: ResourceFileNamesProvider, + private val resourcesDirsProvider: ResourcesDirsProvider, ) : Screenshots { private val originalScreenshotsDir: File @@ -59,7 +62,7 @@ class ScreenshotsImpl( null } else { originalScreenshotsDir.mkdirs() - File(originalScreenshotsDir, resourceFileNamesProvider.getFileName(tag, FileExtension.PNG.toString())) + resourcesDirsProvider.provide(originalScreenshotsDir).resolve(resourceFileNamesProvider.getFileName(tag, FileExtension.PNG.toString())) } doTakeAndApply(tag = tag, isFull = isFullWindow, targetPath) { screenshot = this } @@ -72,10 +75,11 @@ class ScreenshotsImpl( private fun File.compare() { logger.i("Comparing screenshot ${this.absolutePath}") - val originalScreenshot = File(originalScreenshotsDir, name) + val originalScreenshot = resourcesDirsProvider.provide(originalScreenshotsDir, provideCleared = false) + .resolve(resourceFileNamesProvider.getFileName(nameWithoutExtension, FileExtension.PNG.toString())) assert(originalScreenshot.exists()) { "Tried to assert screenshot $absolutePath, but failed to find matching " + - "original screenshot by the path: ${originalScreenshotsDir.absolutePath}/$name" + "original screenshot by the path: ${originalScreenshot.absolutePath}/$name" } val doesMatch = screenshotsComparator.compare(originalScreenshot, this) logger.i("Does screenshot $name matches the original one: $doesMatch") diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/ResourcesDirsProvider.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/ResourcesDirsProvider.kt index 14bf08f34..68318907c 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/ResourcesDirsProvider.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/ResourcesDirsProvider.kt @@ -6,5 +6,5 @@ import java.io.File * Provides directories for resources */ interface ResourcesDirsProvider { - fun provide(dest: File, subDir: String? = null): File + fun provide(dest: File, subDir: String? = null, provideCleared: Boolean = true): File } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/impl/DefaultResourcesDirsProvider.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/impl/DefaultResourcesDirsProvider.kt index 72006706f..0f2cd1737 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/impl/DefaultResourcesDirsProvider.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/files/resources/impl/DefaultResourcesDirsProvider.kt @@ -5,6 +5,7 @@ import com.kaspersky.kaspresso.files.extensions.findTestMethod import com.kaspersky.kaspresso.files.models.TestMethod import com.kaspersky.kaspresso.files.resources.ResourcesDirNameProvider import com.kaspersky.kaspresso.files.resources.ResourcesDirsProvider +import com.kaspersky.kaspresso.internal.extensions.other.createDirIfNeeded import java.io.File class DefaultResourcesDirsProvider( @@ -13,10 +14,14 @@ class DefaultResourcesDirsProvider( private val testThread: Thread = Thread.currentThread() ) : ResourcesDirsProvider { - override fun provide(dest: File, subDir: String?): File { + override fun provide(dest: File, subDir: String?, provideCleared: Boolean): File { val rootDir: File = dirsProvider.provideNew(dest) val resourcesDest: File = resolveResourcesDirDest(rootDir, subDir) - return dirsProvider.provideCleared(resourcesDest) + return if (provideCleared) { + dirsProvider.provideCleared(resourcesDest) + } else { + resourcesDest.createDirIfNeeded() + } } private fun resolveResourcesDirDest(rootDir: File, subDir: String? = null): File { diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/visual/DefaultVisualTestWatcher.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/visual/DefaultVisualTestWatcher.kt index f71c1752a..3cbd6dfdb 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/visual/DefaultVisualTestWatcher.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/visual/DefaultVisualTestWatcher.kt @@ -3,6 +3,7 @@ package com.kaspersky.kaspresso.internal.visual import com.kaspersky.kaspresso.device.files.Files import com.kaspersky.kaspresso.files.dirs.DirsProvider import com.kaspersky.kaspresso.files.resources.ResourcesRootDirsProvider +import com.kaspersky.kaspresso.internal.exceptions.AdbServerException import com.kaspersky.kaspresso.logger.Logger import com.kaspersky.kaspresso.visual.VisualTestParams import com.kaspersky.kaspresso.visual.VisualTestType @@ -32,7 +33,11 @@ internal class DefaultVisualTestWatcher( dirsProvider.provideCleared(diffDir) dirsProvider.provideCleared(originalScreenshotsTargetDir) - files.push(params.hostScreenshotsDir, dirsProvider.provideNew(File("")).absolutePath) + try { + files.push(params.hostScreenshotsDir, dirsProvider.provideNew(File("")).absolutePath) + } catch (ex: AdbServerException) { + throw RuntimeException("Failed to push screenshots. Please, check that they exist by the path: ${params.hostScreenshotsDir} (relatively to the ADB server executable", ex) + } logger.i("Done pushing the screenshots unto the device") } } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt index f19d8e85e..a37612bc1 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt @@ -797,6 +797,7 @@ data class Kaspresso( screenshotsComparator = screenshotsComparator, dirsProvider = dirsProvider, resourceFileNamesProvider = resourceFileNamesProvider, + resourcesDirsProvider = resourcesDirsProvider, ) } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/visual/VisualTestParams.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/visual/VisualTestParams.kt index 9aa67dfe9..087c1325d 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/visual/VisualTestParams.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/visual/VisualTestParams.kt @@ -2,10 +2,29 @@ package com.kaspersky.kaspresso.visual import android.annotation.SuppressLint +/** + * @see com.kaspersky.kaspresso.internal.visual.DefaultScreenshotsComparator + */ @SuppressLint("SdCardPath") data class VisualTestParams( + /** + * Controls whether to take the new reference screenshots and save them or use the old ones and compare them to the ones being taken during the test + */ val testType: VisualTestType = VisualTestType.Record, + /** + * The path with the reference screenshots. Used to save the new reference screenshots if testType is set to the VisualTestType.Record + * or to push screenshot files if testType is set to VisualTestType.Compare + */ val hostScreenshotsDir: String = "original_screenshots", + /** + * The color threshold to mark the single pixel different from the other one. + * @see com.kaspersky.kaspresso.internal.visual.DefaultScreenshotsComparator.checkColors + */ val colorTolerance: Int = 1, + /** + * Controls the threshold of the screenshots difference. The value is in percents. Screenshots with difference less than this value + * are "acceptable" and don't fail the test + * @see com.kaspersky.kaspresso.internal.visual.DefaultScreenshotsComparator.compare + */ val tolerance: Float = 0.3f, ) diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/customdirectory/FlatDirectoryProvider.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/customdirectory/FlatDirectoryProvider.kt index 6d05e9578..85c31cd79 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/customdirectory/FlatDirectoryProvider.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/docloc_tests/customdirectory/FlatDirectoryProvider.kt @@ -4,6 +4,7 @@ import com.kaspersky.kaspresso.files.dirs.DirsProvider import com.kaspersky.kaspresso.files.resources.impl.DefaultResourcesDirsProvider import com.kaspersky.kaspresso.files.resources.ResourcesDirsProvider import com.kaspersky.kaspresso.files.resources.impl.DefaultResourcesDirNameProvider +import com.kaspersky.kaspresso.internal.extensions.other.createDirIfNeeded import java.io.File internal class FlatDirectoryProvider( @@ -12,12 +13,16 @@ internal class FlatDirectoryProvider( dirsProvider = dirsProvider, resourcesDirNameProvider = DefaultResourcesDirNameProvider() ) { - override fun provide(dest: File, subDir: String?): File { + override fun provide(dest: File, subDir: String?, provideCleared: Boolean): File { val rootDir: File = dirsProvider.provideNew(dest) val resultsDir: File = when (subDir) { null -> rootDir.resolve("") else -> rootDir.resolve(subDir).resolve("") } - return dirsProvider.provideCleared(resultsDir) + return if (provideCleared) { + dirsProvider.provideCleared(resultsDir) + } else { + resultsDir.createDirIfNeeded() + } } }