Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-14 17:19:46 +02:00
parent 18da968728
commit 81abb6b699
13 changed files with 488 additions and 5 deletions

View file

@ -23,6 +23,31 @@ fun BaseTestCase.openTangemPay() {
}
}
/** Opens Tangem Pay and taps the card to reach the card management page. */
fun BaseTestCase.openTangemPayCardPage() {
openTangemPay()
step("Click on 'Card' button") {
onTangemPayMainScreen { cardButton.clickWithAssertion() }
}
step("Assert card page 'More' button is displayed") {
awaitSuccess { onTangemPayCardPageScreen { moreButton.assertIsDisplayed() } }
}
}
/** From the card page, opens the 'Replace card' reissue bottom sheet via the 'More' menu. */
fun BaseTestCase.openReissueSheet() {
step("Click on 'More' button") {
onTangemPayCardPageScreen { moreButton.clickWithAssertion() }
}
step("Click on 'Replace card' menu item") {
awaitSuccess { onTangemPayCardPageScreen { replaceCardMenuItem.assertIsDisplayed() } }
onTangemPayCardPageScreen { replaceCardMenuItem.performClick() }
}
step("Assert reissue bottom sheet is displayed") {
awaitSuccess { onTangemPayReissueSheet { confirmButton.assertIsDisplayed() } }
}
}
// Compose Test gesture — UiAutomator swipe doesn't reach Material3 PullToRefreshBox's NestedScrollConnection.
fun BaseTestCase.pullToRefreshTangemPay() {
val balance = composeTestRule.onNode(hasTestTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE))

View file

@ -19,6 +19,11 @@ class TokenReceiveWarningBottomSheetPageObject(semanticsProvider: SemanticsNodeI
val gotItButton: KNode = child {
hasText(getResourceString(R.string.common_got_it))
}
fun networkName(name: String): KNode = child {
hasText(text = name, substring = true)
useUnmergedTree = true
}
}
internal fun BaseTestCase.onTokenReceiveWarningBottomSheet(function: TokenReceiveWarningBottomSheetPageObject.() -> Unit) =

View file

@ -17,7 +17,7 @@ class TangemPayAddFundsSheetPageObject(semanticsProvider: SemanticsNodeInteracti
}
val receiveOption: KNode = child {
hasText(getResourceString(CoreResR.string.common_receive))
hasText(getResourceString(CoreResR.string.tangempay_topup_receive_title))
useUnmergedTree = true
}

View file

