mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
taking screenshots on sanity test failure
This commit is contained in:
parent
fc865682b1
commit
2583a6d6bf
@ -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.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.espresso.tools.ScreenshotFailureRule
|
||||||
import im.vector.app.features.MainActivity
|
import im.vector.app.features.MainActivity
|
||||||
import im.vector.app.getString
|
import im.vector.app.getString
|
||||||
import im.vector.app.ui.robot.ElementRobot
|
import im.vector.app.ui.robot.ElementRobot
|
||||||
import im.vector.app.ui.robot.withDeveloperMode
|
import im.vector.app.ui.robot.withDeveloperMode
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.junit.rules.RuleChain
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@ -37,7 +39,9 @@ import java.util.UUID
|
|||||||
class UiAllScreensSanityTest {
|
class UiAllScreensSanityTest {
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val activityRule = ActivityScenarioRule(MainActivity::class.java)
|
val testRule = RuleChain
|
||||||
|
.outerRule(ActivityScenarioRule(MainActivity::class.java))
|
||||||
|
.around(ScreenshotFailureRule())
|
||||||
|
|
||||||
private val elementRobot = ElementRobot()
|
private val elementRobot = ElementRobot()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user