Taking screenshots from a composable is possible in tests.
For taking screenshots in production code see this question and this issue.
First, make sure you have the following dependency in your build script (along with other required Compose dependencies):
debugImplementation("androidx.compose.ui:ui-test-manifest:<version>")
Note: Instead of the above dependency, you can simply add AndroidManifest.xml in androidTest directory and in the manifest
>application
element add this: <activity android:name="androidx.activity.ComponentActivity"/>
.
Refer to this answer.
Here is a complete example for saving, reading, and comparing screenshots:
(Please refer to this post for setting up write permissions and so on for the tests)
class ScreenshotTest {
@get:Rule val composeTestRule = createComposeRule()
@Test fun takeAndSaveScreenshot() {
composeTestRule.setContent { MyComposableFunction() }
val node = composeTestRule.onRoot()
val screenshot = node.captureToImage().asAndroidBitmap()
saveScreenshot("screenshot.png", screenshot)
}
@Test fun readAndCompareScreenshots() {
composeTestRule.setContent { MyComposableFunction() }
val node = composeTestRule.onRoot()
val screenshot = node.captureToImage().asAndroidBitmap()
val context = InstrumentationRegistry.getInstrumentation().targetContext
val path = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val file = File(path, "screenshot.png")
val saved = readScreenshot(file)
println("Are screenshots the same: ${screenshot.sameAs(saved)}")
}
private fun readScreenshot(file: File) = BitmapFactory.decodeFile(file.path)
private fun saveScreenshot(filename: String, screenshot: Bitmap) {
val context = InstrumentationRegistry.getInstrumentation().targetContext
// Saves in /Android/data/your.package.name.test/files/Pictures on external storage
val path = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val file = File(path, filename)
file.outputStream().use { stream ->
screenshot.compress(Bitmap.CompressFormat.PNG, 100, stream)
}
}
}
Thanks to Google Codelabs for this.