@ -2,14 +2,39 @@ 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 com.tangem.core.ui.test.TangemPayTestTags
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 TangemPayCardPagePageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<TangemPayCardPagePageObject>(semanticsProvider = semanticsProvider) {
val moreButton: KNode = child {
hasTestTag(TangemPayTestTags.CARD_PAGE_MORE_BUTTON)
useUnmergedTree = true
}
val replaceCardMenuItem: KNode = child {
hasText(getResourceString(CoreResR.string.tangempay_card_details_reissue_card))
useUnmergedTree = true
}
val cardNumberShort: KNode = child {
hasTestTag(TangemPayTestTags.CARD_NUMBER_SHORT)
useUnmergedTree = true
}
val reissueInProgressBlock: KNode = child {
hasText(
text = getResourceString(CoreResR.string.tangempay_reissue_card_in_progress),
substring = true,
)
useUnmergedTree = true
}
val changePinRow: KNode = child {
hasTestTag(TangemPayTestTags.CHANGE_PIN_ROW)
useUnmergedTree = true

View file

@ -61,6 +61,14 @@ class TangemPayMainPageObject(semanticsProvider: SemanticsNodeInteractionsProvid
hasText(text)
useUnmergedTree = true
}
val reissueInProgressBanner: KNode = child {
hasText(
text = getResourceString(CoreResR.string.tangempay_reissue_card_in_progress),
substring = true,
)
useUnmergedTree = true
}
}
internal fun BaseTestCase.onTangemPayMainScreen(function: TangemPayMainPageObject.() -> Unit) =

View file

@ -0,0 +1,62 @@
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 com.tangem.core.ui.test.TangemPayTestTags
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 TangemPayReissueSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<TangemPayReissueSheetPageObject>(semanticsProvider = semanticsProvider) {
val title: KNode = child {
hasText(getResourceString(CoreResR.string.tangempay_reissue_card_title))
useUnmergedTree = true
}
val description: KNode = child {
hasText(getResourceString(CoreResR.string.tangempay_reissue_card_description))
useUnmergedTree = true
}
val feeLabel: KNode = child {
hasText(getResourceString(CoreResR.string.tangempay_reissue_card_fee_label))
useUnmergedTree = true
}
val feeValue: KNode = child {
hasTestTag(TangemPayTestTags.REISSUE_SHEET_FEE_VALUE)
useUnmergedTree = true
}
val confirmButton: KNode = child {
hasTestTag(TangemPayTestTags.REISSUE_SHEET_CONFIRM_BUTTON)
useUnmergedTree = true
}
val feeErrorTitle: KNode = child {
hasText(getResourceString(CoreResR.string.tangempay_reissue_card_fee_unreachable_error_title))
useUnmergedTree = true
}
val refreshButton: KNode = child {
hasText(getResourceString(CoreResR.string.warning_button_refresh))
useUnmergedTree = true
}
val insufficientFundsTitle: KNode = child {
hasText(getResourceString(CoreResR.string.tangempay_reissue_card_insufficient_funds_title))
useUnmergedTree = true
}
val addFundsButton: KNode = child {
hasText(getResourceString(CoreResR.string.tangempay_card_details_add_funds))
useUnmergedTree = true
}
}
internal fun BaseTestCase.onTangemPayReissueSheet(function: TangemPayReissueSheetPageObject.() -> Unit) =
onComposeScreen(composeTestRule, function)

View file

@ -0,0 +1,33 @@
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 com.tangem.core.ui.test.TangemPayTestTags
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 TangemPayTransactionDetailsSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<TangemPayTransactionDetailsSheetPageObject>(semanticsProvider = semanticsProvider) {
val feeTitle: KNode = child {
hasText(getResourceString(CoreResR.string.tangem_pay_fee_title))
useUnmergedTree = true
}
val serviceFeesCategory: KNode = child {
hasText(getResourceString(CoreResR.string.tangem_pay_fee_subtitle))
useUnmergedTree = true
}
val amount: KNode = child {
hasTestTag(TangemPayTestTags.TRANSACTION_DETAILS_AMOUNT)
useUnmergedTree = true
}
}
internal fun BaseTestCase.onTangemPayTransactionDetailsSheet(
function: TangemPayTransactionDetailsSheetPageObject.() -> Unit,
) = onComposeScreen(composeTestRule, function)

View file

@ -0,0 +1,299 @@
package com.tangem.tests.tangempay
import com.tangem.common.BaseTestCase
import com.tangem.common.constants.TestConstants.TANGEM_PAY_ELIGIBILITY_SCENARIO
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_VERY_LONG
import com.tangem.common.extensions.assertTextContainsSafe
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.common.extensions.extractText
import com.tangem.common.utils.resetWireMockScenarioState
import com.tangem.common.utils.resetWireMockScenarios
import com.tangem.common.utils.setWireMockScenarioState
import com.tangem.scenarios.*
import com.tangem.screens.onTokenReceiveWarningBottomSheet
import com.tangem.screens.tangempay.*
import dagger.hilt.android.testing.HiltAndroidTest
import io.qameta.allure.kotlin.AllureId
import io.qameta.allure.kotlin.junit4.DisplayName
import org.junit.Assert
import org.junit.Test
@HiltAndroidTest
class TangemPayReissueTest : BaseTestCase() {
private val eligibilityState = "PaeraCustomer"
private val balanceScenario = "tangem_pay_balance_update"
private val balanceInitialState = "InitialBalance"
private val cardReissueScenario = "tangem_pay_card_reissue"
private val cardReissueStartedState = "Started"
private val cardReissueFeeErrorState = "FeeError"
private val reissueOrderScenario = "tangem_pay_reissue_order"
private val reissueOrderStartedState = "Started"
private val reissueOrderCompletedState = "Completed"
private val reissueScenario = "tangem_pay_reissue"
private val reissueCompletedState = "Completed"
private val historyScenario = "tangem_pay_transaction_history"
private val historyInitialEmptyState = "InitialEmpty"
private val historyAfterReissueFeeState = "AfterReissueFee"
@AllureId("9749")
@DisplayName("Tangem Pay: card reissue bottom sheet displays replace card details")
@Test
fun reissueBottomSheetDisplaysReplaceCardDetailsTest() {
setupHooks(
additionalBeforeSection = {
resetWireMockScenarios()
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
setWireMockScenarioState(balanceScenario, balanceInitialState)
setWireMockScenarioState(cardReissueScenario, cardReissueStartedState)
},
additionalAfterSection = {
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
resetWireMockScenarioState(balanceScenario)
resetWireMockScenarioState(cardReissueScenario)
},
).run {
step("Open Tangem Pay card page") { openTangemPayCardPage() }
step("Open the 'Replace card' reissue bottom sheet") { openReissueSheet() }
step("Assert reissue sheet title, description and fee label are displayed") {
onTangemPayReissueSheet {
title.assertIsDisplayed()
description.assertIsDisplayed()
feeLabel.assertIsDisplayed()
}
}
step("Assert replacement fee value is displayed") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayReissueSheet { feeValue.assertTextContainsSafe("1.00", substring = true) }
}
}
}
}
@AllureId("9833")
@DisplayName("Tangem Pay: error is shown when reissue cost is not fetched")
@Test
fun reissueFeeErrorShowsErrorWhenFeeRequestFailsTest() {
setupHooks(
additionalBeforeSection = {
resetWireMockScenarios()
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
setWireMockScenarioState(cardReissueScenario, cardReissueFeeErrorState)
},
additionalAfterSection = {
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
resetWireMockScenarioState(cardReissueScenario)
},
).run {
step("Open Tangem Pay card page") { openTangemPayCardPage() }
step("Open the 'Replace card' reissue bottom sheet") { openReissueSheet() }
step("Assert fee unreachable error and 'Refresh' button are displayed") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayReissueSheet {
feeErrorTitle.assertIsDisplayed()
refreshButton.assertIsDisplayed()
}
}
}
}
}
@AllureId("9752")
@DisplayName("Tangem Pay: reissue fee transaction appears in history and details")
@Test
fun reissueFeeTransactionAppearsInHistoryAndDetailsTest() {
val feeMerchantName = "Card replacement fee"
setupHooks(
additionalBeforeSection = {
resetWireMockScenarios()
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
setWireMockScenarioState(balanceScenario, balanceInitialState)
setWireMockScenarioState(cardReissueScenario, cardReissueStartedState)
setWireMockScenarioState(reissueOrderScenario, reissueOrderStartedState)
setWireMockScenarioState(historyScenario, historyInitialEmptyState)
},
additionalAfterSection = {
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
resetWireMockScenarioState(balanceScenario)
resetWireMockScenarioState(cardReissueScenario)
resetWireMockScenarioState(reissueOrderScenario)
resetWireMockScenarioState(historyScenario)
},
).run {
step("Open Tangem Pay card page") { openTangemPayCardPage() }
step("Open the 'Replace card' reissue bottom sheet") { openReissueSheet() }
step("Wait for replacement fee to load") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayReissueSheet { feeValue.assertTextContainsSafe("1.00", substring = true) }
}
}
step("Click on 'Replace card' confirm button") {
onTangemPayReissueSheet { confirmButton.clickWithAssertion() }
}
step("Assert reissue started and the sheet is dismissed") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayCardPageScreen { reissueInProgressBlock.assertIsDisplayed() }
}
}
step("Return to the payment account screen") {
device.uiDevice.pressBack()
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayMainScreen { balance.assertIsDisplayed() }
}
}
step("Switch WireMock scenario '$historyScenario' to '$historyAfterReissueFeeState'") {
setWireMockScenarioState(historyScenario, historyAfterReissueFeeState)
}
step("Pull to refresh Tangem Pay") { pullToRefreshTangemPay() }
step("Assert '$feeMerchantName' transaction is displayed") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayMainScreen { transactionRowWithText(feeMerchantName).assertIsDisplayed() }
}
}
step("Click on '$feeMerchantName' transaction row") {
onTangemPayMainScreen { transactionRowWithText(feeMerchantName).performClick() }
}
step("Assert fee transaction details are displayed") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayTransactionDetailsSheet {
feeTitle.assertIsDisplayed()
serviceFeesCategory.assertIsDisplayed()
amount.assertTextContainsSafe("1.00", substring = true)
}
}
}
}
}
@AllureId("9743")
@DisplayName("Tangem Pay: card reissue end-to-end replaces card with new details")
@Test
fun reissueEndToEndReplacesCardWithNewDetailsTest() {
val reissuedCardLastDigits = "5353"
val balanceAfterWithdrawState = "AfterWithdraw"
// AfterWithdraw funds the fee check without a customer/me stub, so reissued customer/me wins.
setupHooks(
additionalBeforeSection = {
resetWireMockScenarios()
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
setWireMockScenarioState(balanceScenario, balanceAfterWithdrawState)
setWireMockScenarioState(cardReissueScenario, cardReissueStartedState)
setWireMockScenarioState(reissueOrderScenario, reissueOrderStartedState)
},
additionalAfterSection = {
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
resetWireMockScenarioState(balanceScenario)
resetWireMockScenarioState(cardReissueScenario)
resetWireMockScenarioState(reissueOrderScenario)
resetWireMockScenarioState(reissueScenario)
},
).run {
var oldCardNumber = ""
step("Open Tangem Pay card page") { openTangemPayCardPage() }
step("Read the current card number") {
onTangemPayCardPageScreen { cardNumberShort.assertIsDisplayed() }
onTangemPayCardPageScreen { oldCardNumber = cardNumberShort.extractText() }
}
step("Open the 'Replace card' reissue bottom sheet") { openReissueSheet() }
step("Wait for replacement fee to load") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayReissueSheet { feeValue.assertTextContainsSafe("1.00", substring = true) }
}
}
step("Click on 'Replace card' confirm button") {
onTangemPayReissueSheet { confirmButton.clickWithAssertion() }
}
step("Assert reissue started (sheet dismissed, card is replacing)") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayReissueSheet { confirmButton.assertDoesNotExist() }
onTangemPayCardPageScreen { reissueInProgressBlock.assertIsDisplayed() }
}
}
step("Switch WireMock scenario '$reissueOrderScenario' to '$reissueOrderCompletedState'") {
setWireMockScenarioState(reissueOrderScenario, reissueOrderCompletedState)
}
step("Switch WireMock scenario '$reissueScenario' to '$reissueCompletedState'") {
setWireMockScenarioState(reissueScenario, reissueCompletedState)
}
step("Return to the payment account screen") {
device.uiDevice.pressBack()
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayMainScreen { balance.assertIsDisplayed() }
}
}
step("Refresh until the card leaves the replacing state") {
pullToRefreshTangemPay()
flakySafely(WAIT_UNTIL_TIMEOUT_VERY_LONG) {
onTangemPayMainScreen { reissueInProgressBanner.assertDoesNotExist() }
}
}
step("Reopen the reissued card") {
onTangemPayMainScreen { cardButton.clickWithAssertion() }
}
var newCardNumber = ""
step("Read the new card number") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayCardPageScreen {
cardNumberShort.assertTextContainsSafe(reissuedCardLastDigits, substring = true)
}
}
onTangemPayCardPageScreen { newCardNumber = cardNumberShort.extractText() }
}
step("Assert the card number changed after reissue") {
Assert.assertNotEquals(oldCardNumber, newCardNumber)
}
}
}
@AllureId("9746")
@DisplayName("Tangem Pay: top up via card reissue when unable to cover fee")
@Test
fun reissueTopUpUnableToCoverFeeAddFundsReceiveTest() {
val depositNetworkName = "Polygon"
setupHooks(
additionalBeforeSection = {
resetWireMockScenarios()
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
setWireMockScenarioState(cardReissueScenario, cardReissueStartedState)
},
additionalAfterSection = {
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
resetWireMockScenarioState(cardReissueScenario)
},
).run {
step("Open Tangem Pay card page") { openTangemPayCardPage() }
step("Open the 'Replace card' reissue bottom sheet") { openReissueSheet() }
step("Assert 'Unable to cover fee' state is displayed") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayReissueSheet { insufficientFundsTitle.assertIsDisplayed() }
}
}
step("Click on 'Add funds' button") {
onTangemPayReissueSheet { addFundsButton.clickWithAssertion() }
}
step("Assert 'Add funds' sheet shows Swap and Receive options") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTangemPayAddFundsSheet {
swapOption.assertIsDisplayed()
receiveOption.assertIsDisplayed()
}
}
}
step("Click on 'Receive' option") {
onTangemPayAddFundsSheet { receiveOption.clickWithAssertion() }
}
step("Assert deposit info for the '$depositNetworkName' network is displayed") {
flakySafely(WAIT_UNTIL_TIMEOUT) {
onTokenReceiveWarningBottomSheet {
bottomSheet.assertIsDisplayed()
networkName(depositNetworkName).assertIsDisplayed()
}
}
}
}
}
}

