Issue#100 Fix screenshot rule for API 21

On API 21 the images could not have been saved before.
Added logic to choose external or internal folder.
Tested on:
API 21, 24, 30, 31, 32
This commit is contained in:
Gergely Hegedus 2022-07-13 19:13:41 +03:00
parent 60e96f2beb
commit d23c1b9a9d
2 changed files with 36 additions and 13 deletions

View file

@ -1,6 +1,7 @@
package org.fnives.test.showcase.android.testutil.screenshot
import android.graphics.Bitmap
import android.util.Log
import androidx.test.runner.screenshot.ScreenCapture
import androidx.test.runner.screenshot.ScreenCaptureProcessor
import androidx.test.runner.screenshot.Screenshot
@ -38,28 +39,29 @@ class ScreenshotRule(
}
}
fun takeScreenshot(prefix: String = this.prefix, baseName: String) {
fun takeScreenshot(prefix: String = this.prefix, baseName: String, capture: ScreenCapture = Screenshot.capture()) {
val fileName = if (timestampSuffix) {
"$prefix-$baseName-${System.currentTimeMillis()}"
} else {
"$prefix-$baseName"
}
takeScreenshot(filename = fileName)
takeScreenshot(filename = fileName, capture = capture)
}
@Suppress("PrintStackTrace")
private fun takeScreenshot(filename: String) {
val capture: ScreenCapture = Screenshot.capture()
private fun takeScreenshot(filename: String, capture: ScreenCapture) {
capture.name = filename
capture.format = Bitmap.CompressFormat.JPEG
try {
capture.process(setOf(processor))
} catch (e: IOException) {
Log.d(TAG, "Couldn't save image: $e")
e.printStackTrace()
}
}
companion object {
const val TAG = "Screenshot Rule"
val Description.testScreenshotName get() = "${testClass.simpleName}-$methodName"
val Description.beforeTestScreenshotName get() = "$testScreenshotName-BEFORE"
val Description.successTestScreenshotName get() = "$testScreenshotName-SUCCESS"

View file

@ -1,19 +1,40 @@
package org.fnives.test.showcase.android.testutil.screenshot
import android.os.Build
import android.os.Environment
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.screenshot.ScreenCaptureProcessor
import androidx.test.runner.screenshot.basicScreenCaptureProcessor
import java.io.File
fun basicScreenCaptureProcessor(subDir: String = "test-screenshots") =
basicScreenCaptureProcessor(File(getTestPicturesDir(), subDir))
fun basicScreenCaptureProcessor(subDir: String = "test-screenshots"): ScreenCaptureProcessor {
val directory = File(getTestPicturesDir(), subDir)
Log.d(ScreenshotRule.TAG, "directory to save screenshots = $directory")
return basicScreenCaptureProcessor(File(getTestPicturesDir(), subDir))
}
/**
* BasicScreenCaptureProcessor seems to work differently on API versions,
* based on where we have access to save and pull the images from.
*
* see example issue: https://github.com/android/android-test/issues/818
*/
@Suppress("DEPRECATION")
fun getTestPicturesDir() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
InstrumentationRegistry.getInstrumentation().targetContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
} else {
fun getTestPicturesDir(): File? {
val packageName = InstrumentationRegistry.getInstrumentation().targetContext.packageName
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), packageName)
val environmentFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
val externalFolder = File(environmentFolder, packageName)
if (externalFolder.canWrite()) {
Log.d(ScreenshotRule.TAG, "external folder")
return externalFolder
}
val internalFolder = InstrumentationRegistry.getInstrumentation().targetContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
if (internalFolder?.canWrite() == true) {
Log.d(ScreenshotRule.TAG, "internal folder")
return internalFolder
}
Log.d(ScreenshotRule.TAG, "cant find directory the screenshots could be saved into")
return null
}