- Also reduced liklihood of timeouts on Firebase test lab for robo tests - Fix emulatorwtf run configuration - Fix screenshots on older API levels - Fix minumum range for emulator.wtf
This commit is contained in:
parent
adc774a20d
commit
1880b2a43f
|
@ -387,7 +387,7 @@ jobs:
|
|||
with:
|
||||
name: Release binaries
|
||||
- name: Robo test
|
||||
timeout-minutes: 15
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
# Path depends on `release_build` job, plus path of `Download a single artifact` step
|
||||
BINARIES_ZIP_PATH: binaries.zip
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="testDebugWithEmulatorWtf" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<configuration default="false" name="testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="scriptParameters" value="testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="testDebugWithEmulatorWtf" />
|
||||
</list>
|
||||
<list />
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
|
@ -101,6 +101,7 @@ android {
|
|||
listOf(
|
||||
"**/*.kotlin_metadata",
|
||||
".readme",
|
||||
"build-data.properties",
|
||||
"META-INF/*.kotlin_module",
|
||||
"META-INF/android.arch**",
|
||||
"META-INF/androidx**",
|
||||
|
@ -110,7 +111,6 @@ android {
|
|||
"META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor",
|
||||
"META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar",
|
||||
"META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages\$Extension",
|
||||
"build-data.properties",
|
||||
"firebase-**.properties",
|
||||
"kotlin/**",
|
||||
"play-services-**.properties",
|
||||
|
@ -206,27 +206,6 @@ if (googlePlayServiceKeyFilePath.isNotEmpty()) {
|
|||
}
|
||||
}
|
||||
|
||||
val reportsDirectory = "${buildDir}/reports/androidTests/connected"
|
||||
|
||||
// This is coordinated with `EccScreenCaptureProcessor`
|
||||
val onDeviceScreenshotsDirectory = "/sdcard/Pictures/zcash_screenshots"
|
||||
|
||||
val clearScreenshotsTask = tasks.create<Exec>("clearScreenshots") {
|
||||
executable = project.android.adbExecutable.absolutePath
|
||||
args = listOf("shell", "rm", "-r", onDeviceScreenshotsDirectory)
|
||||
}
|
||||
|
||||
val fetchScreenshotsTask = tasks.create<Exec>("fetchScreenshots") {
|
||||
executable = project.android.adbExecutable.absolutePath
|
||||
args = listOf("pull", onDeviceScreenshotsDirectory, reportsDirectory)
|
||||
finalizedBy(clearScreenshotsTask)
|
||||
}
|
||||
|
||||
tasks.whenTaskAdded {
|
||||
if (name == "connectedZcashmainnetDebugAndroidTest") {
|
||||
finalizedBy(fetchScreenshotsTask)
|
||||
}
|
||||
}
|
||||
|
||||
fladle {
|
||||
// Firebase Test Lab has min and max values that might differ from our project's
|
||||
|
@ -265,7 +244,7 @@ fladle {
|
|||
}
|
||||
)
|
||||
|
||||
testTimeout.set("5m")
|
||||
testTimeout.set("3m")
|
||||
|
||||
devices.addAll(
|
||||
mapOf("model" to "Pixel2", "version" to minSdkVersion),
|
||||
|
@ -278,13 +257,19 @@ fladle {
|
|||
}
|
||||
|
||||
emulatorwtf {
|
||||
// This path needs to be coordinated with the implementation in the app module's tests
|
||||
directoriesToPull.set(listOf("/sdcard/Pictures/zcash_screenshots"))
|
||||
directoriesToPull.set(listOf("/sdcard/googletest/test_outputfiles"))
|
||||
|
||||
val appMinSdkVersion = run {
|
||||
@Suppress("MagicNumber", "PropertyName", "VariableNaming")
|
||||
val EMULATOR_WTF_MIN_SDK = 23
|
||||
|
||||
val buildMinSdk = project.properties["ANDROID_APP_MIN_SDK_VERSION"].toString().toInt()
|
||||
buildMinSdk.coerceAtLeast(EMULATOR_WTF_MIN_SDK).toString()
|
||||
}
|
||||
|
||||
devices.set(
|
||||
listOf(
|
||||
// TODO [#285]: Our screenshot tests don't work on older devices
|
||||
// mapOf("model" to "Pixel2", "version" to minSdkVersion),
|
||||
mapOf("model" to "Pixel2", "version" to appMinSdkVersion),
|
||||
// TODO [#430]: App won't run on API 31 Intel emulators
|
||||
@Suppress("MagicNumber")
|
||||
mapOf("model" to "Pixel2", "version" to 30)
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="co.electriccoin.zcash.test">
|
||||
|
||||
<!-- Required to write screenshots -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<manifest package="co.electriccoin.zcash.app.test">
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package co.electriccoin.zcash.app
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.compose.ui.test.assertCountEquals
|
||||
import androidx.compose.ui.test.hasContentDescription
|
||||
import androidx.compose.ui.test.hasTestTag
|
||||
|
@ -18,16 +15,15 @@ import androidx.compose.ui.test.performClick
|
|||
import androidx.compose.ui.test.performScrollTo
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.core.graphics.writeToTestStorage
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
||||
import androidx.test.espresso.screenshot.captureToBitmap
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.filters.SdkSuppress
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import androidx.test.runner.screenshot.Screenshot
|
||||
import cash.z.ecc.sdk.ext.ui.model.MonetarySeparators
|
||||
import cash.z.ecc.sdk.fixture.SeedPhraseFixture
|
||||
import cash.z.ecc.sdk.fixture.WalletAddressFixture
|
||||
import co.electriccoin.zcash.app.test.EccScreenCaptureProcessor
|
||||
import co.electriccoin.zcash.app.test.getStringResource
|
||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||
import co.electriccoin.zcash.test.UiTestPrerequisites
|
||||
|
@ -39,44 +35,21 @@ import co.electriccoin.zcash.ui.screen.restore.RestoreTag
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
|
||||
// TODO [#285]: Screenshot tests fail on older devices due to issue granting external storage permission
|
||||
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
|
||||
class ScreenshotTest : UiTestPrerequisites() {
|
||||
|
||||
companion object {
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun setupPPlus() {
|
||||
if (Build.VERSION_CODES.P <= Build.VERSION.SDK_INT) {
|
||||
val instrumentation = InstrumentationRegistry.getInstrumentation()
|
||||
if (PackageManager.PERMISSION_DENIED == instrumentation.context.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
instrumentation.uiAutomation.grantRuntimePermission(instrumentation.context.packageName, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun takeScreenshot(screenshotName: String) {
|
||||
val screenshot = Screenshot.capture().apply {
|
||||
name = screenshotName
|
||||
}
|
||||
screenshot.process(setOf(EccScreenCaptureProcessor.new()))
|
||||
onView(isRoot())
|
||||
.captureToBitmap()
|
||||
.writeToTestStorage(screenshotName)
|
||||
}
|
||||
}
|
||||
|
||||
private val composeTestRule = createAndroidComposeRule(MainActivity::class.java)
|
||||
|
||||
@get:Rule
|
||||
val ruleChain = if (Build.VERSION_CODES.P <= Build.VERSION.SDK_INT) {
|
||||
composeTestRule
|
||||
} else {
|
||||
val runtimePermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
RuleChain.outerRule(runtimePermissionRule).around(composeTestRule)
|
||||
}
|
||||
val composeTestRule = createAndroidComposeRule(MainActivity::class.java)
|
||||
|
||||
private fun navigateTo(route: String) = runBlocking {
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
package co.electriccoin.zcash.app.test
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import androidx.test.runner.screenshot.ScreenCapture
|
||||
import androidx.test.runner.screenshot.ScreenCaptureProcessor
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.util.UUID
|
||||
|
||||
class EccScreenCaptureProcessor private constructor(private val screenshotDir: File) : ScreenCaptureProcessor {
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun process(capture: ScreenCapture): String {
|
||||
screenshotDir.checkDirectoryIsWriteable()
|
||||
|
||||
val filename = newFilename(
|
||||
name = capture.name ?: "",
|
||||
suffix = capture.format.toString().lowercase()
|
||||
)
|
||||
|
||||
BufferedOutputStream(FileOutputStream(File(screenshotDir, filename))).use {
|
||||
capture.bitmap.compress(capture.format, DEFAULT_QUALITY, it)
|
||||
it.flush()
|
||||
}
|
||||
|
||||
return filename
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_QUALITY = 100
|
||||
|
||||
fun new(): EccScreenCaptureProcessor {
|
||||
|
||||
// Screenshots need to be stored in a public directory so they won't get cleared by Test Orchestrator
|
||||
// This path must be coordinated with the build.gradle.kts script which copies these off the device
|
||||
@Suppress("DEPRECATION")
|
||||
val screenshotsDirectory = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "zcash_screenshots").also {
|
||||
it.mkdirs()
|
||||
}
|
||||
|
||||
return EccScreenCaptureProcessor(screenshotsDirectory)
|
||||
}
|
||||
|
||||
private fun newFilename(name: String, suffix: String) = "screenshot-$name-${Build.VERSION.SDK_INT}-${Build.DEVICE}-${UUID.randomUUID()}.$suffix"
|
||||
}
|
||||
}
|
||||
|
||||
private fun File.checkDirectoryIsWriteable() {
|
||||
if (!isDirectory && !canWrite()) {
|
||||
throw IOException("The directory $this does not exist or is not writable.")
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="co.electriccoin.zcash">
|
||||
package="co.electriccoin.zcash.app">
|
||||
|
||||
<application
|
||||
android:name=".app.ZcashApplication"
|
||||
android:name="co.electriccoin.zcash.app.ZcashApplication"
|
||||
android:allowBackup="false"
|
||||
android:label="@string/app_name">
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
|||
Using an alias ensures we can refactor the actual Activity without breaking
|
||||
clients. -->
|
||||
<activity-alias
|
||||
android:name=".LauncherActivity"
|
||||
android:name="co.electricoin.zcash.LauncherActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:targetActivity="co.electriccoin.zcash.ui.MainActivity">
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package co.electriccoin.zcash.app
|
||||
|
||||
import android.app.Application
|
||||
import co.electriccoin.zcash.BuildConfig
|
||||
import co.electriccoin.zcash.crash.android.CrashReporter
|
||||
import co.electriccoin.zcash.spackle.StrictModeCompat
|
||||
import co.electriccoin.zcash.spackle.Twig
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// These are determined by `ew-cli --models`
|
||||
|
||||
@Suppress("MagicNumber", "PropertyName", "VariableNaming")
|
||||
val EMULATOR_WTF_MIN_SDK = 24
|
||||
val EMULATOR_WTF_MIN_SDK = 23
|
||||
|
||||
@Suppress("MagicNumber", "PropertyName", "VariableNaming")
|
||||
val EMULATOR_WTF_MAX_SDK = 31
|
||||
|
|
|
@ -97,12 +97,11 @@ fladle {
|
|||
|
||||
filesToDownload.set(listOf(
|
||||
"*/matrix_*/*test_results_merged\\.xml",
|
||||
"*/matrix_*/*/artifacts/sdcard/Pictures/zcash_screenshots/*\\.png"
|
||||
"*/matrix_*/*/artifacts/sdcard/googletest/test_outputfiles/*\\.png"
|
||||
))
|
||||
|
||||
directoriesToPull.set(listOf(
|
||||
// This path needs to be coordinated with the implementation in the app module's tests
|
||||
"/sdcard/Pictures/zcash_screenshots"
|
||||
"/sdcard/googletest/test_outputfiles"
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ IS_SDK_INCLUDED_BUILD=false
|
|||
# A lower version on the libraries helps to ensure some degree of backwards compatiblity, for the project
|
||||
# as a whole. But a higher version on the app ensures that we aren't directly supporting users
|
||||
# with old devices.
|
||||
ANDROID_LIB_MIN_SDK_VERSION=23
|
||||
ANDROID_LIB_MIN_SDK_VERSION=24
|
||||
ANDROID_APP_MIN_SDK_VERSION=27
|
||||
ANDROID_TARGET_SDK_VERSION=31
|
||||
ANDROID_COMPILE_SDK_VERSION=31
|
||||
|
@ -91,14 +91,14 @@ ANDROIDX_COMPOSE_MATERIAL3_VERSION=1.0.0-alpha09
|
|||
ANDROIDX_COMPOSE_VERSION=1.1.1
|
||||
ANDROIDX_CONSTRAINTLAYOUT_VERSION=1.0.0
|
||||
ANDROIDX_CORE_VERSION=1.7.0
|
||||
ANDROIDX_ESPRESSO_VERSION=3.4.0
|
||||
ANDROIDX_ESPRESSO_VERSION=3.5.0-alpha07
|
||||
ANDROIDX_LIFECYCLE_VERSION=2.4.1
|
||||
ANDROIDX_NAVIGATION_COMPOSE_VERSION=2.4.2
|
||||
ANDROIDX_SECURITY_CRYPTO_VERSION=1.1.0-alpha03
|
||||
ANDROIDX_SPLASH_SCREEN_VERSION=1.0.0-rc01
|
||||
ANDROIDX_TEST_JUNIT_VERSION=1.1.3
|
||||
ANDROIDX_TEST_ORCHESTRATOR_VERSION=1.4.1
|
||||
ANDROIDX_TEST_CORE_VERSION=1.4.1-alpha06
|
||||
ANDROIDX_TEST_JUNIT_VERSION=1.1.4-alpha07
|
||||
ANDROIDX_TEST_ORCHESTRATOR_VERSION=1.4.2-alpha03
|
||||
ANDROIDX_TEST_CORE_VERSION=1.4.1-alpha07
|
||||
ANDROIDX_TEST_RUNNER_VERSION=1.5.0-alpha03
|
||||
ANDROIDX_UI_AUTOMATOR_VERSION=2.2.0-alpha1
|
||||
ANDROIDX_WORK_MANAGER_VERSION=2.7.1
|
||||
|
|
|
@ -199,8 +199,8 @@ dependencyResolutionManagement {
|
|||
//alias("androidx-espresso-contrib", "androidx.test.espresso:espresso-contrib:$androidxEspressoVersion")
|
||||
library("androidx-espresso-core", "androidx.test.espresso:espresso-core:$androidxEspressoVersion")
|
||||
library("androidx-espresso-intents", "androidx.test.espresso:espresso-intents:$androidxEspressoVersion")
|
||||
library("androidx-test-core", "androidx.test:core:$androidxTestCoreVersion")
|
||||
library("androidx-test-junit", "androidx.test.ext:junit:$androidxTestJunitVersion")
|
||||
library("androidx-test-core", "androidx.test:core-ktx:$androidxTestCoreVersion")
|
||||
library("androidx-test-junit", "androidx.test.ext:junit-ktx:$androidxTestJunitVersion")
|
||||
library("androidx-test-orchestrator", "androidx.test:orchestrator:$androidxTestOrchestratorVersion")
|
||||
library("androidx-test-runner", "androidx.test:runner:$androidxTestRunnerVersion")
|
||||
library("androidx-uiAutomator", "androidx.test.uiautomator:uiautomator-v18:$androidxUiAutomatorVersion")
|
||||
|
|
Loading…
Reference in New Issue