View file

@ -24,6 +24,19 @@ object TangemPayTestTags {
const val FREEZE_CARD_ROW = "TANGEM_PAY_FREEZE_CARD_ROW"
const val CARD_FROZEN_BADGE = "TANGEM_PAY_CARD_FROZEN_BADGE"
// Card page top bar more-actions menu (redesign)
const val CARD_PAGE_MORE_BUTTON = "TANGEM_PAY_CARD_PAGE_MORE_BUTTON"
// Masked card number shown on the card face (e.g. "*4242")
const val CARD_NUMBER_SHORT = "TANGEM_PAY_CARD_NUMBER_SHORT"
// Replace card (reissue) bottom sheet
const val REISSUE_SHEET_CONFIRM_BUTTON = "TANGEM_PAY_REISSUE_SHEET_CONFIRM_BUTTON"
const val REISSUE_SHEET_FEE_VALUE = "TANGEM_PAY_REISSUE_SHEET_FEE_VALUE"
// Transaction details bottom sheet
const val TRANSACTION_DETAILS_AMOUNT = "TANGEM_PAY_TRANSACTION_DETAILS_AMOUNT"
// Freeze confirmation bottom sheet
const val FREEZE_CONFIRMATION_SUBMIT_BUTTON = "TANGEM_PAY_FREEZE_CONFIRMATION_SUBMIT_BUTTON"

View file

@ -448,7 +448,8 @@ private fun ConstraintLayoutScope.CardNumberBlock(
start.linkTo(parent.start)
bottom.linkTo(parent.bottom)
}
.padding(bottom = 8.dp),
.padding(bottom = 8.dp)
.testTag(TangemPayTestTags.CARD_NUMBER_SHORT),
)
} else {
Text(

View file

@ -34,6 +34,7 @@ import com.tangem.core.ui.ds.topbar.TangemTopBar
import com.tangem.core.ui.ds2.button.TangemButton
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.*
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.domain.models.pay.TangemPayCardFrozenState
import com.tangem.domain.models.pay.TangemPayCardState
import com.tangem.features.tangempay.details.impl.R
@ -355,6 +356,7 @@ private fun CardPageTopBar(
endContent = {
Box {
TangemButton(
modifier = Modifier.testTag(TangemPayTestTags.CARD_PAGE_MORE_BUTTON),
iconStart = TangemIconUM.Icon(iconRes = CoreUiR.drawable.ic_more_default_24),
onClick = { isDropdownMenuShown = true },
size = TangemButton.Size.X11,

View file

@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@ -39,6 +40,7 @@ import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_arrow_refresh_32
import com.tangem.core.ui.res.generated.icons.ic_error_28
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayReissueCardError
import com.tangem.features.tangempay.entity.TangemPayReissueCardUM
@ -155,6 +157,7 @@ private fun FeeBlock(
titleRes = R.string.tangempay_reissue_card_fee_label,
value = state.feeAmount,
showDivider = appearance.shouldShowBalanceRow,
valueTestTag = TangemPayTestTags.REISSUE_SHEET_FEE_VALUE,
)
if (appearance.shouldShowBalanceRow) {
FeeInfoRow(
@ -166,7 +169,7 @@ private fun FeeBlock(
}
@Composable
private fun FeeInfoRow(titleRes: Int, value: String, showDivider: Boolean = false) {
private fun FeeInfoRow(titleRes: Int, value: String, showDivider: Boolean = false, valueTestTag: String? = null) {
TangemRow(
divider = showDivider,
contentLead = TangemRowContentLead.Start,
@ -185,6 +188,7 @@ private fun FeeInfoRow(titleRes: Int, value: String, showDivider: Boolean = fals
)
} else {
TangemRowText(
modifier = if (valueTestTag != null) Modifier.testTag(valueTestTag) else Modifier,
text = value,
role = TangemRowTextRole.Value,
)
@ -213,7 +217,9 @@ private fun BottomButtonsBlock(
text = resourceReference(R.string.common_cancel),
)
TangemButton(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth()
.testTag(TangemPayTestTags.REISSUE_SHEET_CONFIRM_BUTTON),
size = TangemButton.Size.X12,
onClick = appearance.primaryAction(state),
isEnabled = !state.isFeeLoading && !state.isReissuingInProgress,

View file

@ -15,6 +15,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Devices
@ -40,6 +41,7 @@ import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_arrow_down_24
import com.tangem.core.ui.res.generated.icons.ic_arrow_refresh_20
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.*
@ -83,7 +85,9 @@ internal fun TangemPayTxHistoryDetailsContentV2(state: TangemPayTxHistoryDetails
modifier = Modifier.padding(top = TangemTheme.dimens2.x12),
)
Text(
modifier = Modifier.padding(top = TangemTheme.dimens2.x6),
modifier = Modifier
.padding(top = TangemTheme.dimens2.x6)
.testTag(TangemPayTestTags.TRANSACTION_DETAILS_AMOUNT),
text = state.transactionAmount.orMaskWithStars(state.isBalanceHidden),
style = TangemTheme.typography3.display.medium,
color = TangemTheme.colors3.text.primary,