From 6288ac3a23b141c02911ec1ec6273ea18d365dcd Mon Sep 17 00:00:00 2001 From: mariuszmarzec <41124722+mariuszmarzec@users.noreply.github.com> Date: Mon, 24 Jan 2022 18:56:37 +0100 Subject: [PATCH] [ISSUE-78] Test orchestrator support (#273) * [ISSUE-78] Updated facebook screenshot plugin, migrated from xml metadata parser to json, initial solution to gather and pull images * Assembling images but not worked for flavors * Clear orchestrated folder from screenshots too * Changed screenshot paths * Uncommented code * Working screenshot testing for compose * Check if orchestrator connected by test options * Fixed tests * Fixed code style * Fixed code style * Fixed broken compose screenshotting without orchestrator * Fixed names and reverted version of shot in config and consumer * Fixed code style * Reverted empty line * Fixed code style * Fixed tests * Fixed issues, doesn't work with composer * Fixed compose screenshot testing * Fixed tests * Rename all metadata json files * Fixed code style * Fixed code style, tests * Add information about orchestrator in composer section * Added additional steps for running CI checks with enabled orchestrator * Fixed syntax * Removed logging --- .github/workflows/build.yml | 17 + README.md | 10 + .../src/main/scala/com/karumi/shot/Shot.scala | 80 ++-- .../scala/com/karumi/shot/android/Adb.scala | 43 +- .../com/karumi/shot/domain/ShotFolder.scala | 23 +- ...scala => ScreenshotsSuiteJsonParser.scala} | 55 ++- .../empty-screenshots-metadata.json | 1 + .../empty-screenshots-metadata.xml | 4 - .../screenshots-metadata/metadata.json | 414 ++++++++++++++++++ .../screenshots-metadata/metadata.xml | 410 ----------------- .../test/scala/com/karumi/shot/ShotSpec.scala | 142 ++++-- .../karumi/shot/domain/ShotFolderSpec.scala | 51 ++- .../json/ScreenshotsSuiteJsonParserSpec.scala | 111 +++++ .../shot/mothers/ProjectFolderMother.scala | 4 +- .../xml/ScreenshotsSuiteXmlParserSpec.scala | 84 ---- shot-android/build.gradle | 2 +- .../shot/compose/ScreenshotSaverTest.kt | 4 +- .../shot/OrchestratorScreenshotSaver.kt | 72 +++ .../java/com/karumi/shot/ShotTestRunner.kt | 2 + .../karumi/shot/compose/ScreenshotSaver.kt | 2 +- shot-consumer-compose/app/build.gradle | 7 + shot-consumer-flavors/app/build.gradle | 6 + .../app/build.gradle.kts | 7 + .../library/build.gradle.kts | 7 + shot-consumer/app/build.gradle | 7 + shot-consumer/app2/build.gradle | 6 + shot-consumer/samplelibrary/build.gradle | 7 + .../scala/com/karumi/shot/ShotPlugin.scala | 20 +- .../scala/com/karumi/shot/tasks/Tasks.scala | 13 +- 29 files changed, 1001 insertions(+), 610 deletions(-) rename core/src/main/scala/com/karumi/shot/xml/{ScreenshotsSuiteXmlParser.scala => ScreenshotsSuiteJsonParser.scala} (52%) create mode 100644 core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.json delete mode 100644 core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.xml create mode 100644 core/src/test/resources/screenshots-metadata/metadata.json delete mode 100644 core/src/test/resources/screenshots-metadata/metadata.xml create mode 100644 core/src/test/scala/com/karumi/shot/json/ScreenshotsSuiteJsonParserSpec.scala delete mode 100644 core/src/test/scala/com/karumi/shot/xml/ScreenshotsSuiteXmlParserSpec.scala create mode 100644 shot-android/src/main/java/com/karumi/shot/OrchestratorScreenshotSaver.kt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1335506f..cf663249 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,6 +45,23 @@ jobs: - name: Execute screenshot tests for shot-consumer-flavors blue flavor run: ./gradlew blueCustomBuildTypeExecuteScreenshotTests working-directory: shot-consumer-flavors + - name: Set orchestrator enabled + run: echo "orchestrated=true" >> $GITHUB_ENV + - name: Execute screenshot tests with orchestrator for shot-consumer-library-no-tests + run: ./gradlew executeScreenshotTests + working-directory: shot-consumer-library-no-tests + - name: Execute screenshot tests with orchestrator for shot-consumer-compose + run: ./gradlew executeScreenshotTests + working-directory: shot-consumer-compose + - name: Execute screenshot tests with orchestrator for shot-consumer + run: ./gradlew executeScreenshotTests + working-directory: shot-consumer + - name: Execute screenshot tests with orchestrator for shot-consumer-flavors green flavor + run: ./gradlew greenCustomBuildTypeExecuteScreenshotTests + working-directory: shot-consumer-flavors + - name: Execute screenshot tests with orchestrator for shot-consumer-flavors blue flavor + run: ./gradlew blueCustomBuildTypeExecuteScreenshotTests + working-directory: shot-consumer-flavors - uses: actions/upload-artifact@v2 if: always() with: diff --git a/README.md b/README.md index 9028c6f4..d541cbd1 100644 --- a/README.md +++ b/README.md @@ -314,6 +314,16 @@ shot { } ``` +If you are using orchestrator remember to enable it in composer configuration: + +```groovy +composer { + // ... + withOrchestrator true + // ... +} +``` + ## Tolerance Shot provides a simple mechanism to be able to configure a threshold value when comparing recorded images with the new ones during the verification stage. You may need to use tolerance in your tests when testing compose components because the API Shot uses to record screenshots depending on the device where your tests are executed. There are other scenarios where you may need to configure a tolerance value, but these are not so common. If you want to configure it you can use this config in your ``build.gradle`` file. diff --git a/core/src/main/scala/com/karumi/shot/Shot.scala b/core/src/main/scala/com/karumi/shot/Shot.scala index e59ec814..82667f41 100644 --- a/core/src/main/scala/com/karumi/shot/Shot.scala +++ b/core/src/main/scala/com/karumi/shot/Shot.scala @@ -12,12 +12,17 @@ import com.karumi.shot.screenshots.{ } import com.karumi.shot.system.EnvVars import com.karumi.shot.ui.Console -import com.karumi.shot.xml.ScreenshotsSuiteXmlParser._ +import com.karumi.shot.xml.ScreenshotsSuiteJsonParser._ import org.apache.commons.io.FileUtils import org.tinyzip.TinyZip import java.io.File import java.nio.file.Paths +import scala.collection.convert.ImplicitConversions.{ + `collection AsScalaIterable`, + `collection asJava` +} +import scala.collection.immutable.Stream.Empty class Shot( adb: Adb, @@ -34,14 +39,14 @@ class Shot( Adb.adbBinaryPath = adbPath } - def downloadScreenshots(appId: AppId, shotFolder: ShotFolder): Unit = { + def downloadScreenshots(appId: AppId, shotFolder: ShotFolder, orchestrated: Boolean): Unit = { console.show("⬇️ Pulling screenshots from your connected devices!") - pullScreenshots(appId, shotFolder) + pullScreenshots(appId, shotFolder, orchestrated) } - def recordScreenshots(appId: AppId, shotFolder: ShotFolder): Unit = { + def recordScreenshots(appId: AppId, shotFolder: ShotFolder, orchestrated: Boolean): Unit = { console.show("💾 Saving screenshots.") - moveComposeScreenshotsToRegularScreenshotsFolder(shotFolder) + moveComposeScreenshotsToRegularScreenshotsFolder(shotFolder, orchestrated) val composeScreenshotSuite = recordComposeScreenshots(shotFolder) val regularScreenshotSuite = recordRegularScreenshots(shotFolder) if (regularScreenshotSuite.isEmpty && composeScreenshotSuite.isEmpty) { @@ -65,10 +70,11 @@ class Shot( projectName: String, shouldPrintBase64Error: Boolean, tolerance: Double, - showOnlyFailingTestsInReports: Boolean + showOnlyFailingTestsInReports: Boolean, + orchestrated: Boolean ): ScreenshotsComparisionResult = { console.show("🔎 Comparing screenshots with previous ones.") - moveComposeScreenshotsToRegularScreenshotsFolder(shotFolder) + moveComposeScreenshotsToRegularScreenshotsFolder(shotFolder, orchestrated) val regularScreenshots = readScreenshotsMetadata(shotFolder) val composeScreenshots = readComposeScreenshotsMetadata(shotFolder) if (regularScreenshots.isEmpty && composeScreenshots.isEmpty) { @@ -132,20 +138,25 @@ class Shot( } } - def removeScreenshots(appId: AppId): Unit = - clearScreenshots(appId) + def removeScreenshots(appId: AppId, orchestrated: Boolean): Unit = + clearScreenshots(appId, orchestrated) private def moveComposeScreenshotsToRegularScreenshotsFolder( - shotFolder: ShotFolder + shotFolder: ShotFolder, + orchestrated: Boolean ): Unit = { - val composeFolder = shotFolder.pulledComposeScreenshotsFolder() - files.listFilesInFolder(composeFolder).forEach { file: File => + val composeFolder = shotFolder.pulledComposeScreenshotsFolder() + var fileList: Iterable[File] = Empty + if (orchestrated) { + val orchestratedComposeFolder = shotFolder.pulledComposeOrchestratedScreenshotsFolder() + fileList = + files.listFilesInFolder(composeFolder) ++ files.listFilesInFolder(orchestratedComposeFolder) + } else { + fileList = files.listFilesInFolder(composeFolder) + } + fileList.forEach { file: File => val rawFilePath = file.getAbsolutePath - val newFilePath = - rawFilePath.replace( - shotFolder.pulledComposeScreenshotsFolder(), - shotFolder.pulledScreenshotsFolder() - ) + val newFilePath = shotFolder.pulledScreenshotsFolder() + file.getName files.rename(rawFilePath, newFilePath) } } @@ -175,8 +186,9 @@ class Shot( } } - private def clearScreenshots(appId: AppId): Unit = forEachDevice { device => - adb.clearScreenshots(device, appId) + private def clearScreenshots(appId: AppId, orchestrated: Boolean): Unit = forEachDevice { + device => + adb.clearScreenshots(device, appId, orchestrated) } private def forEachDevice[T](f: String => T): Unit = devices().foreach(f) @@ -197,17 +209,32 @@ class Shot( private def pullScreenshots( appId: AppId, - shotFolder: ShotFolder + shotFolder: ShotFolder, + orchestrated: Boolean ): Unit = forEachDevice { device => val screenshotsFolder = shotFolder.screenshotsFolder() createScreenshotsFolderIfDoesNotExist(screenshotsFolder) removeProjectTemporalScreenshotsFolder(shotFolder) - adb.pullScreenshots(device, screenshotsFolder, appId) + adb.pullScreenshots(device, screenshotsFolder, appId, orchestrated) extractPicturesFromBundle(shotFolder.pulledScreenshotsFolder()) - files.rename(shotFolder.metadataFile(), s"${shotFolder.metadataFile()}_$device") - files.rename(shotFolder.composeMetadataFile(), s"${shotFolder.composeMetadataFile()}_$device") + + files + .listFilesInFolder(shotFolder.pulledScreenshotsFolder()) + .filter(file => file.getAbsolutePath.contains(shotFolder.metadataFileName())) + .foreach(file => { + val filePath = shotFolder.pulledScreenshotsFolder() + file.getName + files.rename(filePath, s"${filePath}_$device") + }) + + files + .listFilesInFolder(shotFolder.pulledComposeOrchestratedScreenshotsFolder()) + .filter(file => file.getAbsolutePath.contains(shotFolder.composeMetadataFileName())) + .foreach(file => { + val filePath = shotFolder.pulledComposeOrchestratedScreenshotsFolder() + file.getName + files.rename(filePath, s"${filePath}_$device") + }) } private def readScreenshotsMetadata( @@ -218,7 +245,7 @@ class Shot( if (folder.exists()) { val filesInScreenshotFolder = folder.listFiles val metadataFiles = - filesInScreenshotFolder.filter(file => file.getAbsolutePath.contains("metadata.xml")) + filesInScreenshotFolder.filter(file => file.getAbsolutePath.contains("metadata.json")) val screenshotSuite = metadataFiles.flatMap { metadataFilePath => val metadataFileContent = files.read(metadataFilePath.getAbsolutePath) parseScreenshots( @@ -247,7 +274,9 @@ class Shot( if (folder.exists()) { val filesInScreenshotFolder = folder.listFiles val metadataFiles = - filesInScreenshotFolder.filter(file => file.getAbsolutePath.contains("metadata.json")) + filesInScreenshotFolder.filter(file => + file.getAbsolutePath.contains(shotFolder.composeMetadataFileName()) + ) val screenshotSuite = metadataFiles.flatMap { metadataFilePath => val metadataFileContent = files.read(metadataFilePath.getAbsolutePath) ScreenshotsComposeSuiteJsonParser.parseScreenshots( @@ -271,6 +300,7 @@ class Shot( private def removeProjectTemporalScreenshotsFolder(shotFolder: ShotFolder): Unit = { FileUtils.deleteDirectory(new File(shotFolder.pulledScreenshotsFolder())) FileUtils.deleteDirectory(new File(shotFolder.pulledComposeScreenshotsFolder())) + FileUtils.deleteDirectory(new File(shotFolder.pulledComposeOrchestratedScreenshotsFolder())) } private def extractPicturesFromBundle(screenshotsFolder: String): Unit = { diff --git a/core/src/main/scala/com/karumi/shot/android/Adb.scala b/core/src/main/scala/com/karumi/shot/android/Adb.scala index dfe5b823..5a234366 100644 --- a/core/src/main/scala/com/karumi/shot/android/Adb.scala +++ b/core/src/main/scala/com/karumi/shot/android/Adb.scala @@ -1,6 +1,6 @@ package com.karumi.shot.android -import com.karumi.shot.android.Adb.baseStoragePath +import com.karumi.shot.android.Adb.{baseStoragePath} import com.karumi.shot.domain.model.{AppId, Folder} import scala.sys.process._ @@ -32,14 +32,44 @@ class Adb { .filter(device => !isCarriageReturnASCII(device)) } - def pullScreenshots(device: String, screenshotsFolder: Folder, appId: AppId): Unit = { - pullFolder("screenshots-default", device, screenshotsFolder, appId) + def pullScreenshots( + device: String, + screenshotsFolder: Folder, + appId: AppId, + orchestrated: Boolean + ): Unit = { + pullFolder( + s"screenshots-default${orchestratedSuffix(orchestrated)}", + device, + screenshotsFolder, + appId + ) pullFolder("screenshots-compose-default", device, screenshotsFolder, appId) + if (orchestrated) { + pullFolder( + s"screenshots-compose-default${orchestratedSuffix(orchestrated)}", + device, + screenshotsFolder, + appId + ) + } } - def clearScreenshots(device: String, appId: AppId): Unit = { + def clearScreenshots(device: String, appId: AppId, orchestrated: Boolean): Unit = { clearScreenshotsFromFolder(device, appId, "screenshots-default") clearScreenshotsFromFolder(device, appId, "screenshots-compose-default") + if (orchestrated) { + clearScreenshotsFromFolder( + device, + appId, + s"screenshots-default${orchestratedSuffix(orchestrated)}" + ) + clearScreenshotsFromFolder( + device, + appId, + s"screenshots-compose-default${orchestratedSuffix(orchestrated)}" + ) + } } private def pullFolder( @@ -59,8 +89,9 @@ class Adb { } } - private def clearScreenshotsFromFolder(device: String, appId: AppId, folder: AppId) = + private def clearScreenshotsFromFolder(device: String, appId: AppId, folder: AppId): Unit = { executeAdbCommand(s"-s $device shell rm -r $baseStoragePath/screenshots/$appId/$folder/") + } private def executeAdbCommand(command: String): Int = s"${Adb.adbBinaryPath} $command" ! logger @@ -70,4 +101,6 @@ class Adb { private def isCarriageReturnASCII(device: String): Boolean = device.charAt(0) == CR_ASCII_DECIMAL + + private def orchestratedSuffix(orchestrated: Boolean) = if (orchestrated) "-orchestrated" else "" } diff --git a/core/src/main/scala/com/karumi/shot/domain/ShotFolder.scala b/core/src/main/scala/com/karumi/shot/domain/ShotFolder.scala index 49bd0278..38bf4c1d 100644 --- a/core/src/main/scala/com/karumi/shot/domain/ShotFolder.scala +++ b/core/src/main/scala/com/karumi/shot/domain/ShotFolder.scala @@ -8,9 +8,12 @@ case class ShotFolder( private val buildType: String, private val flavor: Option[String], private val directorySuffix: Option[String], - private val separator: String + private val separator: String, + private val orchestrated: Boolean ) { + private val orchestratedSuffix = if (orchestrated) "-orchestrated" else "" + private def pathSuffix(): String = { s"${flavor.fold("") { s => s"$s$separator" }}" + s"$buildType$separator" + @@ -22,19 +25,31 @@ case class ShotFolder( } def pulledScreenshotsFolder(): FilePath = { - s"${screenshotsFolder()}screenshots-default$separator" + s"${screenshotsFolder()}screenshots-default$orchestratedSuffix$separator" } def pulledComposeScreenshotsFolder(): FilePath = { s"${screenshotsFolder()}screenshots-compose-default$separator" } + def pulledComposeOrchestratedScreenshotsFolder(): FilePath = { + s"${screenshotsFolder()}screenshots-compose-default$orchestratedSuffix$separator" + } + def metadataFile(): FilePath = { - pulledScreenshotsFolder() + s"metadata.xml" + pulledScreenshotsFolder() + s"metadata.json" + } + + def metadataFileName(): FilePath = { + "metadata.json" } def composeMetadataFile(): FilePath = { - pulledComposeScreenshotsFolder() + s"metadata.json" + pulledComposeScreenshotsFolder() + composeMetadataFileName() + } + + def composeMetadataFileName(): FilePath = { + "metadata_compose.json" } def reportFolder(): FilePath = { diff --git a/core/src/main/scala/com/karumi/shot/xml/ScreenshotsSuiteXmlParser.scala b/core/src/main/scala/com/karumi/shot/xml/ScreenshotsSuiteJsonParser.scala similarity index 52% rename from core/src/main/scala/com/karumi/shot/xml/ScreenshotsSuiteXmlParser.scala rename to core/src/main/scala/com/karumi/shot/xml/ScreenshotsSuiteJsonParser.scala index e569fb76..243c0514 100644 --- a/core/src/main/scala/com/karumi/shot/xml/ScreenshotsSuiteXmlParser.scala +++ b/core/src/main/scala/com/karumi/shot/xml/ScreenshotsSuiteJsonParser.scala @@ -1,48 +1,61 @@ package com.karumi.shot.xml -import com.karumi.shot.domain.model.{Folder, ScreenshotsSuite} +import com.karumi.shot.domain.model.{FilePath, Folder, ScreenshotsSuite} import com.karumi.shot.domain.{Dimension, Screenshot} import org.json4s._ import org.json4s.native.JsonMethods._ -import scala.xml._ +import scala.collection.mutable +import scala.collection.mutable.ListBuffer -object ScreenshotsSuiteXmlParser { +object ScreenshotsSuiteJsonParser { def parseScreenshots( - xml: String, + metadataJson: String, screenshotsFolder: Folder, temporalScreenshotsFolder: Folder, screenshotsTemporalBuildPath: Folder ): ScreenshotsSuite = { - val xmlScreenshots = XML.loadString(xml) \ "screenshot" - xmlScreenshots.map( + val json = parse(metadataJson) + val JArray(jsonScreenshots) = json + jsonScreenshots.map( parseScreenshot(_, screenshotsFolder, temporalScreenshotsFolder, screenshotsTemporalBuildPath) ) } private def parseScreenshot( - xmlNode: Node, + jsonNode: JValue, screenshotsFolder: Folder, temporalScreenshotsFolder: Folder, screenshotsTemporalBuildPath: Folder ): Screenshot = { - val name = (xmlNode \ "name" head).text.trim + val JString(name) = jsonNode \ "name" val recordedScreenshotPath = screenshotsFolder + name + ".png" val temporalScreenshotPath = screenshotsTemporalBuildPath + "/" + name + ".png" - val testClass = (xmlNode \ "test_class" head).text.trim - val testName = (xmlNode \ "test_name" head).text.trim - val tileWidth = (xmlNode \ "tile_width" head).text.toInt - val tileHeight = (xmlNode \ "tile_height" head).text.toInt - val tilesDimension = Dimension(tileWidth, tileHeight) - val viewHierarchy = (xmlNode \ "view_hierarchy" head).text.trim - val absoluteFileNames = - (xmlNode \ "absolute_file_name").map(_.text.trim + ".png") - val relativeFileNames = - (xmlNode \ "relative_file_name").map(_.text.trim + ".png") - val recordedPartsPaths = - relativeFileNames.map(temporalScreenshotsFolder + _) + val JString(testClass) = (jsonNode \ "testClass") + val JString(testName) = (jsonNode \ "testName") + val JInt(tileWidth) = (jsonNode \ "tileWidth") + val JInt(tileHeight) = (jsonNode \ "tileHeight") + val tilesDimension = Dimension(tileWidth.toInt, tileHeight.toInt) + val JString(viewHierarchy) = (jsonNode \ "viewHierarchy") + val JArray(absoluteFileNamesFromJson) = (jsonNode \ "absoluteFilesNames") + val absoluteFileNames = ListBuffer[String]() + absoluteFileNamesFromJson.foreach(value => { + val JString(fileName) = value + absoluteFileNames += (fileName + ".png") + }) + val JArray(relativeFileNamesFromJson) = + (jsonNode \ "relativeFileNames") + + val relativeFileNames = ListBuffer[String]() + relativeFileNamesFromJson.foreach(value => { + val JString(fileName) = value + relativeFileNames += (fileName + ".png") + }) + + implicit val formats = DefaultFormats + Screenshot( name, recordedScreenshotPath, @@ -53,7 +66,7 @@ object ScreenshotsSuiteXmlParser { viewHierarchy, absoluteFileNames, relativeFileNames, - recordedPartsPaths, + relativeFileNames.map(temporalScreenshotsFolder + _), Dimension(0, 0) ) } diff --git a/core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.json b/core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.json new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.xml b/core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.xml deleted file mode 100644 index e86add67..00000000 --- a/core/src/test/resources/screenshots-metadata/empty-screenshots-metadata.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/core/src/test/resources/screenshots-metadata/metadata.json b/core/src/test/resources/screenshots-metadata/metadata.json new file mode 100644 index 00000000..7b2940aa --- /dev/null +++ b/core/src/test/resources/screenshots-metadata/metadata.json @@ -0,0 +1,414 @@ +[ + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_4" + ], + "axIssues": "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes", + "relativeFileNames": [ + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_3", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_4", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_3", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_4", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_0", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_1", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_2", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_3", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_4" + ], + "testClass": "com.karumi.ui.view.MainActivityTest", + "testName": "showsSuperHeroesIfThereAreSomeSuperHeroes", + "tileHeight": 5, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_4" + ], + "axIssues": "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam", + "relativeFileNames": [ + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_1", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_2", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_3", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_4", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_0", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_1", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_2", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_3", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_4", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_0", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_1", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_2", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_3", + "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_2_4" + ], + "testClass": "com.karumi.ui.view.MainActivityTest", + "testName": "doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam", + "tileHeight": 5, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_4" + ], + "axIssues": "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam", + "relativeFileNames": [ + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_1", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_2", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_3", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_4", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_0", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_1", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_2", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_3", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_4", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_0", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_1", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_2", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_3", + "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_2_4" + ], + "testClass": "com.karumi.ui.view.MainActivityTest", + "testName": "showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam", + "tileHeight": 5, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_4" + ], + "axIssues": "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes", + "relativeFileNames": [ + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_1", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_2", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_3", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_4", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_0", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_1", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_2", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_3", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_4", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_0", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_1", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_2", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_3", + "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_2_4" + ], + "testClass": "com.karumi.ui.view.MainActivityTest", + "testName": "showsEmptyCaseIfThereAreNoSuperHeroes", + "tileHeight": 5, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_4" + ], + "axIssues": "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero", + "relativeFileNames": [ + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_1", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_2", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_3", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_4", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_0", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_1", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_2", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_3", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_4", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_0", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_1", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_2", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_3", + "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_2_4" + ], + "testClass": "com.karumi.ui.view.MainActivityTest", + "testName": "showsJustOneSuperHero", + "tileHeight": 5, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_4" + ], + "axIssues": "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam", + "relativeFileNames": [ + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_1", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_2", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_3", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_4", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_0", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_1", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_2", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_3", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_4", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_0", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_1", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_2", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_3", + "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_2_4" + ], + "testClass": "com.karumi.ui.view.SuperHeroDetailActivityTest", + "testName": "showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam", + "tileHeight": 5, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_4", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_2", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_3", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_4" + ], + "axIssues": "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam", + "relativeFileNames": [ + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_1", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_2", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_3", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_4", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_0", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_1", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_2", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_3", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_4", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_0", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_1", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_2", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_3", + "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_2_4" + ], + "testClass": "com.karumi.ui.view.SuperHeroDetailActivityTest", + "testName": "doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam", + "tileHeight": 5, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_2_1" + ], + "axIssues": "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames", + "relativeFileNames": [ + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_0_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_1_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_1_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_2_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_2_1" + ], + "testClass": "com.karumi.ui.view.SuperHeroViewHolderTest", + "testName": "showsSuperHeroesWithLongNames", + "tileHeight": 2, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_2_1" + ], + "axIssues": "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero", + "relativeFileNames": [ + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_0_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_1_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_1_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_2_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_2_1" + ], + "testClass": "com.karumi.ui.view.SuperHeroViewHolderTest", + "testName": "showsAnySuperHero", + "tileHeight": 2, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_2_1" + ], + "axIssues": "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge", + "relativeFileNames": [ + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_0_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_1_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_1_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_2_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_2_1" + ], + "testClass": "com.karumi.ui.view.SuperHeroViewHolderTest", + "testName": "showsAvengersBadge", + "tileHeight": 2, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_dump.json" + }, + { + "absoluteFilesNames": [ + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_0_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_1_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_1_1", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_2_0", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_2_1" + ], + "axIssues": "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_issues.json", + "extras": {}, + "name": "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions", + "relativeFileNames": [ + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_0_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_1_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_1_1", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_2_0", + "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_2_1" + ], + "testClass": "com.karumi.ui.view.SuperHeroViewHolderTest", + "testName": "showsSuperHeroesWithLongDescriptions", + "tileHeight": 2, + "tileWidth": 3, + "viewHierarchy": "com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_dump.json" + } +] \ No newline at end of file diff --git a/core/src/test/resources/screenshots-metadata/metadata.xml b/core/src/test/resources/screenshots-metadata/metadata.xml deleted file mode 100644 index 0d30fea9..00000000 --- a/core/src/test/resources/screenshots-metadata/metadata.xml +++ /dev/null @@ -1,410 +0,0 @@ - - - - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes - com.karumi.ui.view.MainActivityTest - showsSuperHeroesIfThereAreSomeSuperHeroes - 2 - 3 - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_dump.json - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_issues.json - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1 - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2 - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0 - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1 - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2 - - com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2 - - - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam - com.karumi.ui.view.MainActivityTest - doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam - 2 - 3 - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_dump.json - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_issues.json - - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_1 - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_2 - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_0_2 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_0 - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_0 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_1 - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_2 - - - com.karumi.ui.view.MainActivityTest_doesNotShowAvengersBadgeIfASuperHeroIsNotPartOfTheAvengersTeam_1_2 - - - - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam - com.karumi.ui.view.MainActivityTest - showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam - 2 - 3 - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_dump.json - - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_issues.json - - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_1 - - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_2 - - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_0_2 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_0 - - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_0 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_1 - - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_2 - - - com.karumi.ui.view.MainActivityTest_showsAvengersBadgeIfASuperHeroIsPartOfTheAvengersTeam_1_2 - - - - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes - com.karumi.ui.view.MainActivityTest - showsEmptyCaseIfThereAreNoSuperHeroes - 2 - 3 - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_dump.json - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_issues.json - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_1 - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_2 - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_0_2 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_0 - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_0 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_1 - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_2 - - com.karumi.ui.view.MainActivityTest_showsEmptyCaseIfThereAreNoSuperHeroes_1_2 - - - - - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero - com.karumi.ui.view.MainActivityTest - showsJustOneSuperHero - 2 - 3 - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_dump.json - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_issues.json - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero - - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_1 - - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_1 - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_2 - - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_0_2 - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_0 - - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_0 - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_1 - - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_1 - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_2 - - com.karumi.ui.view.MainActivityTest_showsJustOneSuperHero_1_2 - - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam - com.karumi.ui.view.SuperHeroDetailActivityTest - showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam - 2 - 3 - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_dump.json - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_issues.json - - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_1 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_2 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_0_2 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_0 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_0 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_1 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_2 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_showsAvengersBadgeIfSuperHeroIsPartOfTheAvengersTeam_1_2 - - - - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam - - com.karumi.ui.view.SuperHeroDetailActivityTest - doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam - 2 - 3 - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_dump.json - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_issues.json - - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_1 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_2 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_0_2 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_0 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_0 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_1 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_1 - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_2 - - - com.karumi.ui.view.SuperHeroDetailActivityTest_doesNotShowAvengersBadgeIfSuperHeroIsNotPartOfTheAvengersTeam_1_2 - - - - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames - com.karumi.ui.view.SuperHeroViewHolderTest - showsSuperHeroesWithLongNames - 2 - 1 - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_dump.json - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_issues.json - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_1_0 - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongNames_1_0 - - - - - com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero - com.karumi.ui.view.SuperHeroViewHolderTest - showsAnySuperHero - 2 - 1 - com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_dump.json - com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_issues.json - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero - - com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_1_0 - - com.karumi.ui.view.SuperHeroViewHolderTest_showsAnySuperHero_1_0 - - - - com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge - com.karumi.ui.view.SuperHeroViewHolderTest - showsAvengersBadge - 2 - 1 - com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_dump.json - com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_issues.json - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge - - com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_1_0 - - com.karumi.ui.view.SuperHeroViewHolderTest_showsAvengersBadge_1_0 - - - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions - com.karumi.ui.view.SuperHeroViewHolderTest - showsSuperHeroesWithLongDescriptions - 2 - 1 - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_dump.json - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_issues.json - - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions - - - /sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_1_0 - - com.karumi.ui.view.SuperHeroViewHolderTest_showsSuperHeroesWithLongDescriptions_1_0 - - - \ No newline at end of file diff --git a/core/src/test/scala/com/karumi/shot/ShotSpec.scala b/core/src/test/scala/com/karumi/shot/ShotSpec.scala index 0bf202d2..a4411754 100644 --- a/core/src/test/scala/com/karumi/shot/ShotSpec.scala +++ b/core/src/test/scala/com/karumi/shot/ShotSpec.scala @@ -52,43 +52,79 @@ class ShotSpec } "Shot" should "should delegate screenshots cleaning to Adb" in { - val appId: AppId = AppIdMother.anyAppId - val device: String = "emulator-5554" + val appId: AppId = AppIdMother.anyAppId + val device: String = "emulator-5554" + val orchestrated: Boolean = false (adb.devices _).expects().returns(List(device)) (envVars.androidSerial _).expects().returns(None) - (adb.clearScreenshots _).expects(device, appId) + (adb.clearScreenshots _).expects(device, appId, orchestrated) - shot.removeScreenshots(appId) + shot.removeScreenshots(appId, orchestrated) } it should "pull the screenshots using the project metadata folder and the app id" in { - val appId = AppIdMother.anyAppId - val device = "emulator-5554" + val appId = AppIdMother.anyAppId + val device = "emulator-5554" + val orchestrated: Boolean = false + + val listOfMetadataFiles = new util.LinkedList[File]() + listOfMetadataFiles.add( + new File( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.json" + ) + ) + + val listOfMetadataComposeFiles = new util.LinkedList[File]() + listOfMetadataComposeFiles.add( + new File( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata_compose.json" + ) + ) (adb.devices _).expects().returns(List(device)) (envVars.androidSerial _).expects().returns(None) (console.show _).expects(*) (adb.pullScreenshots _) - .expects(device, "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/", appId) + .expects( + device, + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/", + appId, + orchestrated + ) (files.rename _) .expects( - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.xml", - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.xml_emulator-5554" + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.json", + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.json_emulator-5554" ) .once() (files.rename _) .expects( - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata.json", - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata.json_emulator-5554" + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata_compose.json", + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata_compose.json_emulator-5554" + ) + .once() + + (files.listFilesInFolder _) + .expects( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/" ) + .returns(listOfMetadataFiles) + .once() + + (files.listFilesInFolder _) + .expects( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/" + ) + .returns(listOfMetadataComposeFiles) .once() shot.downloadScreenshots( appId, - ProjectFolderMother.anyShotFolder + ProjectFolderMother.anyShotFolder, + orchestrated ) } @@ -101,57 +137,94 @@ class ShotSpec } it should "should delegate screenshots cleaning to Adb using the specified ANDROID_SERIAL env var" in { - val appId: AppId = AppIdMother.anyAppId - val device1: String = "emulator-5554" - val device2: String = "emulator-5556" + val appId: AppId = AppIdMother.anyAppId + val device1: String = "emulator-5554" + val device2: String = "emulator-5556" + val orchestrated: Boolean = false (adb.devices _).expects().returns(List(device1, device2)) (envVars.androidSerial _).expects().returns(Some(device2)) - (adb.clearScreenshots _).expects(device2, appId) + (adb.clearScreenshots _).expects(device2, appId, orchestrated) - shot.removeScreenshots(appId) + shot.removeScreenshots(appId, orchestrated) } it should "pull the screenshots using the project metadata folder and the app id from the specified ANDROID_SERIAL env var" in { - val appId = AppIdMother.anyAppId - val device1 = "emulator-5554" - val device2 = "emulator-5556" + val appId = AppIdMother.anyAppId + val device1 = "emulator-5554" + val device2 = "emulator-5556" + val orchestrated: Boolean = false + + val listOfMetadataFiles = new util.LinkedList[File]() + listOfMetadataFiles.add( + new File( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.json" + ) + ) + + val listOfMetadataComposeFiles = new util.LinkedList[File]() + listOfMetadataComposeFiles.add( + new File( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata_compose.json" + ) + ) (adb.devices _).expects().returns(List(device1, device2)) (envVars.androidSerial _).expects().returns(Some(device2)) (console.show _).expects(*) (adb.pullScreenshots _) - .expects(device2, "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/", appId) + .expects( + device2, + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/", + appId, + orchestrated + ) (files.rename _).expects( - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.xml", - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.xml_emulator-5556" + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.json", + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/metadata.json_emulator-5556" ) (files.rename _) .expects( - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata.json", - "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata.json_emulator-5556" + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata_compose.json", + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/metadata_compose.json_emulator-5556" + ) + + (files.listFilesInFolder _) + .expects( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-default/" ) + .returns(listOfMetadataFiles) + .once() + + (files.listFilesInFolder _) + .expects( + "/User/pedro/projects/KarumiApp/app/screenshots/green/debug/Api26/screenshots-compose-default/" + ) + .returns(listOfMetadataComposeFiles) + .once() shot.downloadScreenshots( appId, - ProjectFolderMother.anyShotFolder + ProjectFolderMother.anyShotFolder, + orchestrated ) } it should "should delegate screenshots cleaning to Adb using the devices if ANDROID_SERIAL env var is not valid" in { - val appId: AppId = AppIdMother.anyAppId - val device1: String = "emulator-5554" - val device2: String = "emulator-5556" + val appId: AppId = AppIdMother.anyAppId + val device1: String = "emulator-5554" + val device2: String = "emulator-5556" + val orchestrated: Boolean = false (adb.devices _).expects().returns(List(device1, device2)) (envVars.androidSerial _).expects().returns(Some("another emulator")) - (adb.clearScreenshots _).expects(device1, appId) - (adb.clearScreenshots _).expects(device2, appId) + (adb.clearScreenshots _).expects(device1, appId, orchestrated) + (adb.clearScreenshots _).expects(device2, appId, orchestrated) - shot.removeScreenshots(appId) + shot.removeScreenshots(appId, orchestrated) } it should "show a warning message if we couldn't find the compose screenshots' metadata during the verification proces" in { @@ -171,7 +244,8 @@ class ShotSpec ProjectNameMother.anyProjectName, shouldPrintBase64Error = false, 0d, - showOnlyFailingTestsInReports = false + showOnlyFailingTestsInReports = false, + orchestrated = false ) } @@ -186,6 +260,6 @@ class ShotSpec "🤔 We couldn't find any screenshot. Did you configure Shot properly and added your tests to your project? https://github.com/Karumi/Shot/#getting-started" ) - shot.recordScreenshots(appId, ProjectFolderMother.anyShotFolder) + shot.recordScreenshots(appId, ProjectFolderMother.anyShotFolder, orchestrated = false) } } diff --git a/core/src/test/scala/com/karumi/shot/domain/ShotFolderSpec.scala b/core/src/test/scala/com/karumi/shot/domain/ShotFolderSpec.scala index 5909eb80..cc55063b 100644 --- a/core/src/test/scala/com/karumi/shot/domain/ShotFolderSpec.scala +++ b/core/src/test/scala/com/karumi/shot/domain/ShotFolderSpec.scala @@ -6,19 +6,23 @@ import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper class ShotFolderSpec extends AnyFunSpec { describe("Shot folder") { - val shotFolder = ShotFolder("shot", "shot/build", "debug", None, None, "/") + val shotFolder = ShotFolder("shot", "shot/build", "debug", None, None, "/", false) it("should have screenshots folder") { shotFolder.screenshotsFolder() shouldBe s"shot/screenshots/debug/" shotFolder.pulledScreenshotsFolder() shouldBe s"shot/screenshots/debug/screenshots-default/" shotFolder .pulledComposeScreenshotsFolder() shouldBe s"shot/screenshots/debug/screenshots-compose-default/" + shotFolder + .pulledComposeOrchestratedScreenshotsFolder() shouldBe s"shot/screenshots/debug/screenshots-compose-default/" } it("should have metadata file") { - shotFolder.metadataFile() shouldBe s"shot/screenshots/debug/screenshots-default/metadata.xml" + shotFolder.metadataFile() shouldBe s"shot/screenshots/debug/screenshots-default/metadata.json" shotFolder - .composeMetadataFile() shouldBe s"shot/screenshots/debug/screenshots-compose-default/metadata.json" + .composeMetadataFile() shouldBe s"shot/screenshots/debug/screenshots-compose-default/metadata_compose.json" + shotFolder.composeMetadataFileName() shouldBe "metadata_compose.json" + shotFolder.metadataFileName() shouldBe "metadata.json" } it("should have a report folder") { @@ -33,7 +37,7 @@ class ShotFolderSpec extends AnyFunSpec { } describe("Product Flavor") { - val shotFolder = ShotFolder("shot", "shot/build", "debug", Some("green"), None, "/") + val shotFolder = ShotFolder("shot", "shot/build", "debug", Some("green"), None, "/", false) it("should have screenshots folder") { shotFolder.screenshotsFolder() shouldBe s"shot/screenshots/green/debug/" @@ -45,9 +49,9 @@ class ShotFolderSpec extends AnyFunSpec { it("should have metadata file") { shotFolder - .metadataFile() shouldBe s"shot/screenshots/green/debug/screenshots-default/metadata.xml" + .metadataFile() shouldBe s"shot/screenshots/green/debug/screenshots-default/metadata.json" shotFolder - .composeMetadataFile() shouldBe s"shot/screenshots/green/debug/screenshots-compose-default/metadata.json" + .composeMetadataFile() shouldBe s"shot/screenshots/green/debug/screenshots-compose-default/metadata_compose.json" } it("should have a report folder") { @@ -59,7 +63,7 @@ class ShotFolderSpec extends AnyFunSpec { } describe("Directory Suffix") { - val shotFolder = ShotFolder("shot", "shot/build", "debug", None, Some("Api26"), "/") + val shotFolder = ShotFolder("shot", "shot/build", "debug", None, Some("Api26"), "/", false) it("should have screenshots folder") { shotFolder.screenshotsFolder() shouldBe s"shot/screenshots/debug/Api26/" @@ -71,9 +75,9 @@ class ShotFolderSpec extends AnyFunSpec { it("should have metadata file") { shotFolder - .metadataFile() shouldBe s"shot/screenshots/debug/Api26/screenshots-default/metadata.xml" + .metadataFile() shouldBe s"shot/screenshots/debug/Api26/screenshots-default/metadata.json" shotFolder - .composeMetadataFile() shouldBe s"shot/screenshots/debug/Api26/screenshots-compose-default/metadata.json" + .composeMetadataFile() shouldBe s"shot/screenshots/debug/Api26/screenshots-compose-default/metadata_compose.json" } it("should have a report folder") { @@ -85,7 +89,8 @@ class ShotFolderSpec extends AnyFunSpec { } describe("Product Flavor & Directory Suffix") { - val shotFolder = ShotFolder("shot", "shot/build", "debug", Some("green"), Some("Api26"), "/") + val shotFolder = + ShotFolder("shot", "shot/build", "debug", Some("green"), Some("Api26"), "/", false) it("should have screenshots folder") { shotFolder.screenshotsFolder() shouldBe s"shot/screenshots/green/debug/Api26/" @@ -97,9 +102,9 @@ class ShotFolderSpec extends AnyFunSpec { it("should have metadata file") { shotFolder - .metadataFile() shouldBe s"shot/screenshots/green/debug/Api26/screenshots-default/metadata.xml" + .metadataFile() shouldBe s"shot/screenshots/green/debug/Api26/screenshots-default/metadata.json" shotFolder - .composeMetadataFile() shouldBe s"shot/screenshots/green/debug/Api26/screenshots-compose-default/metadata.json" + .composeMetadataFile() shouldBe s"shot/screenshots/green/debug/Api26/screenshots-compose-default/metadata_compose.json" } it("should have a report folder") { @@ -110,4 +115,26 @@ class ShotFolderSpec extends AnyFunSpec { .recordingReportFolder() shouldBe s"shot/build/reports/shot/green/debug/Api26/record/" } } + + describe("Shot folder orchestrated") { + val shotFolder = ShotFolder("shot", "shot/build", "debug", None, None, "/", true) + + it("should have screenshots folder") { + shotFolder + .pulledScreenshotsFolder() shouldBe s"shot/screenshots/debug/screenshots-default-orchestrated/" + shotFolder + .pulledComposeScreenshotsFolder() shouldBe s"shot/screenshots/debug/screenshots-compose-default/" + shotFolder + .pulledComposeOrchestratedScreenshotsFolder() shouldBe s"shot/screenshots/debug/screenshots-compose-default-orchestrated/" + } + + it("should have metadata file") { + shotFolder + .metadataFile() shouldBe s"shot/screenshots/debug/screenshots-default-orchestrated/metadata.json" + shotFolder + .composeMetadataFile() shouldBe s"shot/screenshots/debug/screenshots-compose-default/metadata_compose.json" + shotFolder.composeMetadataFileName() shouldBe "metadata_compose.json" + shotFolder.metadataFileName() shouldBe "metadata.json" + } + } } diff --git a/core/src/test/scala/com/karumi/shot/json/ScreenshotsSuiteJsonParserSpec.scala b/core/src/test/scala/com/karumi/shot/json/ScreenshotsSuiteJsonParserSpec.scala new file mode 100644 index 00000000..1e9803a1 --- /dev/null +++ b/core/src/test/scala/com/karumi/shot/json/ScreenshotsSuiteJsonParserSpec.scala @@ -0,0 +1,111 @@ +package com.karumi.shot.json + +import com.karumi.shot.Resources +import com.karumi.shot.xml.ScreenshotsSuiteJsonParser.{parseScreenshotSize, parseScreenshots} +import org.scalatest.flatspec._ +import org.scalatest.matchers._ + +class ScreenshotsSuiteJsonParserSpec extends AnyFlatSpec with should.Matchers with Resources { + + private val anyScreenshotsFolder = "/screenshots/" + private val anyTemporalScreenshotsFolder = + "/screenshots/screenshots-default/" + private val anyScreenshotsTemporalBuildPath = + "build/tmp/shot/screenshots" + + "ScreenshotsSuiteJsonParser" should "return an empty spec if there are no screenshots" in { + val json = testResourceContent("/screenshots-metadata/empty-screenshots-metadata.json") + + val screenshots = + parseScreenshots( + json, + anyScreenshotsFolder, + anyTemporalScreenshotsFolder, + anyScreenshotsTemporalBuildPath + ) + + screenshots shouldBe empty + } + + it should "parse a regular metadata file" in { + val json = testResourceContent("/screenshots-metadata/metadata.json") + val viewHierarchyContent = + testResourceContent("/screenshots-metadata/view-hierarchy.json") + + val screenshotsWithoutSize = + parseScreenshots( + json, + anyScreenshotsFolder, + anyTemporalScreenshotsFolder, + anyScreenshotsTemporalBuildPath + ) + val screenshots = screenshotsWithoutSize.map { screenshot => + parseScreenshotSize(screenshot, viewHierarchyContent) + } + + screenshots.size shouldBe 11 + val firstScreenshot = screenshots.head + firstScreenshot.name shouldBe "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes" + firstScreenshot.recordedScreenshotPath shouldBe "/screenshots/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png" + firstScreenshot.temporalScreenshotPath shouldBe "build/tmp/shot/screenshots/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png" + firstScreenshot.testClass shouldBe "com.karumi.ui.view.MainActivityTest" + firstScreenshot.testName shouldBe "showsSuperHeroesIfThereAreSomeSuperHeroes" + firstScreenshot.tilesDimension.width shouldBe 3 + firstScreenshot.tilesDimension.height shouldBe 5 + firstScreenshot.viewHierarchy shouldBe "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_dump.json" + firstScreenshot.absoluteFileNames shouldBe Seq( + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_3.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_4.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_3.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_4.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_0.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_1.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_2.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_3.png", + "/storage/emulated/0/Download/screenshots/com.test.application.id.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_4.png" + ) + firstScreenshot.relativeFileNames shouldBe Seq( + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_3.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_4.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_3.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_4.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_0.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_1.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_2.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_3.png", + "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_4.png" + ) + firstScreenshot.recordedPartsPaths shouldBe Seq( + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_3.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_4.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_3.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_4.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_0.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_1.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_2.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_3.png", + "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_2_4.png" + ) + firstScreenshot.screenshotDimension.width shouldBe 768 + firstScreenshot.screenshotDimension.height shouldBe 400 + firstScreenshot.fileName shouldBe "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png" + } +} diff --git a/core/src/test/scala/com/karumi/shot/mothers/ProjectFolderMother.scala b/core/src/test/scala/com/karumi/shot/mothers/ProjectFolderMother.scala index f2592513..c8d2c21a 100644 --- a/core/src/test/scala/com/karumi/shot/mothers/ProjectFolderMother.scala +++ b/core/src/test/scala/com/karumi/shot/mothers/ProjectFolderMother.scala @@ -10,6 +10,7 @@ object ProjectFolderMother { val anyFlavor = "green" val anyDirectorySuffix = "Api26" val anySeparator = "/" + val anyOrchestrated = false val anyShotFolder: ShotFolder = ShotFolder( anyProjectFolder, @@ -17,7 +18,8 @@ object ProjectFolderMother { anyBuildType, Some(anyFlavor), Some(anyDirectorySuffix), - anySeparator + anySeparator, + anyOrchestrated ) } diff --git a/core/src/test/scala/com/karumi/shot/xml/ScreenshotsSuiteXmlParserSpec.scala b/core/src/test/scala/com/karumi/shot/xml/ScreenshotsSuiteXmlParserSpec.scala deleted file mode 100644 index 4cfe9f19..00000000 --- a/core/src/test/scala/com/karumi/shot/xml/ScreenshotsSuiteXmlParserSpec.scala +++ /dev/null @@ -1,84 +0,0 @@ -package com.karumi.shot.xml - -import com.karumi.shot.Resources -import com.karumi.shot.xml.ScreenshotsSuiteXmlParser._ -import org.scalatest.flatspec._ -import org.scalatest.matchers._ - -class ScreenshotsSuiteXmlParserSpec extends AnyFlatSpec with should.Matchers with Resources { - - private val anyScreenshotsFolder = "/screenshots/" - private val anyTemporalScreenshotsFolder = - "/screenshots/screenshots-default/" - private val anyScreenshotsTemporalBuildPath = - "build/tmp/shot/screenshots" - - "ScreenshotsSuiteXmlParser" should "return an empty spec if there are no screenshots" in { - val xml = testResourceContent("/screenshots-metadata/empty-screenshots-metadata.xml") - - val screenshots = - parseScreenshots( - xml, - anyScreenshotsFolder, - anyTemporalScreenshotsFolder, - anyScreenshotsTemporalBuildPath - ) - - screenshots shouldBe empty - } - - it should "parse a regular metadata file" in { - val xml = testResourceContent("/screenshots-metadata/metadata.xml") - val viewHierarchyContent = - testResourceContent("/screenshots-metadata/view-hierarchy.json") - - val screenshotsWithoutSize = - parseScreenshots( - xml, - anyScreenshotsFolder, - anyTemporalScreenshotsFolder, - anyScreenshotsTemporalBuildPath - ) - val screenshots = screenshotsWithoutSize.map { screenshot => - parseScreenshotSize(screenshot, viewHierarchyContent) - } - - screenshots.size shouldBe 11 - val firstScreenshot = screenshots.head - firstScreenshot.name shouldBe "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes" - firstScreenshot.recordedScreenshotPath shouldBe "/screenshots/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png" - firstScreenshot.temporalScreenshotPath shouldBe "build/tmp/shot/screenshots/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png" - firstScreenshot.testClass shouldBe "com.karumi.ui.view.MainActivityTest" - firstScreenshot.testName shouldBe "showsSuperHeroesIfThereAreSomeSuperHeroes" - firstScreenshot.tilesDimension.width shouldBe 2 - firstScreenshot.tilesDimension.height shouldBe 3 - firstScreenshot.viewHierarchy shouldBe "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_dump.json" - firstScreenshot.absoluteFileNames shouldBe Seq( - "/sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png", - "/sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1.png", - "/sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2.png", - "/sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0.png", - "/sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1.png", - "/sdcard/screenshots/com.karumi.test/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2.png" - ) - firstScreenshot.relativeFileNames shouldBe Seq( - "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png", - "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1.png", - "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2.png", - "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0.png", - "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1.png", - "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2.png" - ) - firstScreenshot.recordedPartsPaths shouldBe Seq( - "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png", - "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_1.png", - "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_0_2.png", - "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_0.png", - "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_1.png", - "/screenshots/screenshots-default/com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes_1_2.png" - ) - firstScreenshot.screenshotDimension.width shouldBe 768 - firstScreenshot.screenshotDimension.height shouldBe 400 - firstScreenshot.fileName shouldBe "com.karumi.ui.view.MainActivityTest_showsSuperHeroesIfThereAreSomeSuperHeroes.png" - } -} diff --git a/shot-android/build.gradle b/shot-android/build.gradle index 47765148..765a3235 100644 --- a/shot-android/build.gradle +++ b/shot-android/build.gradle @@ -48,7 +48,7 @@ repositories { } dependencies { - implementation "com.facebook.testing.screenshot:core:0.13.0" + implementation "com.facebook.testing.screenshot:core:0.14.0" implementation "androidx.test:runner:1.3.0" implementation "androidx.recyclerview:recyclerview:1.2.0" implementation "androidx.test.espresso:espresso-core:3.3.0" diff --git a/shot-android/src/androidTest/java/com/karumi/shot/compose/ScreenshotSaverTest.kt b/shot-android/src/androidTest/java/com/karumi/shot/compose/ScreenshotSaverTest.kt index 67009105..56dbe99b 100644 --- a/shot-android/src/androidTest/java/com/karumi/shot/compose/ScreenshotSaverTest.kt +++ b/shot-android/src/androidTest/java/com/karumi/shot/compose/ScreenshotSaverTest.kt @@ -86,7 +86,7 @@ class ScreenshotSaverTest { saver.saveMetadata(session) val expectedContent = "{\"screenshots\":[{\"name\":\"test1\",\"testClassName\":\"MainActivityTest\",\"testName\":\"testName1\"},{\"name\":\"test2\",\"testClassName\":\"MainActivityTest\",\"testName\":\"testName2\"}]}" - val file = File("${AndroidStorageInfo.storageBaseUrl}/screenshots/com.karumi.shot.test/screenshots-compose-default/metadata.json") + val file = File("${AndroidStorageInfo.storageBaseUrl}/screenshots/com.karumi.shot.test/screenshots-compose-default/metadata_compose.json") val content = file.readText(Charset.defaultCharset()) assertTrue(file.exists()) assertEquals(expectedContent, content) @@ -101,7 +101,7 @@ class ScreenshotSaverTest { val bitmapFile = File("${AndroidStorageInfo.storageBaseUrl}/screenshots/com.karumi.shot.test/screenshots-compose-default/${anyScreenshotMetadata.name}.png") assertTrue(bitmapFile.exists()) - val metadataFile = File("${AndroidStorageInfo.storageBaseUrl}/screenshots/com.karumi.shot.test/screenshots-compose-default/metadata.json") + val metadataFile = File("${AndroidStorageInfo.storageBaseUrl}/screenshots/com.karumi.shot.test/screenshots-compose-default/metadata_compose.json") assertTrue(metadataFile.exists()) } diff --git a/shot-android/src/main/java/com/karumi/shot/OrchestratorScreenshotSaver.kt b/shot-android/src/main/java/com/karumi/shot/OrchestratorScreenshotSaver.kt new file mode 100644 index 00000000..71bd0543 --- /dev/null +++ b/shot-android/src/main/java/com/karumi/shot/OrchestratorScreenshotSaver.kt @@ -0,0 +1,72 @@ +package com.karumi.shot + +import android.app.Instrumentation +import android.os.Bundle +import androidx.test.internal.runner.RunnerArgs +import java.io.File + +class OrchestratorScreenshotSaver { + companion object { + + var packageName: String? = null + var orchestrated: Boolean = false + + fun onCreate(instrumentation: Instrumentation, args: Bundle) { + orchestrated = RunnerArgs.Builder() + .fromManifest(instrumentation) + .fromBundle(instrumentation, args) + .build() + .orchestratorService != null + packageName = instrumentation.context.packageName + } + + fun onDestroy() { + if (orchestrated) { + copyScreenshots("screenshots-default") + copyScreenshots( + screenshotDirName = "screenshots-compose-default", + onlyMetadata = true, + fileSuffix = "_compose" + ) + } + } + + private fun copyScreenshots( + screenshotDirName: String, + onlyMetadata: Boolean = false, + fileSuffix: String = "" + ) { + val orchestratedSuffix = "-orchestrated" + + val screenshotsFolderPath = + "${AndroidStorageInfo.storageBaseUrl}/screenshots/$packageName/$screenshotDirName/" + val orchestratedFolderPath = + "${AndroidStorageInfo.storageBaseUrl}/screenshots/$packageName/$screenshotDirName$orchestratedSuffix/" + + File(orchestratedFolderPath).mkdirs() + val screenshotsFolder = File(screenshotsFolderPath) + + screenshotsFolder.listFiles()?.forEach { file -> + if (!onlyMetadata || file.name.contains("metadata$fileSuffix.json")) { + moveFile(file, orchestratedFolderPath) + } + } + } + + private fun moveFile(file: File, targetDirPath: String) { + // Under orchestrated tests metadata files are created for every test. + // It requires to change their names to achieve unique files and avoid + // FileExistsException be thrown during copying. + var counter = 0 + var targetFile: File + do { + val counterSuffix = if (counter == 0) "" else "_$counter" + val newPath = "$targetDirPath${file.nameWithoutExtension}.${file.extension}$counterSuffix" + targetFile = File(newPath) + counter = counter.inc() + } while (targetFile.exists()) + + file.renameTo(targetFile) + } + } +} diff --git a/shot-android/src/main/java/com/karumi/shot/ShotTestRunner.kt b/shot-android/src/main/java/com/karumi/shot/ShotTestRunner.kt index d4cbce6a..697cd530 100644 --- a/shot-android/src/main/java/com/karumi/shot/ShotTestRunner.kt +++ b/shot-android/src/main/java/com/karumi/shot/ShotTestRunner.kt @@ -13,11 +13,13 @@ open class ShotTestRunner : AndroidJUnitRunner() { configureFacebookLibFolder() ScreenshotRunner.onCreate(this, args) ComposeScreenshotRunner.onCreate(this) + OrchestratorScreenshotSaver.onCreate(this, args) } override fun finish(resultCode: Int, results: Bundle?) { ScreenshotRunner.onDestroy() ComposeScreenshotRunner.onDestroy() + OrchestratorScreenshotSaver.onDestroy() super.finish(resultCode, results) } diff --git a/shot-android/src/main/java/com/karumi/shot/compose/ScreenshotSaver.kt b/shot-android/src/main/java/com/karumi/shot/compose/ScreenshotSaver.kt index 4ca9ff0d..23143eef 100644 --- a/shot-android/src/main/java/com/karumi/shot/compose/ScreenshotSaver.kt +++ b/shot-android/src/main/java/com/karumi/shot/compose/ScreenshotSaver.kt @@ -12,7 +12,7 @@ import java.lang.IllegalArgumentException class ScreenshotSaver(private val packageName: String, private val bitmapGenerator: SemanticsNodeBitmapGenerator) { private val screenshotsFolder: String = "${AndroidStorageInfo.storageBaseUrl}/screenshots/$packageName/screenshots-compose-default/" - private val metadataFile: String = "$screenshotsFolder/metadata.json" + private val metadataFile: String = "$screenshotsFolder/metadata_compose.json" private val gson: Gson = Gson() fun saveScreenshot(screenshot: ScreenshotToSave) { diff --git a/shot-consumer-compose/app/build.gradle b/shot-consumer-compose/app/build.gradle index 73d30912..10e94a5e 100644 --- a/shot-consumer-compose/app/build.gradle +++ b/shot-consumer-compose/app/build.gradle @@ -56,6 +56,11 @@ android { packagingOptions { exclude "META-INF/*" } + testOptions { + if (System.getenv("orchestrated") == "true") { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + } } shot { @@ -76,6 +81,8 @@ dependencies { testImplementation "junit:junit:4.13.1" + androidTestUtil "androidx.test:orchestrator:1.4.1" + androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0" androidTestImplementation "androidx.test:core-ktx:1.3.0" diff --git a/shot-consumer-flavors/app/build.gradle b/shot-consumer-flavors/app/build.gradle index cc208af6..579a84ea 100644 --- a/shot-consumer-flavors/app/build.gradle +++ b/shot-consumer-flavors/app/build.gradle @@ -61,6 +61,11 @@ android { dimension "color" } } + testOptions { + if (System.getenv("orchestrated") == "true") { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + } } configurations { @@ -84,6 +89,7 @@ dependencies { annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0' testImplementation "junit:junit:4.13" + androidTestUtil "androidx.test:orchestrator:1.4.1" androidTestImplementation "androidx.test:runner:1.3.0" androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0" diff --git a/shot-consumer-library-no-tests/app/build.gradle.kts b/shot-consumer-library-no-tests/app/build.gradle.kts index cf826a6f..febc8deb 100644 --- a/shot-consumer-library-no-tests/app/build.gradle.kts +++ b/shot-consumer-library-no-tests/app/build.gradle.kts @@ -19,6 +19,12 @@ android { kotlinOptions { jvmTarget = "1.8" } + + testOptions { + if (System.getenv("orchestrated") == "true") { + execution = "ANDROIDX_TEST_ORCHESTRATOR" + } + } } dependencies { @@ -28,6 +34,7 @@ dependencies { implementation("com.google.android.material:material:1.3.0") implementation("androidx.constraintlayout:constraintlayout:2.0.4") testImplementation("junit:junit:4.+") + androidTestUtil("androidx.test:orchestrator:1.4.1") androidTestImplementation("androidx.test.ext:junit:1.1.2") androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0") } diff --git a/shot-consumer-library-no-tests/library/build.gradle.kts b/shot-consumer-library-no-tests/library/build.gradle.kts index f45266a9..8adaea48 100644 --- a/shot-consumer-library-no-tests/library/build.gradle.kts +++ b/shot-consumer-library-no-tests/library/build.gradle.kts @@ -25,6 +25,12 @@ android { exclude("META-INF/AL2.0") exclude("META-INF/LGPL2.1") } + + testOptions { + if (System.getenv("orchestrated") == "true") { + execution = "ANDROIDX_TEST_ORCHESTRATOR" + } + } } shot { @@ -36,6 +42,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.3.0") implementation("com.google.android.material:material:1.3.0") testImplementation("junit:junit:4.+") + androidTestUtil("androidx.test:orchestrator:1.4.1") androidTestImplementation("androidx.test.ext:junit:1.1.2") androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0") } diff --git a/shot-consumer/app/build.gradle b/shot-consumer/app/build.gradle index 3278d274..b6c687d9 100644 --- a/shot-consumer/app/build.gradle +++ b/shot-consumer/app/build.gradle @@ -46,6 +46,12 @@ android { packagingOptions { exclude "META-INF/*" } + + testOptions { + if (System.getenv("orchestrated") == "true") { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + } } configurations { @@ -70,6 +76,7 @@ dependencies { debugImplementation "androidx.fragment:fragment-testing:1.3.2" testImplementation "junit:junit:4.12" + androidTestUtil "androidx.test:orchestrator:1.4.1" androidTestImplementation "androidx.test:runner:1.2.0" androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0" diff --git a/shot-consumer/app2/build.gradle b/shot-consumer/app2/build.gradle index 26165616..06fcf3cd 100644 --- a/shot-consumer/app2/build.gradle +++ b/shot-consumer/app2/build.gradle @@ -43,6 +43,11 @@ android { packagingOptions { exclude "META-INF/*" } + testOptions { + if (System.getenv("orchestrated") == "true") { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + } } configurations { @@ -66,6 +71,7 @@ dependencies { annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0' testImplementation "junit:junit:4.13" + androidTestUtil "androidx.test:orchestrator:1.4.1" androidTestImplementation "androidx.test:runner:1.3.0" androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0" diff --git a/shot-consumer/samplelibrary/build.gradle b/shot-consumer/samplelibrary/build.gradle index 44706f28..cf7d3f17 100644 --- a/shot-consumer/samplelibrary/build.gradle +++ b/shot-consumer/samplelibrary/build.gradle @@ -28,12 +28,19 @@ android { packagingOptions { exclude "META-INF/*" } + testOptions { + if (System.getenv("orchestrated") == "true") { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation "junit:junit:4.13" + androidTestUtil "androidx.test:orchestrator:1.4.1" + androidTestImplementation "androidx.test:runner:1.3.0" androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0" androidTestImplementation "androidx.test.espresso:espresso-intents:3.3.0" diff --git a/shot/src/main/scala/com/karumi/shot/ShotPlugin.scala b/shot/src/main/scala/com/karumi/shot/ShotPlugin.scala index 8481500b..fd479528 100644 --- a/shot/src/main/scala/com/karumi/shot/ShotPlugin.scala +++ b/shot/src/main/scala/com/karumi/shot/ShotPlugin.scala @@ -98,7 +98,9 @@ class ShotPlugin extends Plugin[Project] { val completeAppId = composeCompleteAppId(project, variant) val appTestId = Option(flavor.getTestApplicationId).getOrElse(completeAppId) val flavorName = if (variant.getFlavorName.nonEmpty) Some(variant.getFlavorName) else None - addTasksFor(project, flavorName, variant.getBuildType, appTestId, baseTask) + val orchestrated = isOrchestratorConnected(project) + + addTasksFor(project, flavorName, variant.getBuildType, appTestId, orchestrated, baseTask) } private def composeCompleteAppId(project: Project, variant: BaseVariant): String = { @@ -138,6 +140,7 @@ class ShotPlugin extends Plugin[Project] { flavor: Option[String], buildType: BuildType, appId: String, + orchestrated: Boolean, baseTask: TaskProvider[ExecuteScreenshotTestsForEveryFlavor] ): Unit = { val extension = project.getExtensions.getByType[ShotExtension](classOf[ShotExtension]) @@ -173,12 +176,14 @@ class ShotPlugin extends Plugin[Project] { task.flavor = flavor task.buildType = buildType task.appId = appId + task.orchestrated = orchestrated } removeScreenshotsBeforeExecution.configure { task => task.setDescription(RemoveScreenshotsTask.description(flavor, buildType)) task.flavor = flavor task.buildType = buildType task.appId = appId + task.orchestrated = orchestrated } val downloadScreenshots = tasks @@ -188,6 +193,7 @@ class ShotPlugin extends Plugin[Project] { task.flavor = flavor task.buildType = buildType task.appId = appId + task.orchestrated = orchestrated } val executeScreenshot = tasks .register(ExecuteScreenshotTests.name(flavor, buildType), classOf[ExecuteScreenshotTests]) @@ -196,6 +202,7 @@ class ShotPlugin extends Plugin[Project] { task.flavor = flavor task.buildType = buildType task.appId = appId + task.orchestrated = orchestrated } if (runInstrumentation(project, extension)) { @@ -274,4 +281,15 @@ class ShotPlugin extends Plugin[Project] { private def getAndroidAppExtension(project: Project) = { project.getExtensions.getByType[AppExtension](classOf[AppExtension]) } + + private def isOrchestratorConnected(project: Project) = { + val orchestrator = "ANDROIDX_TEST_ORCHESTRATOR" + if (isAnAndroidProject(project)) { + getAndroidAppExtension(project).getTestOptions.getExecution.equalsIgnoreCase(orchestrator) + } else if (isAnAndroidLibrary(project)) { + getAndroidLibraryExtension(project).getTestOptions.getExecution.equalsIgnoreCase(orchestrator) + } else { + false + } + } } diff --git a/shot/src/main/scala/com/karumi/shot/tasks/Tasks.scala b/shot/src/main/scala/com/karumi/shot/tasks/Tasks.scala index 97c0feca..f4a0b6f4 100644 --- a/shot/src/main/scala/com/karumi/shot/tasks/Tasks.scala +++ b/shot/src/main/scala/com/karumi/shot/tasks/Tasks.scala @@ -22,6 +22,7 @@ abstract class ShotTask extends DefaultTask { var appId: String = _ var flavor: Option[String] = _ var buildType: BuildType = _ + var orchestrated: Boolean = false private val console = new Console protected val shot: Shot = new Shot( @@ -47,7 +48,8 @@ abstract class ShotTask extends DefaultTask { flavor, if (project.hasProperty("directorySuffix")) Some(project.property("directorySuffix").toString) else None, - File.separator + File.separator, + orchestrated ) } @@ -85,7 +87,7 @@ class ExecuteScreenshotTests extends ShotTask { .getByType[ShotExtension](classOf[ShotExtension]) .showOnlyFailingTestsInReports if (recordScreenshots) { - shot.recordScreenshots(appId, shotFolder) + shot.recordScreenshots(appId, shotFolder, orchestrated) } else { val result = shot.verifyScreenshots( appId, @@ -93,7 +95,8 @@ class ExecuteScreenshotTests extends ShotTask { project.getName, printBase64, tolerance, - showOnlyFailingTestsInReports + showOnlyFailingTestsInReports, + orchestrated ) if (result.hasErrors) { throw new GradleException( @@ -116,7 +119,7 @@ object DownloadScreenshotsTask { class DownloadScreenshotsTask extends ShotTask { @TaskAction def downloadScreenshots(): Unit = { - shot.downloadScreenshots(appId, shotFolder) + shot.downloadScreenshots(appId, shotFolder, orchestrated) } } @@ -133,7 +136,7 @@ object RemoveScreenshotsTask { class RemoveScreenshotsTask extends ShotTask { @TaskAction def clearScreenshots(): Unit = - shot.removeScreenshots(appId) + shot.removeScreenshots(appId, orchestrated) } object ExecuteScreenshotTestsForEveryFlavor { val name: String = "executeScreenshotTests"