mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
taking screenshots on sanity test failure
This commit is contained in:
parent
fc865682b1
commit
2583a6d6bf
2 changed files with 123 additions and 1 deletions
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.espresso.tools
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.ContentValues
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||
import org.junit.rules.TestWatcher
|
||||
import org.junit.runner.Description
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
private val SCREENSHOT_FOLDER_LOCATION = "${Environment.DIRECTORY_PICTURES}/failure_screenshots"
|
||||
private val deviceLanguage = Locale.getDefault().language
|
||||
|
||||
class ScreenshotFailureRule : TestWatcher() {
|
||||
override fun failed(e: Throwable?, description: Description) {
|
||||
val screenShotName = "$deviceLanguage-${description.methodName}-${SimpleDateFormat("EEE-MMMM-dd-HH:mm:ss").format(Date())}"
|
||||
val bitmap = getInstrumentation().uiAutomation.takeScreenshot()
|
||||
storeFailureScreenshot(bitmap, screenShotName)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores screenshots in sdcard/Pictures/failure_screenshots
|
||||
*/
|
||||
private fun storeFailureScreenshot(bitmap: Bitmap, screenshotName: String) {
|
||||
val contentResolver = getInstrumentation().targetContext.applicationContext.contentResolver
|
||||
|
||||
val contentValues = ContentValues().apply {
|
||||
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
|
||||
put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
|
||||
}
|
||||
if (android.os.Build.VERSION.SDK_INT >= 29) {
|
||||
useMediaStoreScreenshotStorage(
|
||||
contentValues,
|
||||
contentResolver,
|
||||
screenshotName,
|
||||
SCREENSHOT_FOLDER_LOCATION,
|
||||
bitmap
|
||||
)
|
||||
} else {
|
||||
usePublicExternalScreenshotStorage(
|
||||
contentValues,
|
||||
contentResolver,
|
||||
screenshotName,
|
||||
SCREENSHOT_FOLDER_LOCATION,
|
||||
bitmap
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun useMediaStoreScreenshotStorage(
|
||||
contentValues: ContentValues,
|
||||
contentResolver: ContentResolver,
|
||||
screenshotName: String,
|
||||
screenshotLocation: String,
|
||||
bitmap: Bitmap
|
||||
) {
|
||||
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "$screenshotName.jpeg")
|
||||
contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, screenshotLocation)
|
||||
val uri: Uri? = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
|
||||
if (uri != null) {
|
||||
contentResolver.openOutputStream(uri)?.let { saveScreenshotToStream(bitmap, it) }
|
||||
contentResolver.update(uri, contentValues, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun usePublicExternalScreenshotStorage(
|
||||
contentValues: ContentValues,
|
||||
contentResolver: ContentResolver,
|
||||
screenshotName: String,
|
||||
screenshotLocation: String,
|
||||
bitmap: Bitmap
|
||||
) {
|
||||
val directory = File(Environment.getExternalStoragePublicDirectory(screenshotLocation).toString())
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs()
|
||||
}
|
||||
val file = File(directory, "$screenshotName.jpeg")
|
||||
saveScreenshotToStream(bitmap, FileOutputStream(file))
|
||||
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
|
||||
}
|
||||
|
||||
private fun saveScreenshotToStream(bitmap: Bitmap, outputStream: OutputStream) {
|
||||
outputStream.use {
|
||||
try {
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, it)
|
||||
} catch (e: IOException) {
|
||||
Timber.e("Screenshot was not stored at this time")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,12 +20,14 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import im.vector.app.R
|
||||
import im.vector.app.espresso.tools.ScreenshotFailureRule
|
||||
import im.vector.app.features.MainActivity
|
||||
import im.vector.app.getString
|
||||
import im.vector.app.ui.robot.ElementRobot
|
||||
import im.vector.app.ui.robot.withDeveloperMode
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
import java.util.UUID
|
||||
|
||||
|
@ -37,7 +39,9 @@ import java.util.UUID
|
|||
class UiAllScreensSanityTest {
|
||||
|
||||
@get:Rule
|
||||
val activityRule = ActivityScenarioRule(MainActivity::class.java)
|
||||
val testRule = RuleChain
|
||||
.outerRule(ActivityScenarioRule(MainActivity::class.java))
|
||||
.around(ScreenshotFailureRule())
|
||||
|
||||
private val elementRobot = ElementRobot()
|
||||
|
||||
|
|
Loading…
Reference in a new issue