Updated on 2026-08-14
This commit is contained in:
parent
cf30e34188
commit
b13137406c
10 changed files with 299 additions and 1 deletions
|
|
@ -69,5 +69,7 @@ object TestConstants {
|
|||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
||||
|
||||
const val TANGEM_PAY_ELIGIBILITY_SCENARIO = "tangem_pay_eligibility"
|
||||
const val TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO = "tangem_pay_eligibility_channels"
|
||||
const val TANGEM_PAY_KYC_STATUS_SCENARIO = "tangem_pay_kyc_status"
|
||||
const val TANGEM_PAY_ACCESS_CODE = "517384"
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onCompose
|
|||
import io.github.kakaocup.compose.node.element.KNode
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
import com.tangem.core.res.R as CoreResR
|
||||
|
||||
class DetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<DetailsPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
|
@ -65,6 +66,12 @@ class DetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
|||
hasAnyDescendant(withText(name))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val getTangemPayRow: KNode = child {
|
||||
hasTestTag(DetailsScreenTestTags.SCREEN_ITEM)
|
||||
hasAnyDescendant(withText(getResourceString(CoreResR.string.tangempay_get_tangem_pay)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onDetailsScreen(function: DetailsPageObject.() -> Unit) =
|
||||
|
|
|
|||
|
|
@ -202,6 +202,12 @@ class MainScreenPageObject(private val semanticsProvider: SemanticsNodeInteracti
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val getTangemPayBanner: KNode = child {
|
||||
hasTestTag(NotificationTestTags.TITLE)
|
||||
hasText(getResourceString(CoreResR.string.tangempay_onboarding_banner_title))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val devCardNotificationIcon: KNode = child {
|
||||
hasAnySibling(withText(getResourceString(R.string.warning_developer_card_title)))
|
||||
hasTestTag(NotificationTestTags.ICON)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.screens.tangempay
|
||||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.WarningBottomSheetTestTags
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.KNode
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
|
||||
class TangemPayKycSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<TangemPayKycSheetPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
fun title(text: String): KNode = child {
|
||||
hasTestTag(WarningBottomSheetTestTags.TITLE)
|
||||
hasText(text)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun primaryButtonWithText(text: String): KNode = child {
|
||||
hasTestTag(WarningBottomSheetTestTags.BUTTON_PRIMARY)
|
||||
hasAnyDescendant(withText(text))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val closeButton: KNode = child {
|
||||
hasTestTag(WarningBottomSheetTestTags.CLOSE_BUTTON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onTangemPayKycSheet(function: TangemPayKycSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -20,6 +20,12 @@ class TangemPayMainPageObject(semanticsProvider: SemanticsNodeInteractionsProvid
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun tileWithSubtitle(subtitle: String): KNode = child {
|
||||
hasTestTag(TangemPayTestTags.MAIN_SCREEN_TILE)
|
||||
hasAnyDescendant(withText(subtitle))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val balance: KNode = child {
|
||||
hasTestTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE)
|
||||
useUnmergedTree = true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.screens.tangempay
|
||||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.res.R as CoreResR
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.KNode
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
|
||||
class TangemPayOnboardingPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<TangemPayOnboardingPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val title: KNode = child {
|
||||
hasText(getResourceString(CoreResR.string.tangempay_onboarding_title))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onTangemPayOnboardingScreen(function: TangemPayOnboardingPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
package com.tangem.tests.tangempay
|
||||
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.SVS_SEED_PHRASE_12
|
||||
import com.tangem.common.constants.TestConstants.TANGEM_PAY_ACCESS_CODE
|
||||
import com.tangem.common.constants.TestConstants.TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.TANGEM_PAY_ELIGIBILITY_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.TANGEM_PAY_KYC_STATUS_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_SHORT
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.scenarios.openMainScreenWithExistingHotWallet
|
||||
import com.tangem.screens.onDetailsScreen
|
||||
import com.tangem.screens.onMainScreen
|
||||
import com.tangem.screens.onMainScreenTopBar
|
||||
import com.tangem.screens.tangempay.onTangemPayKycSheet
|
||||
import com.tangem.screens.tangempay.onTangemPayMainScreen
|
||||
import com.tangem.screens.tangempay.onTangemPayOnboardingScreen
|
||||
import com.tangem.core.res.R as CoreResR
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
import io.qameta.allure.kotlin.AllureId
|
||||
import io.qameta.allure.kotlin.junit4.DisplayName
|
||||
import org.junit.Test
|
||||
|
||||
@HiltAndroidTest
|
||||
class TangemPayOnboardingKycTest : BaseTestCase() {
|
||||
|
||||
@AllureId("9630")
|
||||
@DisplayName("Tangem Pay: existing customer authorization shows the tile on Main")
|
||||
@Test
|
||||
fun existingUserAuthorizationShowsTangemPayTileOnMainTest() {
|
||||
val paeraCustomerState = "PaeraCustomer"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||
},
|
||||
).run {
|
||||
step("Set WireMock scenario '$TANGEM_PAY_ELIGIBILITY_SCENARIO' to '$paeraCustomerState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, paeraCustomerState)
|
||||
}
|
||||
step("Open 'Main' screen with existing hot wallet") {
|
||||
openMainScreenWithExistingHotWallet(SVS_SEED_PHRASE_12, accessCode = TANGEM_PAY_ACCESS_CODE)
|
||||
}
|
||||
step("Assert Tangem Pay tile is displayed on Main") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onTangemPayMainScreen { mainScreenTile.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("9632")
|
||||
@DisplayName("Tangem Pay: Get Tangem Pay banner is shown on Main for the BANNER channel")
|
||||
@Test
|
||||
fun getTangemPayBannerShownOnMainWhenBannerChannelReceivedTest() {
|
||||
val eligibilityStartedState = "Started"
|
||||
val channelsBannerState = "Banner"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO)
|
||||
},
|
||||
).run {
|
||||
step("Set WireMock scenario '$TANGEM_PAY_ELIGIBILITY_SCENARIO' to '$eligibilityStartedState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityStartedState)
|
||||
}
|
||||
step("Set WireMock scenario '$TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO' to '$channelsBannerState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO, channelsBannerState)
|
||||
}
|
||||
step("Open 'Main' screen with existing hot wallet") {
|
||||
openMainScreenWithExistingHotWallet(SVS_SEED_PHRASE_12, accessCode = TANGEM_PAY_ACCESS_CODE)
|
||||
}
|
||||
step("Assert 'Get Tangem Pay' banner is displayed on Main") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onMainScreen { getTangemPayBanner.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("9673")
|
||||
@DisplayName("Tangem Pay: onboarding opens from app Details for the DETAILS channel")
|
||||
@Test
|
||||
fun onboardingOpensFromAppDetailsWhenDetailsChannelReceivedTest() {
|
||||
val eligibilityStartedState = "Started"
|
||||
val channelsBannerAndDetailsState = "BannerAndDetails"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO)
|
||||
},
|
||||
).run {
|
||||
step("Set WireMock scenario '$TANGEM_PAY_ELIGIBILITY_SCENARIO' to '$eligibilityStartedState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityStartedState)
|
||||
}
|
||||
step("Set WireMock scenario '$TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO' to '$channelsBannerAndDetailsState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_CHANNELS_SCENARIO, channelsBannerAndDetailsState)
|
||||
}
|
||||
step("Open 'Main' screen with existing hot wallet") {
|
||||
openMainScreenWithExistingHotWallet(SVS_SEED_PHRASE_12, accessCode = TANGEM_PAY_ACCESS_CODE)
|
||||
}
|
||||
step("Click on 'More' button") {
|
||||
onMainScreenTopBar { moreButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Get Tangem Pay' row is displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onDetailsScreen { getTangemPayRow.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Click on 'Get Tangem Pay' row") {
|
||||
onDetailsScreen { getTangemPayRow.clickWithAssertion() }
|
||||
}
|
||||
step("Assert Tangem Pay onboarding screen is displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onTangemPayOnboardingScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("9643")
|
||||
@DisplayName("Tangem Pay: KYC in progress sheet closes and the status remains on Main")
|
||||
@Test
|
||||
fun kycInProgressSheetClosesAndStatusRemainsOnMainTest() {
|
||||
val paeraCustomerState = "PaeraCustomer"
|
||||
val kycInProgressState = "InProgress"
|
||||
val kycInProgressText = getResourceString(CoreResR.string.tangempay_kyc_in_progress)
|
||||
val viewStatusText = getResourceString(CoreResR.string.tangempay_kyc_in_progress_notification_button)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||
resetWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO)
|
||||
},
|
||||
).run {
|
||||
step("Set WireMock scenario '$TANGEM_PAY_ELIGIBILITY_SCENARIO' to '$paeraCustomerState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, paeraCustomerState)
|
||||
}
|
||||
step("Set WireMock scenario '$TANGEM_PAY_KYC_STATUS_SCENARIO' to '$kycInProgressState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO, kycInProgressState)
|
||||
}
|
||||
step("Open 'Main' screen with existing hot wallet") {
|
||||
openMainScreenWithExistingHotWallet(SVS_SEED_PHRASE_12, accessCode = TANGEM_PAY_ACCESS_CODE)
|
||||
}
|
||||
step("Assert Tangem Pay tile with '$kycInProgressText' is displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onTangemPayMainScreen { tileWithSubtitle(kycInProgressText).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Click on Tangem Pay tile") {
|
||||
onTangemPayMainScreen { mainScreenTile.clickWithAssertion() }
|
||||
}
|
||||
step("Assert KYC in progress sheet is displayed") {
|
||||
onTangemPayKycSheet {
|
||||
title(kycInProgressText).assertIsDisplayed()
|
||||
primaryButtonWithText(viewStatusText).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
step("Click on 'Close' button") {
|
||||
onTangemPayKycSheet { closeButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert KYC in progress sheet is not displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_SHORT) {
|
||||
onTangemPayKycSheet { primaryButtonWithText(viewStatusText).assertDoesNotExist() }
|
||||
}
|
||||
}
|
||||
step("Assert Tangem Pay tile with '$kycInProgressText' is still displayed") {
|
||||
onTangemPayMainScreen { tileWithSubtitle(kycInProgressText).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("9517")
|
||||
@DisplayName("Tangem Pay: KYC rejected status shown on Main and in the sheet")
|
||||
@Test
|
||||
fun kycRejectedStatusShownOnMainAndInSheetTest() {
|
||||
val paeraCustomerState = "PaeraCustomer"
|
||||
val kycDeclinedState = "Declined"
|
||||
val kycRejectedTileText = getResourceString(CoreResR.string.tangempay_kyc_has_failed)
|
||||
val rejectedSheetTitle = getResourceString(CoreResR.string.tangempay_kyc_rejected)
|
||||
val goToSupportText = getResourceString(CoreResR.string.tangempay_go_to_support)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||
resetWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO)
|
||||
},
|
||||
).run {
|
||||
step("Set WireMock scenario '$TANGEM_PAY_ELIGIBILITY_SCENARIO' to '$paeraCustomerState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, paeraCustomerState)
|
||||
}
|
||||
step("Set WireMock scenario '$TANGEM_PAY_KYC_STATUS_SCENARIO' to '$kycDeclinedState'") {
|
||||
setWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO, kycDeclinedState)
|
||||
}
|
||||
step("Open 'Main' screen with existing hot wallet") {
|
||||
openMainScreenWithExistingHotWallet(SVS_SEED_PHRASE_12, accessCode = TANGEM_PAY_ACCESS_CODE)
|
||||
}
|
||||
step("Assert Tangem Pay tile with '$kycRejectedTileText' is displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onTangemPayMainScreen { tileWithSubtitle(kycRejectedTileText).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Click on Tangem Pay tile") {
|
||||
onTangemPayMainScreen { mainScreenTile.clickWithAssertion() }
|
||||
}
|
||||
step("Assert KYC rejected sheet is displayed") {
|
||||
onTangemPayKycSheet {
|
||||
title(rejectedSheetTitle).assertIsDisplayed()
|
||||
primaryButtonWithText(goToSupportText).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -63,6 +63,7 @@ fun MessageBottomSheetV2(state: MessageBottomSheetUM, onDismissRequest: () -> Un
|
|||
type = TangemTopBarType.BottomSheet,
|
||||
endContent = {
|
||||
TangemButton(
|
||||
modifier = Modifier.testTag(WarningBottomSheetTestTags.CLOSE_BUTTON),
|
||||
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
|
||||
onClick = stateWithOnDismiss.onDismissRequest,
|
||||
size = TangemButton.Size.X11,
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ object WarningBottomSheetTestTags {
|
|||
const val MESSAGE = "BASE_WARNING_BOTTOM_SHEET_MESSAGE"
|
||||
const val BUTTON_PRIMARY = "BASE_WARNING_BOTTOM_SHEET_BUTTON_PRIMARY"
|
||||
const val BUTTON_SECONDARY = "BASE_WARNING_BOTTOM_SHEET_BUTTON_SECONDARY"
|
||||
const val CLOSE_BUTTON = "BASE_WARNING_BOTTOM_SHEET_CLOSE_BUTTON"
|
||||
}
|
||||
|
|
@ -149,7 +149,8 @@ private fun TangemPayStateRow(
|
|||
modifier = modifier
|
||||
.clip(RoundedCornerShape(size = 18.dp))
|
||||
.background(TangemTheme.colors2.surface.level3)
|
||||
.conditional(onClick != null && isEnabled) { clickableSingle(onClick = requireNotNull(onClick)) },
|
||||
.conditional(onClick != null && isEnabled) { clickableSingle(onClick = requireNotNull(onClick)) }
|
||||
.testTag(TangemPayTestTags.MAIN_SCREEN_TILE),
|
||||
) {
|
||||
Image(
|
||||
painter = getVisaIconPainter(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue