Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Take screenshot on test failure
Browse files Browse the repository at this point in the history
  • Loading branch information
jonnyandrew committed Nov 16, 2023
1 parent 59d2a99 commit 04b84f5
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 4 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,8 @@ jobs:
disable-animations: true
enable-hw-keyboard: true
script: |
./gradlew unitTestsWithCoverage ${{ env.CI_GRADLE_ARG_PROPERTIES }}
./gradlew generateUnitTestCoverageReport ${{ env.CI_GRADLE_ARG_PROPERTIES }}
./gradlew instrumentationTestsWithCoverage ${{ env.CI_GRADLE_ARG_PROPERTIES }}
./gradlew generateInstrumentationTestCoverageReport ${{ env.CI_GRADLE_ARG_PROPERTIES }}
chmod +x scripts/ci_test.sh
scripts/ci_test.sh
- name : Upload test results
if : ${{ always() }}
Expand All @@ -105,6 +103,7 @@ jobs:
path : |
./**/build/reports/tests/**
./**/build/reports/androidTests/connected/**
./**/build/reports/screenshots/**
- name: Upload unit test coverage to Codecov
uses: codecov/codecov-action@v3
Expand Down
1 change: 1 addition & 0 deletions platforms/android/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ test-turbine = { module="app.cash.turbine:turbine", version="1.0.0" }
test-androidx-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" }
test-androidx-espresso = { module="androidx.test.espresso:espresso-core", version.ref="espresso" }
test-androidx-espresso-accessibility = { module="androidx.test.espresso:espresso-accessibility", version.ref="espresso" }
test-androidx-uiautomator = "androidx.test.uiautomator:uiautomator:2.2.0"
test-mockk-android = { module="io.mockk:mockk-android", version.ref="mockk" }
1 change: 1 addition & 0 deletions platforms/android/library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ dependencies {
androidTestImplementation libs.test.androidx.espresso
androidTestImplementation libs.test.androidx.espresso.accessibility
androidTestImplementation libs.test.mockk.android
androidTestImplementation libs.test.androidx.uiautomator
}

android.libraryVariants.all { variant ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.core.text.getSpans
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.setFailureHandler
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.action.ViewActions.pressKey
import androidx.test.espresso.action.ViewActions.replaceText
Expand Down Expand Up @@ -58,6 +60,13 @@ class EditorEditTextInputTests {
AccessibilityChecks.enable()
}

@Before
fun setUp() {
setFailureHandler(
ScreenshotFailureHandler(ApplicationProvider.getApplicationContext())
)
}

@After
fun cleanUp() {
// Finish composing just in case, to prevent clashes between test cases
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.element.android.wysiwyg.test.utils

import android.content.ContentValues
import android.content.Context
import android.graphics.Bitmap
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import androidx.test.espresso.FailureHandler
import androidx.test.espresso.base.DefaultFailureHandler
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import org.hamcrest.Matcher
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Calendar

class ScreenshotFailureHandler(appContext: Context) : FailureHandler {
private val defaultHandler: FailureHandler = DefaultFailureHandler(appContext)

override fun handle(error: Throwable, viewMatcher: Matcher<View>) {
getInstrumentation()
.uiAutomation
.takeScreenshot()
.save()

defaultHandler.handle(error, viewMatcher)
}
}

private fun Bitmap.save() {
val timestamp = timestamp()
val contentResolver = getInstrumentation().targetContext.applicationContext.contentResolver
try {
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "$timestamp.jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/UiTest")
}

val uri = contentResolver
.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
?: return

contentResolver.openOutputStream(uri)?.use { outputStream ->
compress(Bitmap.CompressFormat.PNG, 20, outputStream)
}

contentResolver.update(uri, contentValues, null, null)
} catch (e: IOException) {
e.printStackTrace()
}
}

private fun timestamp(): String =
SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().time)
23 changes: 23 additions & 0 deletions platforms/android/scripts/ci_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
./gradlew generateUnitTestCoverageReport $CI_GRADLE_ARG_PROPERTIES

# Don't exit immediately from UI test failure to collect screenshots
set +e

./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES

UI_TEST_EXIT_CODE=$?
if [ $UI_TEST_EXIT_CODE -ne 0 ]; then
echo "UI tests failed."
echo "Pulling screenshots from device..."
adb shell ls /sdcard/Pictures/UiTest/
mkdir build/reports/screenshots
adb pull /sdcard/Pictures/UiTest/ build/reports/screenshots/
exit $UI_TEST_EXIT_CODE
fi
set -e

./gradlew generateInstrumentationTestCoverageReport $CI_GRADLE_ARG_PROPERTIES

0 comments on commit 04b84f5

Please sign in to comment.