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

View file

@ -1,19 +1,40 @@
package org.fnives.test.showcase.android.testutil.screenshot package org.fnives.test.showcase.android.testutil.screenshot
import android.os.Build
import android.os.Environment import android.os.Environment
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.screenshot.ScreenCaptureProcessor
import androidx.test.runner.screenshot.basicScreenCaptureProcessor import androidx.test.runner.screenshot.basicScreenCaptureProcessor
import java.io.File import java.io.File
fun basicScreenCaptureProcessor(subDir: String = "test-screenshots") = fun basicScreenCaptureProcessor(subDir: String = "test-screenshots"): ScreenCaptureProcessor {
basicScreenCaptureProcessor(File(getTestPicturesDir(), subDir)) 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") @Suppress("DEPRECATION")
fun getTestPicturesDir() = fun getTestPicturesDir(): File? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val packageName = InstrumentationRegistry.getInstrumentation().targetContext.packageName
InstrumentationRegistry.getInstrumentation().targetContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES) val environmentFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
} else { val externalFolder = File(environmentFolder, packageName)
val packageName = InstrumentationRegistry.getInstrumentation().targetContext.packageName if (externalFolder.canWrite()) {
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), packageName) 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
}