Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-23 12:06:26 +03:00
parent 12e53a3aa3
commit 315d7c9d6c
25 changed files with 482 additions and 321 deletions

View file

@ -71,6 +71,10 @@ configurations.all {
}
}
configurations.androidTestImplementation {
exclude(module = "protobuf-lite")
}
dependencies {
implementation(projects.domain.legacy)
@ -317,19 +321,13 @@ dependencies {
testImplementation(deps.test.mockk)
testImplementation(deps.test.truth)
androidTestImplementation(deps.test.junit.android)
androidTestImplementation(deps.test.espresso){
exclude(group = "com.google.protobuf", module = "protobuf-lite") //conflicting with firebasePerf
}
androidTestImplementation(deps.test.espresso)
androidTestImplementation(deps.test.espresso.intents)
{
exclude(group = "com.google.protobuf", module = "protobuf-lite") //conflicting with firebasePerf
}
androidTestImplementation(deps.test.kaspresso)
androidTestImplementation(deps.test.kaspresso.compose)
androidTestImplementation(deps.test.compose.junit)
androidTestImplementation(deps.test.hamcrest)
androidTestImplementation(deps.test.hilt)
androidTestImplementation(deps.test.ultron.android)
androidTestImplementation(deps.test.ultron.compose)
androidTestImplementation(deps.test.ultron.allure)
kaptAndroidTest(deps.test.hilt.compiler)
/** Chucker */

View file

@ -1,66 +1,77 @@
package com.tangem.common
import android.Manifest
import android.content.Context
import android.util.Log
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.datastore.dataStoreFile
import androidx.test.espresso.intent.Intents
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import com.atiurin.ultron.core.compose.config.UltronComposeConfig
import com.atiurin.ultron.core.compose.createUltronComposeRule
import com.atiurin.ultron.core.compose.listeners.ComposDebugListener
import com.atiurin.ultron.core.config.UltronCommonConfig
import com.atiurin.ultron.core.config.UltronConfig
import com.atiurin.ultron.core.test.UltronTest
import com.kaspersky.components.composesupport.config.withComposeSupport
import com.kaspersky.kaspresso.kaspresso.Kaspresso
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.tap.MainActivity
import dagger.hilt.android.testing.HiltAndroidRule
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.junit.BeforeClass
import org.junit.Rule
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.RunWith
import javax.inject.Inject
abstract class BaseTestCase : UltronTest() {
abstract class BaseTestCase : TestCase(
kaspressoBuilder = Kaspresso.Builder.withComposeSupport()
) {
@Inject
lateinit var tangemSdkManager: TangemSdkManager
@Inject
lateinit var appPreferencesStore: AppPreferencesStore
@get:Rule(order = 0)
val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(
private val hiltRule = HiltAndroidRule(this)
private val permissionRule = GrantPermissionRule.grant(
Manifest.permission.POST_NOTIFICATIONS,
Manifest.permission.CAMERA
Manifest.permission.CAMERA,
)
@get:Rule(order = 1)
val hiltRule = HiltAndroidRule(this)
val composeTestRule = createAndroidComposeRule<MainActivity>()
@get:Rule (order = 2)
val injectionRule = ApplicationInjectionExecutionRule()
@Rule
@JvmField
val ruleChain: TestRule = RuleChain
.outerRule(hiltRule)
.around(ApplicationInjectionExecutionRule())
.around(permissionRule)
.around(composeTestRule)
@get:Rule(order = 3)
val composeRule = createUltronComposeRule<MainActivity>()
override val beforeTest: () -> Unit = {
protected fun setupHooks(
additionalBeforeSection: () -> Unit = {},
additionalAfterSection: () -> Unit = {},
) = before {
hiltRule.inject()
Intents.init()
additionalBeforeSection()
runBlocking {
delay(INIT_DELAY)
}
}
override val afterTest: () -> Unit = {
}.after {
runBlocking {
appPreferencesStore.editData { prefs -> prefs.clear() }
}
additionalAfterSection()
Intents.release()
}
companion object {
@BeforeClass
@JvmStatic
fun config() {
UltronConfig.applyRecommended()
UltronComposeConfig.applyRecommended()
UltronCommonConfig.addListener(ComposDebugListener())
}
private const val INIT_DELAY = 2000L
private const val INIT_DELAY = 1000L
}
}

View file

@ -0,0 +1,8 @@
package com.tangem.common.extensions
import io.github.kakaocup.compose.node.element.KNode
fun KNode.clickWithAssertion() {
assertIsDisplayed()
performClick()
}

View file

@ -1,9 +0,0 @@
package com.tangem.common.extensions
import androidx.test.platform.app.InstrumentationRegistry
object TestDataUtils {
fun getResourceString(resourceId: Int): String {
return InstrumentationRegistry.getInstrumentation().targetContext.resources.getString(resourceId)
}
}

View file

@ -1,27 +0,0 @@
package com.tangem.scenarios
import com.atiurin.ultron.allure.step.step
import com.atiurin.ultron.extensions.assertIsDisplayed
import com.atiurin.ultron.extensions.click
import com.tangem.domain.models.scan.ProductType
import com.tangem.screens.DisclaimerPage
import com.tangem.screens.MainPage
import com.tangem.screens.StoriesPage
import com.tangem.tap.domain.sdk.mocks.MockProvider
object MainPageScenario {
fun open(productType: ProductType? = null) {
if (productType != null) {
MockProvider.setMocks(productType)
}
step("Click on \"Accept\" button") {
DisclaimerPage.acceptButton.click()
}
step("Click on \"Scan\" button emulating scan error") {
StoriesPage.scanButton.click()
}
step("Assert: main is displayed") {
MainPage.container.assertIsDisplayed()
}
}
}

View file

@ -0,0 +1,44 @@
package com.tangem.scenarios
import androidx.compose.ui.test.junit4.ComposeTestRule
import com.kaspersky.kaspresso.testcases.api.scenario.Scenario
import com.kaspersky.kaspresso.testcases.core.testcontext.TestContext
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.domain.models.scan.ProductType
import com.tangem.screens.DisclaimerTestScreen
import com.tangem.screens.MainTestScreen
import com.tangem.screens.StoriesTestScreen
import com.tangem.screens.TestTopBar
import com.tangem.tap.domain.sdk.mocks.MockProvider
import io.github.kakaocup.compose.node.element.ComposeScreen
class OpenMainScreenScenario(
private val testRule: ComposeTestRule,
private val productType: ProductType? = null,
) : Scenario() {
override val steps: TestContext<Unit>.() -> Unit = {
if (productType != null) {
MockProvider.setMocks(productType)
}
ComposeScreen.onComposeScreen<DisclaimerTestScreen>(testRule) {
step("Click on \"Accept\" button") {
acceptButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<StoriesTestScreen>(testRule) {
step("Click on \"Scan\" button") {
scanButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<MainTestScreen>(testRule) {
step("Make sure wallet screen is visible") {
assertIsDisplayed()
}
}
ComposeScreen.onComposeScreen<TestTopBar>(testRule) {
step("Close Markets tooltip"){
performClick()
}
}
}
}

View file

@ -1,16 +0,0 @@
package com.tangem.screens
import androidx.compose.ui.test.hasText
import com.atiurin.ultron.page.Page
import com.tangem.common.extensions.TestDataUtils.getResourceString
import com.tangem.wallet.R
object DetailsPage : Page<DetailsPage>() {
val walletConnectButton = hasText(getResourceString(R.string.wallet_connect_title))
val walletNameButton = hasText(getResourceString(R.string.manage_tokens_network_selector_wallet))
val scanCardButton = hasText(getResourceString(R.string.scan_card_settings_button))
val buyTangemButton = hasText(getResourceString(R.string.details_buy_wallet))
val appSettingsButton = hasText(getResourceString(R.string.app_settings_title))
val contactSupportButton = hasText(getResourceString(R.string.details_row_title_contact_to_support))
val toSButton = hasText(getResourceString(R.string.disclaimer_title))
}

View file

@ -0,0 +1,51 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.core.ui.test.TestTags
import com.tangem.wallet.R
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
class DetailsTestScreen(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<DetailsTestScreen>(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(TestTags.DETAILS_SCREEN) }
) {
val walletConnectButton: KNode = child {
hasTestTag(TestTags.DETAILS_SCREEN_ITEM)
hasText(getResourceString(R.string.wallet_connect_title))
}
private val walletBlock: KNode = child {
hasTestTag(TestTags.DETAILS_SCREEN_ITEM)
}
val walletNameButton: KNode = walletBlock.child {
hasClickAction()
hasPosition(0)
}
val scanCardButton: KNode = walletBlock.child {
hasText(getResourceString(R.string.scan_card_settings_button))
}
val buyTangemButton: KNode = child {
hasTestTag(TestTags.DETAILS_SCREEN_ITEM)
hasText(getResourceString(R.string.details_buy_wallet))
}
val appSettingsButton: KNode = child {
hasTestTag(TestTags.DETAILS_SCREEN_ITEM)
hasText(getResourceString(R.string.app_settings_title))
}
val contactSupportButton: KNode = child {
hasTestTag(TestTags.DETAILS_SCREEN_ITEM)
hasText(getResourceString(R.string.details_row_title_contact_to_support))
}
val toSButton: KNode = child {
hasTestTag(TestTags.DETAILS_SCREEN_ITEM)
hasText(getResourceString(R.string.disclaimer_title))
}
}

View file

@ -1,9 +0,0 @@
package com.tangem.screens
import androidx.compose.ui.test.hasTestTag
import com.atiurin.ultron.page.Page
import com.tangem.core.ui.test.TestTags
object DisclaimerPage : Page<DisclaimerPage>() {
val acceptButton = hasTestTag(TestTags.DISCLAIMER_SCREEN_ACCEPT_BUTTON)
}

View file

@ -0,0 +1,17 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.core.ui.test.TestTags
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.KNode
class DisclaimerTestScreen(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<DisclaimerTestScreen>(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(TestTags.DISCLAIMER_SCREEN_CONTAINER) }
) {
val acceptButton: KNode = child {
hasTestTag(TestTags.DISCLAIMER_SCREEN_ACCEPT_BUTTON)
}
}

View file

@ -1,9 +0,0 @@
package com.tangem.screens
import androidx.compose.ui.test.hasTestTag
import com.atiurin.ultron.page.Page
import com.tangem.core.ui.test.TestTags
object MainPage : Page<MainPage>() {
val container = hasTestTag(TestTags.MAIN_SCREEN)
}

View file

@ -0,0 +1,11 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.core.ui.test.TestTags
import io.github.kakaocup.compose.node.element.ComposeScreen
class MainTestScreen(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<MainTestScreen>(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(TestTags.MAIN_SCREEN) }
)

View file

@ -1,10 +0,0 @@
package com.tangem.screens
import androidx.compose.ui.test.hasTestTag
import com.atiurin.ultron.page.Page
import com.tangem.core.ui.test.TestTags
object StoriesPage : Page<StoriesPage>() {
val scanButton = hasTestTag(TestTags.STORIES_SCREEN_SCAN_BUTTON)
val orderButton = hasTestTag(TestTags.STORIES_SCREEN_ORDER_BUTTON)
}

View file

@ -0,0 +1,32 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.core.ui.test.TestTags
import com.tangem.wallet.R
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.views.KView
import io.github.kakaocup.kakao.text.KButton
class StoriesTestScreen(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<StoriesTestScreen>(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(TestTags.STORIES_SCREEN) }
) {
val scanButton: KNode = child {
hasTestTag(TestTags.STORIES_SCREEN_SCAN_BUTTON)
}
val orderButton: KNode = child {
hasTestTag(TestTags.STORIES_SCREEN_ORDER_BUTTON)
}
val enableNFCAlert: KView = KView {
withId(R.id.alertTitle)
}
val cancelButton: KButton = KButton {
withId(android.R.id.button2)
}
}

View file

@ -0,0 +1,16 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.core.ui.test.TestTags
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.KNode
class TestTopBar(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<TestTopBar>(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(TestTags.MAIN_SCREEN_TOP_BAR) }
) {
val moreButton: KNode = child {
hasTestTag(TestTags.MAIN_SCREEN_MORE_BUTTON)
}
}

View file

@ -1,9 +0,0 @@
package com.tangem.screens
import androidx.compose.ui.test.hasTestTag
import com.atiurin.ultron.page.Page
import com.tangem.core.ui.test.TestTags
object TopBarPage : Page<TopBarPage>() {
val moreButton = hasTestTag(TestTags.MAIN_SCREEN_MORE_BUTTON)
}

View file

@ -1,13 +0,0 @@
package com.tangem.screens
import androidx.compose.ui.test.hasText
import com.atiurin.ultron.page.Page
import com.tangem.common.extensions.TestDataUtils.getResourceString
import com.tangem.wallet.R
object WalletSettingsPage : Page<WalletSettingsPage>() {
val linkMoreCardsButton = hasText(getResourceString(R.string.details_row_title_create_backup))
val cardSettingsButton = hasText(getResourceString(R.string.card_settings_title))
val referralProgramButton = hasText(getResourceString(R.string.details_referral_title))
val forgetWalletButton = hasText(getResourceString(R.string.settings_forget_wallet))
}

View file

@ -0,0 +1,31 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.core.ui.test.TestTags
import com.tangem.wallet.R
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
class WalletSettingsTestScreen(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<WalletSettingsTestScreen>(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(TestTags.WALLET_SETTINGS_SCREEN) }
) {
private val walletSettingsItem: KNode = child {
hasTestTag(TestTags.WALLET_SETTINGS_SCREEN_ITEM)
}
val linkMoreCardsButton: KNode = walletSettingsItem.child {
hasText(getResourceString(R.string.details_row_title_create_backup))
}
val cardSettingsButton: KNode = walletSettingsItem.child {
hasText(getResourceString(R.string.card_settings_title))
}
val referralProgramButton: KNode = walletSettingsItem.child {
hasText(getResourceString(R.string.details_referral_title))
}
val forgetWalletButton: KNode = walletSettingsItem.child {
hasText(getResourceString(R.string.settings_forget_wallet))
}
}

View file

@ -1,138 +1,157 @@
package com.tangem.tests
import com.atiurin.ultron.allure.step.step
import com.atiurin.ultron.extensions.assertIsDisplayed
import com.atiurin.ultron.extensions.assertIsNotDisplayed
import com.atiurin.ultron.extensions.click
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.domain.models.scan.ProductType
import com.tangem.scenarios.MainPageScenario
import com.tangem.screens.DetailsPage
import com.tangem.screens.TopBarPage
import com.tangem.screens.WalletSettingsPage
import com.tangem.scenarios.OpenMainScreenScenario
import com.tangem.screens.DetailsTestScreen
import com.tangem.screens.TestTopBar
import com.tangem.screens.WalletSettingsTestScreen
import dagger.hilt.android.testing.HiltAndroidTest
import io.github.kakaocup.compose.node.element.ComposeScreen
import org.junit.Test
@HiltAndroidTest
class DetailsScreenTest : BaseTestCase() {
@Test
fun walletWithoutBackupDetails() {
MainPageScenario.open()
step("Open wallet details") {
TopBarPage.moreButton.click()
fun walletWithoutBackupDetails() =
setupHooks().run {
scenario(OpenMainScreenScenario(composeTestRule))
ComposeScreen.onComposeScreen<TestTopBar>(composeTestRule) {
step("Open wallet details") {
moreButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<DetailsTestScreen>(composeTestRule) {
step("Assert wallet connect button is visible") {
walletConnectButton.assertIsDisplayed()
}
step("Assert scan card button is visible") {
scanCardButton.assertIsDisplayed()
}
step("Assert buy Tangem card button is visible") {
buyTangemButton.assertIsDisplayed()
}
step("Assert app settings button is visible") {
appSettingsButton.assertIsDisplayed()
}
step("Assert contact support button is visible") {
contactSupportButton.assertIsDisplayed()
}
step("Assert terms or service button is visible") {
toSButton.assertIsDisplayed()
}
step("Open wallet settings screen") {
walletNameButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<WalletSettingsTestScreen>(composeTestRule) {
step("Assert Link more cards button is visible") {
linkMoreCardsButton.assertIsDisplayed()
}
step("Assert Card Settings button is visible") {
cardSettingsButton.assertIsDisplayed()
}
step("Assert Referral program button is visible") {
referralProgramButton.assertIsDisplayed()
}
step("Assert Forget wallet button is visible") {
forgetWalletButton.assertIsDisplayed()
}
}
}
step("Assert wallet connect button is visible") {
DetailsPage.walletConnectButton.assertIsDisplayed()
}
step("Assert scan card button is visible") {
DetailsPage.scanCardButton.assertIsDisplayed()
}
step("Assert buy Tangem card button is visible") {
DetailsPage.buyTangemButton.assertIsDisplayed()
}
step("Assert app settings button is visible") {
DetailsPage.appSettingsButton.assertIsDisplayed()
}
step("Assert contact support button is visible") {
DetailsPage.contactSupportButton.assertIsDisplayed()
}
step("Assert terms or service button is visible") {
DetailsPage.toSButton.assertIsDisplayed()
}
step("Open wallet settings screen") {
DetailsPage.walletNameButton.click()
}
step("Assert Link more cards button is visible") {
WalletSettingsPage.linkMoreCardsButton.assertIsDisplayed()
}
step("Assert Card Settings button is visible") {
WalletSettingsPage.cardSettingsButton.assertIsDisplayed()
}
step("Assert Referral program button is visible") {
WalletSettingsPage.referralProgramButton.assertIsDisplayed()
}
step("Assert Forget wallet button is visible") {
WalletSettingsPage.forgetWalletButton.assertIsDisplayed()
}
}
@Test
fun wallet2Details() {
MainPageScenario.open(ProductType.Wallet2)
step("Open wallet details") {
TopBarPage.moreButton.click()
fun wallet2Details() =
setupHooks().run {
scenario(OpenMainScreenScenario(composeTestRule, ProductType.Wallet2))
ComposeScreen.onComposeScreen<TestTopBar>(composeTestRule) {
step("Open wallet details") {
moreButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<DetailsTestScreen>(composeTestRule) {
step("Assert wallet connect button is visible") {
walletConnectButton.assertIsDisplayed()
}
step("Assert scan card button is visible") {
scanCardButton.assertIsDisplayed()
}
step("Assert buy Tangem card button is visible") {
buyTangemButton.assertIsDisplayed()
}
step("Assert app settings button is visible") {
appSettingsButton.assertIsDisplayed()
}
step("Assert contact support button is visible") {
contactSupportButton.assertIsDisplayed()
}
step("Assert terms or service button is visible") {
toSButton.assertIsDisplayed()
}
step("Open wallet settings screen") {
walletNameButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<WalletSettingsTestScreen>(composeTestRule) {
step("Assert Link more cards button does not exist") {
linkMoreCardsButton.assertIsNotDisplayed()
}
step("Assert Card Settings button is visible") {
cardSettingsButton.assertIsDisplayed()
}
step("Assert Referral program button is visible") {
referralProgramButton.assertIsDisplayed()
}
step("Assert Forget wallet button is visible") {
forgetWalletButton.assertIsDisplayed()
}
}
}
step("Assert wallet connect button is visible") {
DetailsPage.walletConnectButton.assertIsDisplayed()
}
step("Assert scan card button is visible") {
DetailsPage.scanCardButton.assertIsDisplayed()
}
step("Assert buy Tangem card button is visible") {
DetailsPage.buyTangemButton.assertIsDisplayed()
}
step("Assert app settings button is visible") {
DetailsPage.appSettingsButton.assertIsDisplayed()
}
step("Assert contact support button is visible") {
DetailsPage.contactSupportButton.assertIsDisplayed()
}
step("Assert terms or service button is visible") {
DetailsPage.toSButton.assertIsDisplayed()
}
step("Open wallet settings screen") {
DetailsPage.walletNameButton.click()
}
step("Assert Link more cards button does not exist") {
WalletSettingsPage.linkMoreCardsButton.assertIsNotDisplayed()
}
step("Assert Card Settings button is visible") {
WalletSettingsPage.cardSettingsButton.assertIsDisplayed()
}
step("Assert Referral program button is visible") {
WalletSettingsPage.referralProgramButton.assertIsDisplayed()
}
step("Assert Forget wallet button is visible") {
WalletSettingsPage.forgetWalletButton.assertIsDisplayed()
}
}
@Test
fun noteDetails() {
MainPageScenario.open(ProductType.Note)
step("Open wallet details") {
TopBarPage.moreButton.click()
fun noteDetails() =
setupHooks().run {
scenario(OpenMainScreenScenario(composeTestRule, ProductType.Note))
ComposeScreen.onComposeScreen<TestTopBar>(composeTestRule) {
step("Open wallet details") {
moreButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<DetailsTestScreen>(composeTestRule) {
step("Assert wallet connect button does not exist") {
walletConnectButton.assertIsNotDisplayed()
}
step("Assert scan card button is visible") {
scanCardButton.assertIsDisplayed()
}
step("Assert buy Tangem card button is visible") {
buyTangemButton.assertIsDisplayed()
}
step("Assert app settings button is visible") {
appSettingsButton.assertIsDisplayed()
}
step("Assert contact support button is visible") {
contactSupportButton.assertIsDisplayed()
}
step("Assert terms or service button is visible") {
toSButton.assertIsDisplayed()
}
step("Open wallet settings screen") {
walletNameButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<WalletSettingsTestScreen>(composeTestRule) {
step("Assert Card Settings button is visible") {
cardSettingsButton.assertIsDisplayed()
}
step("Assert Referral program button does not exist") {
referralProgramButton.assertIsNotDisplayed()
}
step("Assert Forget wallet button is visible") {
forgetWalletButton.assertIsDisplayed()
}
}
}
step("Assert wallet connect button does not exist") {
DetailsPage.walletConnectButton.assertIsNotDisplayed()
}
step("Assert scan card button is visible") {
DetailsPage.scanCardButton.assertIsDisplayed()
}
step("Assert buy Tangem card button is visible") {
DetailsPage.buyTangemButton.assertIsDisplayed()
}
step("Assert app settings button is visible") {
DetailsPage.appSettingsButton.assertIsDisplayed()
}
step("Assert contact support button is visible") {
DetailsPage.contactSupportButton.assertIsDisplayed()
}
step("Assert terms or service button is visible") {
DetailsPage.toSButton.assertIsDisplayed()
}
step("Open wallet settings screen") {
DetailsPage.walletNameButton.click()
}
step("Assert Card Settings button is visible") {
WalletSettingsPage.cardSettingsButton.assertIsDisplayed()
}
step("Assert Referral program button does not exist") {
WalletSettingsPage.referralProgramButton.assertIsNotDisplayed()
}
step("Assert Forget wallet button is visible") {
WalletSettingsPage.forgetWalletButton.assertIsDisplayed()
}
}
}
}

View file

@ -0,0 +1,21 @@
package com.tangem.tests
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import com.tangem.common.BaseTestCase
import com.tangem.scenarios.OpenMainScreenScenario
import com.tangem.tap.MainActivity
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Rule
import org.junit.Test
@HiltAndroidTest
class MainScreenTest : BaseTestCase() {
@Test
fun goToMain() {
setupHooks().run {
scenario(OpenMainScreenScenario(composeTestRule))
}
}
}

View file

@ -1,42 +1,40 @@
package com.tangem.tests
import com.atiurin.ultron.allure.step.step
import com.atiurin.ultron.extensions.assertIsDisplayed
import com.atiurin.ultron.extensions.assertIsNotDisplayed
import com.atiurin.ultron.extensions.click
import com.tangem.common.BaseTestCase
import com.tangem.screens.DisclaimerPage
import com.tangem.screens.MainPage
import com.tangem.screens.StoriesPage
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.screens.DisclaimerTestScreen
import com.tangem.screens.MainTestScreen
import com.tangem.screens.StoriesTestScreen
import com.tangem.tap.domain.sdk.mocks.MockProvider
import dagger.hilt.android.testing.HiltAndroidTest
import io.github.kakaocup.compose.node.element.ComposeScreen
import org.junit.Test
@HiltAndroidTest
class ScanErrorTest : BaseTestCase() {
@Test
fun goToMain() {
step("Click on \"Accept\" button") {
DisclaimerPage.acceptButton.click()
fun goToMain() =
setupHooks().run {
ComposeScreen.onComposeScreen<DisclaimerTestScreen>(composeTestRule) {
step("Click on \"Accept\" button") {
acceptButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<StoriesTestScreen>(composeTestRule) {
step("Click on \"Scan\" button emulating scan error") {
MockProvider.setEmulateError()
scanButton.clickWithAssertion()
}
step("Click on \"Scan\" button again without emulating error") {
MockProvider.resetEmulateError()
scanButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<MainTestScreen>(composeTestRule) {
step("Make sure wallet screen is visible") {
assertIsDisplayed()
}
}
}
step("Emulate scan error") {
MockProvider.setEmulateError()
}
step("Click on \"Scan\" button emulating scan error") {
StoriesPage.scanButton.click()
}
step("Assert: Error is displayed") {
MainPage.container.assertIsNotDisplayed()
}
step("Emulate success scan") {
MockProvider.resetEmulateError()
}
step("Click on \"Scan\" button") {
StoriesPage.scanButton.click()
}
step("Assert: wallet screen is displayed") {
MainPage.container.assertIsDisplayed()
}
}
}

View file

@ -1,36 +1,41 @@
package com.tangem.tests
import android.content.Intent.ACTION_VIEW
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
import androidx.test.espresso.intent.matcher.IntentMatchers.hasData
import com.atiurin.ultron.allure.step.step
import com.atiurin.ultron.core.config.UltronConfig.UiAutomator.Companion.uiDevice
import com.atiurin.ultron.extensions.click
import androidx.test.espresso.intent.matcher.UriMatchers
import com.tangem.common.BaseTestCase
import com.tangem.screens.DisclaimerPage
import com.tangem.screens.StoriesPage
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.screens.DisclaimerTestScreen
import com.tangem.screens.StoriesTestScreen
import com.tangem.tap.features.home.redux.HomeMiddleware.NEW_BUY_WALLET_URL
import dagger.hilt.android.testing.HiltAndroidTest
import org.hamcrest.core.AllOf.allOf
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.kakao.intent.KIntent
import org.hamcrest.Matchers
import org.junit.Test
@HiltAndroidTest
class StoriesTest : BaseTestCase() {
@Test
fun checkOrderButton() {
Intents.init()
step("Click Accept on ToS") {
DisclaimerPage.acceptButton.click()
fun clickOnOrderButton() =
setupHooks().run {
ComposeScreen.onComposeScreen<DisclaimerTestScreen>(composeTestRule) {
step("Click on \"Accept\" button") {
acceptButton.clickWithAssertion()
}
}
ComposeScreen.onComposeScreen<StoriesTestScreen>(composeTestRule) {
step("Click on \"Order\" button") {
orderButton.clickWithAssertion()
}
step("Assert: browser opened") {
val expectedIntent = KIntent {
hasAction(ACTION_VIEW)
hasData { toString().startsWith(NEW_BUY_WALLET_URL) }
}
expectedIntent.intended()
device.uiDevice.pressBack()
}
}
}
step("Click order button ") {
StoriesPage.orderButton.click()
}
step("Assert: browser is opened ") {
Intents.intended(allOf(hasAction(ACTION_VIEW), hasData(NEW_BUY_WALLET_URL)))
uiDevice.pressBack()
Intents.release()
}
}
}

View file

@ -77,6 +77,7 @@ import com.tangem.tap.routing.utils.DeepLinkFactory
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler
import com.tangem.utils.extensions.uriValidate
import com.tangem.wallet.BuildConfig
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
@ -353,7 +354,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
intentProcessor.removeAll()
// workaround: kill process when activity destroy to avoid state when lock() wallets
// and navigation to unlock screen was skipped because system kills activity but not process
android.os.Process.killProcess(android.os.Process.myPid())
if (BuildConfig.BUILD_TYPE != MOCKED_BUILD_TYPE) {
android.os.Process.killProcess(android.os.Process.myPid())
}
super.onDestroy()
}
@ -556,5 +559,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
companion object {
private const val APP_THEME_LOAD_TIMEOUT = 2
private const val MOCKED_BUILD_TYPE = "mocked"
}
}