[#439] Take light/dark screenshots
Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
parent
b4bad94068
commit
020192b01e
|
@ -83,6 +83,10 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
getByName("debug").apply {
|
||||||
|
// Note that the build-conventions defines the res configs
|
||||||
|
isPseudoLocalesEnabled = true
|
||||||
|
}
|
||||||
getByName("release").apply {
|
getByName("release").apply {
|
||||||
isMinifyEnabled = project.property("IS_MINIFY_ENABLED").toString().toBoolean()
|
isMinifyEnabled = project.property("IS_MINIFY_ENABLED").toString().toBoolean()
|
||||||
isShrinkResources = project.property("IS_MINIFY_ENABLED").toString().toBoolean()
|
isShrinkResources = project.property("IS_MINIFY_ENABLED").toString().toBoolean()
|
||||||
|
@ -143,14 +147,14 @@ dependencies {
|
||||||
implementation(projects.spackleAndroidLib)
|
implementation(projects.spackleAndroidLib)
|
||||||
implementation(projects.uiLib)
|
implementation(projects.uiLib)
|
||||||
|
|
||||||
androidTestImplementation(projects.testLib)
|
|
||||||
androidTestImplementation(libs.androidx.compose.test.junit)
|
androidTestImplementation(libs.androidx.compose.test.junit)
|
||||||
androidTestImplementation(libs.androidx.navigation.compose)
|
androidTestImplementation(libs.androidx.navigation.compose)
|
||||||
androidTestImplementation(libs.androidx.uiAutomator)
|
androidTestImplementation(libs.androidx.uiAutomator)
|
||||||
androidTestImplementation(libs.bundles.androidx.test)
|
androidTestImplementation(libs.bundles.androidx.test)
|
||||||
androidTestImplementation(projects.sdkExtLib)
|
androidTestImplementation(projects.sdkExtLib)
|
||||||
androidTestImplementation(projects.spackleLib)
|
|
||||||
androidTestImplementation(projects.sdkExtUiLib)
|
androidTestImplementation(projects.sdkExtUiLib)
|
||||||
|
androidTestImplementation(projects.spackleLib)
|
||||||
|
androidTestImplementation(projects.testLib)
|
||||||
|
|
||||||
if (isOrchestratorEnabled) {
|
if (isOrchestratorEnabled) {
|
||||||
androidTestUtil(libs.androidx.test.orchestrator) {
|
androidTestUtil(libs.androidx.test.orchestrator) {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package co.electriccoin.zcash.app
|
package co.electriccoin.zcash.app
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.LocaleList
|
||||||
import androidx.compose.ui.test.assertCountEquals
|
import androidx.compose.ui.test.assertCountEquals
|
||||||
import androidx.compose.ui.test.hasContentDescription
|
import androidx.compose.ui.test.hasContentDescription
|
||||||
import androidx.compose.ui.test.hasTestTag
|
import androidx.compose.ui.test.hasTestTag
|
||||||
|
@ -20,15 +23,18 @@ import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
||||||
import androidx.test.espresso.screenshot.captureToBitmap
|
import androidx.test.espresso.screenshot.captureToBitmap
|
||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import androidx.test.filters.MediumTest
|
||||||
|
import androidx.test.filters.SdkSuppress
|
||||||
import cash.z.ecc.sdk.ext.ui.model.MonetarySeparators
|
import cash.z.ecc.sdk.ext.ui.model.MonetarySeparators
|
||||||
import cash.z.ecc.sdk.fixture.SeedPhraseFixture
|
import cash.z.ecc.sdk.fixture.SeedPhraseFixture
|
||||||
import cash.z.ecc.sdk.fixture.WalletAddressFixture
|
import cash.z.ecc.sdk.fixture.WalletAddressFixture
|
||||||
import co.electriccoin.zcash.app.test.getStringResource
|
|
||||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||||
import co.electriccoin.zcash.test.UiTestPrerequisites
|
import co.electriccoin.zcash.test.UiTestPrerequisites
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ConfigurationOverride
|
||||||
|
import co.electriccoin.zcash.ui.design.component.UiMode
|
||||||
import co.electriccoin.zcash.ui.screen.backup.BackupTag
|
import co.electriccoin.zcash.ui.screen.backup.BackupTag
|
||||||
import co.electriccoin.zcash.ui.screen.home.viewmodel.SecretState
|
import co.electriccoin.zcash.ui.screen.home.viewmodel.SecretState
|
||||||
import co.electriccoin.zcash.ui.screen.restore.RestoreTag
|
import co.electriccoin.zcash.ui.screen.restore.RestoreTag
|
||||||
|
@ -38,13 +44,34 @@ import kotlinx.coroutines.withContext
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This screenshot implementation does not change the system-wide configuration, but rather
|
||||||
|
* injects a Context with a modified Configuration to change the uiMode and Locale.
|
||||||
|
*
|
||||||
|
* This works by:
|
||||||
|
* 1. Main Activity wraps the Composable with an Override
|
||||||
|
* 2. Main Activity exposes a Flow where a ConfigurationOverride can be set
|
||||||
|
* 3. We use an altered resContext in the tests instead of Application Context in order to load
|
||||||
|
* the right resources for comparison.
|
||||||
|
*
|
||||||
|
* Benefits of this implementation are that we do not modify system-wide values and don't require
|
||||||
|
* additional permissions to run these tests.
|
||||||
|
*
|
||||||
|
* Limitations of this implementation are that any views outside of Compose will not be updated, which
|
||||||
|
* can include the on-screen keyboard, system dialogs (like permissions), or other UI elements.
|
||||||
|
*
|
||||||
|
* An alternative implementation would be to use AppCompatActivity as the parent class for MainActivity,
|
||||||
|
* then rely on the AppCompat APIs for changing uiMode and Locale. This doesn't bring much benefit over
|
||||||
|
* our approach (it still has the problem with system dialogs and the keyboard), and it requires that
|
||||||
|
* we pull in the appcompat library.
|
||||||
|
*/
|
||||||
class ScreenshotTest : UiTestPrerequisites() {
|
class ScreenshotTest : UiTestPrerequisites() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun takeScreenshot(screenshotName: String) {
|
fun takeScreenshot(tag: String, screenshotName: String) {
|
||||||
onView(isRoot())
|
onView(isRoot())
|
||||||
.captureToBitmap()
|
.captureToBitmap()
|
||||||
.writeToTestStorage(screenshotName)
|
.writeToTestStorage("$screenshotName - $tag")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +84,52 @@ class ScreenshotTest : UiTestPrerequisites() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun runWith(uiMode: UiMode, locale: String, action: (Context, String) -> Unit) {
|
||||||
|
val configurationOverride = ConfigurationOverride(uiMode, LocaleList.forLanguageTags(locale))
|
||||||
|
composeTestRule.activity.configurationOverrideFlow.value = configurationOverride
|
||||||
|
|
||||||
|
val applicationContext = ApplicationProvider.getApplicationContext<Context>()
|
||||||
|
val configuration = configurationOverride.newConfiguration(applicationContext.resources.configuration)
|
||||||
|
val resContext = applicationContext.createConfigurationContext(configuration)
|
||||||
|
|
||||||
|
action(resContext, "$uiMode-$locale")
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SmallTest
|
@MediumTest
|
||||||
fun take_screenshots_for_restore_wallet() {
|
fun take_screenshots_for_restore_wallet_light_en_XA() {
|
||||||
|
runWith(UiMode.Light, "en-XA") { context, tag ->
|
||||||
|
take_screenshots_for_restore_wallet(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@MediumTest
|
||||||
|
fun take_screenshots_for_restore_wallet_light_ar_XB() {
|
||||||
|
runWith(UiMode.Light, "ar-XB") { context, tag ->
|
||||||
|
take_screenshots_for_restore_wallet(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@MediumTest
|
||||||
|
fun take_screenshots_for_restore_wallet_light_en_US() {
|
||||||
|
runWith(UiMode.Light, "en-US") { context, tag ->
|
||||||
|
take_screenshots_for_restore_wallet(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dark mode was introduced in Android Q
|
||||||
|
@Test
|
||||||
|
@MediumTest
|
||||||
|
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
|
||||||
|
fun take_screenshots_for_restore_wallet_dark_en_US() {
|
||||||
|
runWith(UiMode.Dark, "en-US") { context, tag ->
|
||||||
|
take_screenshots_for_restore_wallet(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun take_screenshots_for_restore_wallet(resContext: Context, tag: String) {
|
||||||
// TODO [#286]: Screenshot tests fail on Firebase Test Lab
|
// TODO [#286]: Screenshot tests fail on Firebase Test Lab
|
||||||
if (FirebaseTestLabUtil.isFirebaseTestLab(ApplicationProvider.getApplicationContext())) {
|
if (FirebaseTestLabUtil.isFirebaseTestLab(ApplicationProvider.getApplicationContext())) {
|
||||||
return
|
return
|
||||||
|
@ -67,25 +137,25 @@ class ScreenshotTest : UiTestPrerequisites() {
|
||||||
|
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.None }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.None }
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_1_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_1_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_skip)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_skip)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_4_import_existing_wallet)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_4_import_existing_wallet)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.restore_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.restore_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
takeScreenshot("Import 1")
|
takeScreenshot(tag, "Import 1")
|
||||||
|
|
||||||
val seedPhraseSplitLength = SeedPhraseFixture.new().split.size
|
val seedPhraseSplitLength = SeedPhraseFixture.new().split.size
|
||||||
SeedPhraseFixture.new().split.forEachIndexed { index, string ->
|
SeedPhraseFixture.new().split.forEachIndexed { index, string ->
|
||||||
|
@ -94,199 +164,231 @@ class ScreenshotTest : UiTestPrerequisites() {
|
||||||
|
|
||||||
// Take a screenshot half-way through filling in the seed phrase
|
// Take a screenshot half-way through filling in the seed phrase
|
||||||
if (index == seedPhraseSplitLength / 2) {
|
if (index == seedPhraseSplitLength / 2) {
|
||||||
takeScreenshot("Import 2")
|
takeScreenshot(tag, "Import 2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.restore_complete_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.restore_complete_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
takeScreenshot("Import 3")
|
takeScreenshot(tag, "Import 3")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SmallTest
|
@LargeTest
|
||||||
fun take_screenshots_for_new_wallet_and_rest_of_app() {
|
fun take_screenshots_for_new_wallet_and_rest_of_app_light_en_XA() {
|
||||||
|
runWith(UiMode.Light, "en-XA") { context, tag ->
|
||||||
|
take_screenshots_for_new_wallet_and_rest_of_app(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@LargeTest
|
||||||
|
fun take_screenshots_for_new_wallet_and_rest_of_app_light_ar_XB() {
|
||||||
|
runWith(UiMode.Light, "ar-XB") { context, tag ->
|
||||||
|
take_screenshots_for_new_wallet_and_rest_of_app(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@LargeTest
|
||||||
|
fun take_screenshots_for_new_wallet_and_rest_of_app_light_en_US() {
|
||||||
|
runWith(UiMode.Light, "en-US") { context, tag ->
|
||||||
|
take_screenshots_for_new_wallet_and_rest_of_app(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dark mode was introduced in Android Q
|
||||||
|
@Test
|
||||||
|
@LargeTest
|
||||||
|
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
|
||||||
|
fun take_screenshots_for_new_wallet_and_rest_of_app_dark_en_US() {
|
||||||
|
runWith(UiMode.Dark, "en-US") { context, tag ->
|
||||||
|
take_screenshots_for_new_wallet_and_rest_of_app(context, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun take_screenshots_for_new_wallet_and_rest_of_app(resContext: Context, tag: String) {
|
||||||
// TODO [#286]: Screenshot tests fail on Firebase Test Lab
|
// TODO [#286]: Screenshot tests fail on Firebase Test Lab
|
||||||
if (FirebaseTestLabUtil.isFirebaseTestLab(ApplicationProvider.getApplicationContext())) {
|
if (FirebaseTestLabUtil.isFirebaseTestLab(ApplicationProvider.getApplicationContext())) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
onboardingScreenshots(composeTestRule)
|
onboardingScreenshots(resContext, tag, composeTestRule)
|
||||||
backupScreenshots(composeTestRule)
|
backupScreenshots(resContext, tag, composeTestRule)
|
||||||
homeScreenshots(composeTestRule)
|
homeScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
// Profile screen
|
// Profile screen
|
||||||
// navigateTo(MainActivity.NAV_PROFILE)
|
// navigateTo(MainActivity.NAV_PROFILE)
|
||||||
composeTestRule.onNode(hasContentDescription(getStringResource(R.string.home_profile_content_description))).also {
|
composeTestRule.onNode(hasContentDescription(resContext.getString(R.string.home_profile_content_description))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
profileScreenshots(composeTestRule)
|
profileScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
// Settings is a subscreen of profile
|
// Settings is a subscreen of profile
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.profile_settings))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.profile_settings))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
settingsScreenshots(composeTestRule)
|
settingsScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
// Back to profile
|
// Back to profile
|
||||||
composeTestRule.onNode(hasContentDescription(getStringResource(R.string.settings_back_content_description))).also {
|
composeTestRule.onNode(hasContentDescription(resContext.getString(R.string.settings_back_content_description))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address Details is a subscreen of profile
|
// Address Details is a subscreen of profile
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.profile_see_address_details))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.profile_see_address_details))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
addressDetailsScreenshots(composeTestRule)
|
addressDetailsScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
// Back to profile
|
// Back to profile
|
||||||
composeTestRule.onNode(hasContentDescription(getStringResource(R.string.wallet_address_back_content_description))).also {
|
composeTestRule.onNode(hasContentDescription(resContext.getString(R.string.wallet_address_back_content_description))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contact Support is a subscreen of profile
|
// Contact Support is a subscreen of profile
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.profile_support))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.profile_support))).also {
|
||||||
it.performScrollTo()
|
it.performScrollTo()
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
supportScreenshots(composeTestRule)
|
supportScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
// Back to profile
|
// Back to profile
|
||||||
composeTestRule.onNode(hasContentDescription(getStringResource(R.string.support_back_content_description))).also {
|
composeTestRule.onNode(hasContentDescription(resContext.getString(R.string.support_back_content_description))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.profile_title))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.profile_title))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
// About is a subscreen of profile
|
// About is a subscreen of profile
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.profile_about))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.profile_about))).also {
|
||||||
it.performScrollTo()
|
it.performScrollTo()
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
aboutScreenshots(composeTestRule)
|
aboutScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
// Back to profile
|
// Back to profile
|
||||||
composeTestRule.onNode(hasContentDescription(getStringResource(R.string.about_back_content_description))).also {
|
composeTestRule.onNode(hasContentDescription(resContext.getString(R.string.about_back_content_description))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back to home
|
// Back to home
|
||||||
composeTestRule.onNode(hasContentDescription(getStringResource(R.string.settings_back_content_description))).also {
|
composeTestRule.onNode(hasContentDescription(resContext.getString(R.string.settings_back_content_description))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.Ready }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.Ready }
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.home_button_request))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.home_button_request))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.walletSnapshot.value != null }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.walletSnapshot.value != null }
|
||||||
requestZecScreenshots(composeTestRule)
|
requestZecScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
navigateTo(MainActivity.NAV_HOME)
|
navigateTo(MainActivity.NAV_HOME)
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.Ready }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.Ready }
|
||||||
|
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.home_button_send))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.home_button_send))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.synchronizer.value != null }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.synchronizer.value != null }
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.spendingKey.value != null }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.spendingKey.value != null }
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.walletSnapshot.value != null }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.walletSnapshot.value != null }
|
||||||
sendZecScreenshots(composeTestRule)
|
sendZecScreenshots(resContext, tag, composeTestRule)
|
||||||
|
|
||||||
navigateTo(MainActivity.NAV_HOME)
|
navigateTo(MainActivity.NAV_HOME)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onboardingScreenshots(composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
private fun onboardingScreenshots(resContext: Context, tag: String, composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.None }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.None }
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_1_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_1_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
ScreenshotTest.takeScreenshot("Onboarding 1")
|
ScreenshotTest.takeScreenshot(tag, "Onboarding 1")
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_next)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_next)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_2_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_2_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
ScreenshotTest.takeScreenshot("Onboarding 2")
|
ScreenshotTest.takeScreenshot(tag, "Onboarding 2")
|
||||||
}
|
}
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_next)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_next)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_3_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_3_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
ScreenshotTest.takeScreenshot("Onboarding 3")
|
ScreenshotTest.takeScreenshot(tag, "Onboarding 3")
|
||||||
}
|
}
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_next)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_next)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_4_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_4_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
ScreenshotTest.takeScreenshot("Onboarding 4")
|
ScreenshotTest.takeScreenshot(tag, "Onboarding 4")
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.onboarding_4_create_new_wallet)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.onboarding_4_create_new_wallet)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun backupScreenshots(composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
private fun backupScreenshots(resContext: Context, tag: String, composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.NeedsBackup }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.NeedsBackup }
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_1_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_1_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
ScreenshotTest.takeScreenshot("Backup 1")
|
ScreenshotTest.takeScreenshot(tag, "Backup 1")
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_1_button)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_1_button)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_2_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_2_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
ScreenshotTest.takeScreenshot("Backup 2")
|
ScreenshotTest.takeScreenshot(tag, "Backup 2")
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_2_button)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_2_button)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_3_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_3_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
ScreenshotTest.takeScreenshot("Backup 3")
|
ScreenshotTest.takeScreenshot(tag, "Backup 3")
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_3_button_finished)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_3_button_finished)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_4_header_verify)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_4_header_verify)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
ScreenshotTest.takeScreenshot("Backup 4")
|
ScreenshotTest.takeScreenshot(tag, "Backup 4")
|
||||||
|
|
||||||
// Fail test first
|
// Fail test first
|
||||||
composeTestRule.onAllNodesWithTag(BackupTag.DROPDOWN_CHIP).also {
|
composeTestRule.onAllNodesWithTag(BackupTag.DROPDOWN_CHIP).also {
|
||||||
|
@ -302,21 +404,21 @@ private fun backupScreenshots(composeTestRule: AndroidComposeTestRule<ActivitySc
|
||||||
it[3].performClick()
|
it[3].performClick()
|
||||||
composeTestRule.onNode(hasTestTag(BackupTag.DROPDOWN_MENU)).onChildren()[3].performClick()
|
composeTestRule.onNode(hasTestTag(BackupTag.DROPDOWN_MENU)).onChildren()[3].performClick()
|
||||||
}
|
}
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_4_header_ouch)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_4_header_ouch)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
ScreenshotTest.takeScreenshot("Backup Fail")
|
ScreenshotTest.takeScreenshot(tag, "Backup Fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.new_wallet_4_button_retry))).performClick()
|
composeTestRule.onNode(hasText(resContext.getString(R.string.new_wallet_4_button_retry))).performClick()
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_3_header)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_3_header)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_3_button_finished)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_3_button_finished)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.new_wallet_4_header_verify)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.new_wallet_4_header_verify)).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,99 +438,99 @@ private fun backupScreenshots(composeTestRule: AndroidComposeTestRule<ActivitySc
|
||||||
composeTestRule.onNode(hasTestTag(BackupTag.DROPDOWN_MENU)).onChildren()[2].performClick()
|
composeTestRule.onNode(hasTestTag(BackupTag.DROPDOWN_MENU)).onChildren()[2].performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.new_wallet_5_body))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.new_wallet_5_body))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
ScreenshotTest.takeScreenshot("Backup 5")
|
ScreenshotTest.takeScreenshot(tag, "Backup 5")
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.new_wallet_5_button_finished))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.new_wallet_5_button_finished))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun homeScreenshots(composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
private fun homeScreenshots(resContext: Context, tag: String, composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.Ready }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.secretState.value is SecretState.Ready }
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.walletSnapshot.value != null }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.walletSnapshot.value != null }
|
||||||
|
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.home_button_send))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.home_button_send))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
ScreenshotTest.takeScreenshot("Home 1")
|
ScreenshotTest.takeScreenshot(tag, "Home 1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun profileScreenshots(composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
private fun profileScreenshots(resContext: Context, tag: String, composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>) {
|
||||||
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.addresses.value != null }
|
composeTestRule.waitUntil { composeTestRule.activity.walletViewModel.addresses.value != null }
|
||||||
|
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.profile_title))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.profile_title))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("Profile 1")
|
ScreenshotTest.takeScreenshot(tag, "Profile 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun settingsScreenshots(composeTestRule: ComposeTestRule) {
|
private fun settingsScreenshots(resContext: Context, tag: String, composeTestRule: ComposeTestRule) {
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.settings_header))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.settings_header))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("Settings 1")
|
ScreenshotTest.takeScreenshot(tag, "Settings 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addressDetailsScreenshots(composeTestRule: ComposeTestRule) {
|
private fun addressDetailsScreenshots(resContext: Context, tag: String, composeTestRule: ComposeTestRule) {
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.wallet_address_title))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.wallet_address_title))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("Addresses 1")
|
ScreenshotTest.takeScreenshot(tag, "Addresses 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requestZecScreenshots(composeTestRule: ComposeTestRule) {
|
private fun requestZecScreenshots(resContext: Context, tag: String, composeTestRule: ComposeTestRule) {
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.request_title))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.request_title))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("Request 1")
|
ScreenshotTest.takeScreenshot(tag, "Request 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendZecScreenshots(composeTestRule: ComposeTestRule) {
|
private fun sendZecScreenshots(resContext: Context, tag: String, composeTestRule: ComposeTestRule) {
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.send_title))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.send_title))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("Send 1")
|
ScreenshotTest.takeScreenshot(tag, "Send 1")
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.send_amount)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.send_amount)).also {
|
||||||
val separators = MonetarySeparators.current()
|
val separators = MonetarySeparators.current()
|
||||||
|
|
||||||
it.performTextInput("{${separators.decimal}}123")
|
it.performTextInput("{${separators.decimal}}123")
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.send_to)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.send_to)).also {
|
||||||
it.performTextInput(WalletAddressFixture.UNIFIED_ADDRESS_STRING)
|
it.performTextInput(WalletAddressFixture.UNIFIED_ADDRESS_STRING)
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(getStringResource(R.string.send_create)).also {
|
composeTestRule.onNodeWithText(resContext.getString(R.string.send_create)).also {
|
||||||
it.performClick()
|
it.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.waitForIdle()
|
composeTestRule.waitForIdle()
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("Send 2")
|
ScreenshotTest.takeScreenshot(tag, "Send 2")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun supportScreenshots(composeTestRule: ComposeTestRule) {
|
private fun supportScreenshots(resContext: Context, tag: String, composeTestRule: ComposeTestRule) {
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.support_header))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.support_header))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("Support 1")
|
ScreenshotTest.takeScreenshot(tag, "Support 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun aboutScreenshots(composeTestRule: ComposeTestRule) {
|
private fun aboutScreenshots(resContext: Context, tag: String, composeTestRule: ComposeTestRule) {
|
||||||
composeTestRule.onNode(hasText(getStringResource(R.string.about_title))).also {
|
composeTestRule.onNode(hasText(resContext.getString(R.string.about_title))).also {
|
||||||
it.assertExists()
|
it.assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTest.takeScreenshot("About 1")
|
ScreenshotTest.takeScreenshot(tag, "About 1")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
package co.electriccoin.zcash.app.test
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.test.core.app.ApplicationProvider
|
|
||||||
|
|
||||||
fun getStringResource(@StringRes resId: Int) = ApplicationProvider.getApplicationContext<Context>().getString(resId)
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package co.electriccoin.zcash.ui.design.component
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.os.LocaleList
|
||||||
|
import android.view.ContextThemeWrapper
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap a Composable with a way to override the Android Configuration. This is primarily useful
|
||||||
|
* for automated tests.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun Override(configurationOverrideFlow: StateFlow<ConfigurationOverride?>, content: @Composable () -> Unit) {
|
||||||
|
val configurationOverride = configurationOverrideFlow.collectAsState().value
|
||||||
|
|
||||||
|
if (null == configurationOverride) {
|
||||||
|
content()
|
||||||
|
} else {
|
||||||
|
val configuration = configurationOverride.newConfiguration(LocalConfiguration.current)
|
||||||
|
|
||||||
|
val contextWrapper = run {
|
||||||
|
val context = LocalContext.current
|
||||||
|
object : ContextThemeWrapper() {
|
||||||
|
init {
|
||||||
|
attachBaseContext(context)
|
||||||
|
applyOverrideConfiguration(configuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalConfiguration provides configuration,
|
||||||
|
LocalContext provides contextWrapper
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ConfigurationOverride(val uiMode: UiMode?, val locale: LocaleList?) {
|
||||||
|
fun newConfiguration(fromConfiguration: Configuration) = Configuration(fromConfiguration).apply {
|
||||||
|
this@ConfigurationOverride.uiMode?.let {
|
||||||
|
uiMode = (uiMode and Configuration.UI_MODE_NIGHT_MASK.inv()) or it.flag()
|
||||||
|
}
|
||||||
|
|
||||||
|
this@ConfigurationOverride.locale?.let {
|
||||||
|
setLocales(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class UiMode {
|
||||||
|
Light, Dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun UiMode.flag() = when (this) {
|
||||||
|
UiMode.Light -> Configuration.UI_MODE_NIGHT_NO
|
||||||
|
UiMode.Dark -> Configuration.UI_MODE_NIGHT_YES
|
||||||
|
}
|
|
@ -81,7 +81,7 @@ dependencies {
|
||||||
implementation(projects.sdkExtLib)
|
implementation(projects.sdkExtLib)
|
||||||
implementation(projects.sdkExtUiLib)
|
implementation(projects.sdkExtUiLib)
|
||||||
implementation(projects.spackleAndroidLib)
|
implementation(projects.spackleAndroidLib)
|
||||||
implementation(projects.uiDesignLib)
|
api(projects.uiDesignLib)
|
||||||
|
|
||||||
androidTestImplementation(projects.testLib)
|
androidTestImplementation(projects.testLib)
|
||||||
androidTestImplementation(libs.bundles.androidx.test)
|
androidTestImplementation(libs.bundles.androidx.test)
|
||||||
|
|
|
@ -33,7 +33,9 @@ import cash.z.ecc.sdk.type.fromResources
|
||||||
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
||||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||||
import co.electriccoin.zcash.ui.design.compat.FontCompat
|
import co.electriccoin.zcash.ui.design.compat.FontCompat
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ConfigurationOverride
|
||||||
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
||||||
|
import co.electriccoin.zcash.ui.design.component.Override
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.screen.about.WrapAbout
|
import co.electriccoin.zcash.ui.screen.about.WrapAbout
|
||||||
import co.electriccoin.zcash.ui.screen.backup.WrapBackup
|
import co.electriccoin.zcash.ui.screen.backup.WrapBackup
|
||||||
|
@ -59,6 +61,7 @@ import co.electriccoin.zcash.ui.screen.update.AppUpdateCheckerImp
|
||||||
import co.electriccoin.zcash.ui.screen.update.WrapUpdate
|
import co.electriccoin.zcash.ui.screen.update.WrapUpdate
|
||||||
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
|
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
|
||||||
import co.electriccoin.zcash.ui.screen.wallet_address.view.WalletAddresses
|
import co.electriccoin.zcash.ui.screen.wallet_address.view.WalletAddresses
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
@ -84,6 +87,9 @@ class MainActivity : ComponentActivity() {
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||||
lateinit var navControllerForTesting: NavHostController
|
lateinit var navControllerForTesting: NavHostController
|
||||||
|
|
||||||
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
|
val configurationOverrideFlow = MutableStateFlow<ConfigurationOverride?>(null)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
@ -120,25 +126,27 @@ class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
private fun setupUiContent() {
|
private fun setupUiContent() {
|
||||||
setContent {
|
setContent {
|
||||||
ZcashTheme {
|
Override(configurationOverrideFlow) {
|
||||||
GradientSurface(
|
ZcashTheme {
|
||||||
Modifier
|
GradientSurface(
|
||||||
.fillMaxWidth()
|
Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxWidth()
|
||||||
) {
|
.fillMaxHeight()
|
||||||
when (val secretState = walletViewModel.secretState.collectAsState().value) {
|
) {
|
||||||
SecretState.Loading -> {
|
when (val secretState = walletViewModel.secretState.collectAsState().value) {
|
||||||
// For now, keep displaying splash screen using condition above.
|
SecretState.Loading -> {
|
||||||
// In the future, we might consider displaying something different here.
|
// For now, keep displaying splash screen using condition above.
|
||||||
|
// In the future, we might consider displaying something different here.
|
||||||
|
}
|
||||||
|
SecretState.None -> {
|
||||||
|
WrapOnboarding()
|
||||||
|
}
|
||||||
|
is SecretState.NeedsBackup -> WrapBackup(
|
||||||
|
secretState.persistableWallet,
|
||||||
|
onBackupComplete = { walletViewModel.persistBackupComplete() }
|
||||||
|
)
|
||||||
|
is SecretState.Ready -> Navigation()
|
||||||
}
|
}
|
||||||
SecretState.None -> {
|
|
||||||
WrapOnboarding()
|
|
||||||
}
|
|
||||||
is SecretState.NeedsBackup -> WrapBackup(
|
|
||||||
secretState.persistableWallet,
|
|
||||||
onBackupComplete = { walletViewModel.persistBackupComplete() }
|
|
||||||
)
|
|
||||||
is SecretState.Ready -> Navigation()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
<style name="Theme.App.Starting" parent="Theme.SplashScreen">
|
<style name="Theme.App.Starting" parent="Theme.SplashScreen">
|
||||||
<item name="windowSplashScreenBackground">@color/splash_screen_background</item>
|
<item name="windowSplashScreenBackground">@color/splash_screen_background</item>
|
||||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher_adaptive_foreground</item>
|
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher_adaptive_foreground</item>
|
||||||
<item name="postSplashScreenTheme">@style/Theme.AppCompat.DayNight</item>
|
<item name="postSplashScreenTheme">@style/Theme.AppCompat.DayNight.NoActionBar</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue