Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-30 10:28:27 +02:00
parent 6a82ee1600
commit 229dc89bcb
28 changed files with 623 additions and 36 deletions

View file

@ -11,6 +11,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -22,6 +23,7 @@ import com.tangem.core.ui.haptic.TangemHapticEffect
import com.tangem.core.ui.res.LocalHapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.HotWalletAccessCodeTestTags
import com.tangem.features.hotwallet.accesscode.entity.AccessCodeUM
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.delay
@ -109,6 +111,7 @@ internal fun AccessCode(
pinTextColor = state.accessCodeColor,
onValueChange = state.onAccessCodeChange,
focusRequester = focusRequester,
modifier = Modifier.testTag(HotWalletAccessCodeTestTags.ACCESS_CODE_INPUT),
)
}
}

View file

@ -36,5 +36,6 @@ internal data class TangemPayCardPageUM(
@Immutable
internal data class TangemPayCardPageSetting(
val title: TextReference,
val testTag: String? = null,
val onSettingClick: () -> Unit,
)

View file

@ -117,10 +117,12 @@ internal class TangemPayCardPageModel @Inject constructor(
TangemPayCardPageSetting(
title = TextReference.Res(R.string.tangempay_card_details_change_pin),
onSettingClick = { onClickChangePIN(card.hasPinCode) },
testTag = com.tangem.core.ui.test.TangemPayTestTags.CHANGE_PIN_ROW,
),
TangemPayCardPageSetting(
title = TextReference.Res(R.string.tangempay_card_details_freeze_card),
onSettingClick = { onClickFreezeOrUnfreezeCard(card.isFrozen) },
testTag = com.tangem.core.ui.test.TangemPayTestTags.FREEZE_CARD_ROW,
),
TangemPayCardPageSetting(
title = TextReference.Res(R.string.tangempay_card_details_reissue_card),

View file

@ -29,6 +29,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.ImeAction
@ -49,6 +50,7 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.domain.models.account.CardDisplayName
import com.tangem.domain.visa.model.TangemPayCardFrozenState
import com.tangem.features.tangempay.details.impl.R
@ -209,10 +211,12 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif
}
TangemPayCardDetailsCustomButton(
modifier = Modifier.constrainAs(buttonRef) {
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
},
modifier = Modifier
.constrainAs(buttonRef) {
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
}
.testTag(TangemPayTestTags.CARD_DETAILS_SHOW_BUTTON),
text = stringResourceSafe(id = R.string.tangempay_card_details_show_details),
onClick = state.onClick,
showProgress = state.isLoading,
@ -336,6 +340,8 @@ private fun TangemPayCardDetailsShownBlock(
title = stringResourceSafe(R.string.tangempay_card_details_card_number),
text = cardNumber,
onCopy = onCopyCardNumber,
valueTestTag = TangemPayTestTags.CARD_DETAILS_NUMBER_VALUE,
copyTestTag = TangemPayTestTags.CARD_DETAILS_COPY_NUMBER,
)
Row(
modifier = Modifier
@ -350,6 +356,8 @@ private fun TangemPayCardDetailsShownBlock(
title = stringResourceSafe(R.string.tangempay_card_details_expiry),
text = expiry,
onCopy = onCopyExpiry,
valueTestTag = TangemPayTestTags.CARD_DETAILS_EXPIRATION_VALUE,
copyTestTag = TangemPayTestTags.CARD_DETAILS_COPY_EXPIRATION,
)
CardDetailsTextContainer(
modifier = Modifier
@ -358,13 +366,17 @@ private fun TangemPayCardDetailsShownBlock(
title = stringResourceSafe(R.string.tangempay_card_details_cvc),
text = cvv,
onCopy = onCopyCvv,
valueTestTag = TangemPayTestTags.CARD_DETAILS_CVC_VALUE,
copyTestTag = TangemPayTestTags.CARD_DETAILS_COPY_CVC,
)
}
Spacer(modifier = Modifier.weight(1f))
Row {
SpacerWMax()
TangemPayCardDetailsCustomButton(
modifier = Modifier.padding(end = 16.dp, bottom = 8.dp),
modifier = Modifier
.padding(end = 16.dp, bottom = 8.dp)
.testTag(TangemPayTestTags.CARD_DETAILS_HIDE_BUTTON),
text = stringResourceSafe(id = R.string.tangempay_card_details_hide_details),
onClick = onHideDetails,
showProgress = false,
@ -374,7 +386,14 @@ private fun TangemPayCardDetailsShownBlock(
}
@Composable
private fun CardDetailsTextContainer(title: String, text: String, onCopy: () -> Unit, modifier: Modifier = Modifier) {
private fun CardDetailsTextContainer(
title: String,
text: String,
onCopy: () -> Unit,
modifier: Modifier = Modifier,
valueTestTag: String? = null,
copyTestTag: String? = null,
) {
Row(
modifier = modifier
.background(
@ -395,10 +414,13 @@ private fun CardDetailsTextContainer(title: String, text: String, onCopy: () ->
text = text,
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.constantWhite,
modifier = if (valueTestTag != null) Modifier.testTag(valueTestTag) else Modifier,
)
}
IconButton(
modifier = Modifier.size(TangemTheme.dimens.size32),
modifier = Modifier
.size(TangemTheme.dimens.size32)
.then(if (copyTestTag != null) Modifier.testTag(copyTestTag) else Modifier),
onClick = onCopy,
) {
Icon(

View file

@ -31,6 +31,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.util.fastForEach
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
@ -169,7 +170,8 @@ private fun TangemPayCardPageSettingRow(
modifier = modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(TangemTheme.dimens.spacing12),
.padding(TangemTheme.dimens.spacing12)
.then(if (item.testTag != null) Modifier.testTag(item.testTag) else Modifier),
contentAlignment = Alignment.CenterStart,
) {
Text(

View file

@ -8,6 +8,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@ -23,6 +24,7 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.features.tangempay.details.impl.R
@Composable
@ -43,7 +45,7 @@ internal fun TangemPayChangePinCodeSuccessScreen(onClick: () -> Unit, modifier:
titleAlignment = Alignment.CenterHorizontally,
)
Column(
modifier
modifier = Modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
@ -58,7 +60,8 @@ internal fun TangemPayChangePinCodeSuccessScreen(onClick: () -> Unit, modifier:
.fillMaxWidth()
.padding(horizontal = 16.dp)
.padding(bottom = 16.dp)
.navigationBarsPadding(),
.navigationBarsPadding()
.testTag(TangemPayTestTags.PIN_DONE_BUTTON),
text = stringResourceSafe(R.string.common_done),
onClick = onClick,
)
@ -101,14 +104,18 @@ private fun SuccessContent(modifier: Modifier = Modifier) {
)
SpacerH32()
Text(
modifier = Modifier.padding(horizontal = 32.dp),
modifier = Modifier
.padding(horizontal = 32.dp)
.testTag(TangemPayTestTags.PIN_SUCCESS_TITLE),
text = stringResourceSafe(R.string.tangempay_card_details_change_pin_success_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
)
SpacerH12()
Text(
modifier = Modifier.padding(horizontal = 32.dp),
modifier = Modifier
.padding(horizontal = 32.dp)
.testTag(TangemPayTestTags.PIN_SUCCESS_DESCRIPTION),
text = stringResourceSafe(R.string.tangempay_card_details_change_pin_success_description),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.secondary,

View file

@ -17,6 +17,7 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color.Companion.Transparent
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
@ -31,6 +32,7 @@ import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayChangePinUM
import kotlinx.coroutines.delay
@ -52,7 +54,7 @@ internal fun TangemPayChangePinScreen(
)
Column(
modifier = modifier
modifier = Modifier
.fillMaxWidth()
.padding(top = 48.dp)
.padding(horizontal = 36.dp)
@ -64,6 +66,7 @@ internal fun TangemPayChangePinScreen(
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
modifier = Modifier.testTag(TangemPayTestTags.PIN_SCREEN_TITLE),
)
SpacerH16()
@ -73,6 +76,7 @@ internal fun TangemPayChangePinScreen(
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
modifier = Modifier.testTag(TangemPayTestTags.PIN_SCREEN_DESCRIPTION),
)
SpacerH(26.dp)
@ -84,7 +88,8 @@ internal fun TangemPayChangePinScreen(
modifier = Modifier
.imePadding()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.fillMaxWidth(),
.fillMaxWidth()
.testTag(TangemPayTestTags.PIN_SUBMIT_BUTTON),
primaryButton = NavigationButton(
textReference = resourceReference(R.string.common_submit),
onClick = state.onSubmitClick,
@ -117,6 +122,7 @@ private fun PinCodeSection(state: TangemPayChangePinUM, modifier: Modifier = Mod
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.warning,
textAlign = TextAlign.Center,
modifier = Modifier.testTag(TangemPayTestTags.PIN_ERROR_MESSAGE),
)
}
}
@ -150,7 +156,8 @@ private fun PinCode(
.clickable {
focusRequester.requestFocus()
keyboardController?.show()
},
}
.testTag(TangemPayTestTags.PIN_INPUT_FIELD),
textStyle = TangemTheme.typography.h1.copy(color = Transparent),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.NumberPassword,

View file

@ -49,6 +49,7 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.core.ui.test.TokenDetailsTopBarTestTags
import com.tangem.core.ui.test.WalletConnectBottomSheetTestTags
import com.tangem.features.tangempay.components.express.PreviewEmptyExpressTransactionsComponent
@ -304,7 +305,7 @@ private fun FiatBalance(
),
)
is TangemPayDetailsBalanceBlockState.Content -> Text(
modifier = modifier,
modifier = modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE),
text = state.fiatBalance.orMaskWithStars(isBalanceHidden),
style = TangemTheme.typography.h2.applyBladeBrush(
isEnabled = state.isBalanceFlickering,
@ -312,7 +313,7 @@ private fun FiatBalance(
),
)
is TangemPayDetailsBalanceBlockState.Error -> Text(
modifier = modifier,
modifier = modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE),
text = DASH_SIGN.orMaskWithStars(isBalanceHidden),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,

View file

@ -16,6 +16,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextAlign
@ -31,6 +32,7 @@ import com.tangem.core.ui.ds.row.TangemRowLayoutId
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.features.tangempay.entity.TangemPayMainUM
import com.tangem.features.tangempay.main.impl.R
import com.tangem.utils.StringsSigns.DASH_SIGN
@ -90,7 +92,8 @@ private fun TangemPayMainContent(
modifier = modifier
.clip(RoundedCornerShape(size = 18.dp))
.background(TangemTheme.colors2.surface.level3)
.clickableSingle(onClick = payMainUM.onClick),
.clickableSingle(onClick = payMainUM.onClick)
.testTag(TangemPayTestTags.MAIN_SCREEN_TILE),
) {
Image(
painter = painterResource(R.drawable.img_visa_36),

View file

@ -14,6 +14,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@ -29,6 +30,7 @@ import com.tangem.core.ui.components.text.applyBladeBrush
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.features.tangempay.entity.TangemPayMainUM
import com.tangem.features.tangempay.main.impl.R
import com.tangem.utils.StringsSigns.DASH_SIGN
@ -57,7 +59,7 @@ private fun TangemPayMainBlockContent(
modifier: Modifier = Modifier,
) {
Surface(
modifier = modifier,
modifier = modifier.testTag(TangemPayTestTags.MAIN_SCREEN_TILE),
shape = TangemTheme.shapes.roundedCornersXMedium,
color = TangemTheme.colors.background.primary,
onClick = state.onClick,