Updated on 2026-08-14
This commit is contained in:
parent
1feec554e6
commit
eff4bd0336
24 changed files with 656 additions and 14 deletions
|
|
@ -80,6 +80,17 @@ fun List<SemanticsNode>.assertTrustScoresValid() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the text content from a [KNode]'s semantics.
|
||||
* Useful when the displayed value is dynamic and you need to capture it for later assertions.
|
||||
*/
|
||||
fun KNode.extractText(): String {
|
||||
val node = delegate.interaction.semanticsNodeInteraction.fetchSemanticsNode(
|
||||
"Failed to extract text from KNode",
|
||||
)
|
||||
return extractText(node) ?: error("Node does not contain SemanticsProperties.Text")
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the text value from a semantic node's config.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -167,4 +167,18 @@ fun BaseTestCase.checkChangesInInputTextField(title: String, newValue: String, a
|
|||
step("Assert '$title' value: '$newValue + $addition'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(title).assertTextContains(newValue + addition) }
|
||||
}
|
||||
}
|
||||
|
||||
fun BaseTestCase.openSendConfirmScreenViaNextButton() {
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen {
|
||||
addressesShimmer.assertIsNotDisplayed()
|
||||
nextButton.assertIsDisplayed()
|
||||
nextButton.assertIsEnabled()
|
||||
nextButton.performClick()
|
||||
}
|
||||
}
|
||||
step("Assert 'Send' button on 'Send confirm' screen is displayed") {
|
||||
onSendConfirmScreen { sendButton.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.test.BaseBottomSheetTestTags
|
||||
import com.tangem.core.ui.test.ChooseNetworkBottomSheetTestTags
|
||||
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
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
|
||||
class ChooseNetworkBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<ChooseNetworkBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val title: KNode = child {
|
||||
hasTestTag(BaseBottomSheetTestTags.TITLE)
|
||||
hasText(getResourceString(R.string.common_choose_network))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun networkItem(title: String, subtitle: String): KNode = child {
|
||||
hasTestTag(ChooseNetworkBottomSheetTestTags.NETWORK_ITEM)
|
||||
hasAnyDescendant(withText(title))
|
||||
hasAnyDescendant(withText(subtitle))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onChooseNetworkBottomSheet(function: ChooseNetworkBottomSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -59,6 +59,11 @@ class DialogPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
|||
hasTestTag(BaseButtonTestTags.BUTTON)
|
||||
hasText(getResourceString(R.string.common_ok))
|
||||
}
|
||||
|
||||
val changeButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.BUTTON)
|
||||
hasText(getResourceString(R.string.common_change))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onDialog(function: DialogPageObject.() -> Unit) =
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class SelectProviderPageObject(semanticsProvider: SemanticsNodeInteractionsProvi
|
|||
|
||||
|
||||
val instantProcessingSpeedText: KNode = child {
|
||||
hasText(getResourceString(com.tangem.core.ui.R.string.onramp_instant_status))
|
||||
hasText(getResourceString(R.string.onramp_instant_status))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.SelectSwapProviderBottomSheetTestTags
|
||||
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.hasTestTag as withTestTag
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
|
||||
class SelectSwapProviderBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<SelectSwapProviderBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
fun providerItem(name: String, type: String, isBestRate: Boolean): KNode = child {
|
||||
hasTestTag(SelectSwapProviderBottomSheetTestTags.PROVIDER_ITEM)
|
||||
hasAnyDescendant(withText(name))
|
||||
hasAnyDescendant(withText(type))
|
||||
if (isBestRate) {
|
||||
hasAnyDescendant(withTestTag(SelectSwapProviderBottomSheetTestTags.BEST_RATE_LABEL))
|
||||
}
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onSelectSwapProviderBottomSheet(function: SelectSwapProviderBottomSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -23,6 +23,11 @@ class SendAddressPageObject(semanticsProvider: SemanticsNodeInteractionsProvider
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val closeButton: KNode = child {
|
||||
hasTestTag(TopAppBarTestTags.CLOSE_BUTTON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val addressesShimmer: KNode = child {
|
||||
hasTestTag(SendAddressScreenTestTags.ADDRESSES_SHIMMER)
|
||||
useUnmergedTree = true
|
||||
|
|
|
|||
|
|
@ -96,6 +96,21 @@ class SendConfirmPageObject(semanticsProvider: SemanticsNodeInteractionsProvider
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val provider: KNode = child {
|
||||
hasText(getResourceString(R.string.express_provider))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val providerName: KNode = child {
|
||||
hasTestTag(SendConfirmScreenTestTags.PROVIDER_NAME)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val bestRateBadge: KNode = child {
|
||||
hasTestTag(SendConfirmScreenTestTags.BEST_RATE_BADGE)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val blockchainAddress: KNode = child {
|
||||
hasTestTag(SendConfirmScreenTestTags.BLOCKCHAIN_ADDRESS)
|
||||
useUnmergedTree = true
|
||||
|
|
@ -134,6 +149,7 @@ class SendConfirmPageObject(semanticsProvider: SemanticsNodeInteractionsProvider
|
|||
hasTestTag(BaseButtonTestTags.BUTTON)
|
||||
hasText(getResourceString(CoreUiR.string.warning_button_refresh))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onSendConfirmScreen(function: SendConfirmPageObject.() -> Unit) =
|
||||
|
|
|
|||
|
|
@ -74,6 +74,22 @@ class SendPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val swapToAnotherTokenButton: KNode = child {
|
||||
hasTestTag(SendScreenTestTags.SWAP_TO_ANOTHER_TOKEN_BUTTON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun swapTokenName(tokenName: String): KNode = child {
|
||||
hasTestTag(SendScreenTestTags.SWAP_TOKEN_NAME)
|
||||
hasText(tokenName)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val closeConvertIcon: KNode = child {
|
||||
hasTestTag(SendScreenTestTags.CLOSE_CONVERT_ICON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val nextButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.BUTTON)
|
||||
hasAnyDescendant(withText(getResourceString(SendR.string.common_next)))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.BaseSearchBarTestTags
|
||||
import com.tangem.core.ui.test.ManageTokensScreenTestTags
|
||||
import com.tangem.core.ui.test.TopAppBarTestTags
|
||||
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 SendViaSwapPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<SendViaSwapPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val closeButton: KNode = child {
|
||||
hasTestTag(TopAppBarTestTags.CLOSE_BUTTON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
||||
val searchField: KNode = child {
|
||||
hasTestTag(BaseSearchBarTestTags.SEARCH_BAR)
|
||||
}
|
||||
|
||||
fun tokenItem(tokenName: String): KNode = child {
|
||||
hasTestTag(ManageTokensScreenTestTags.NETWORK_NAME)
|
||||
hasAnyChild(withText(tokenName))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onSendViaSwapScreen(function: SendViaSwapPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.test.BaseButtonTestTags
|
||||
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 io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
|
||||
class WarningBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<WarningBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val icon: KNode = child {
|
||||
hasTestTag(WarningBottomSheetTestTags.ICON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun title(title: String): KNode = child {
|
||||
hasTestTag(WarningBottomSheetTestTags.TITLE)
|
||||
hasText(title)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun message(message: String): KNode = child {
|
||||
hasTestTag(WarningBottomSheetTestTags.MESSAGE)
|
||||
hasText(message)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val gotItButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasText(getResourceString(R.string.warning_button_ok))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onWarningBottomSheet(function: WarningBottomSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -0,0 +1,372 @@
|
|||
package com.tangem.tests.send.sendViaSwap
|
||||
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.R
|
||||
import com.tangem.common.extensions.extractText
|
||||
import com.tangem.common.constants.TestConstants.ETHEREUM_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.SOLANA_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.scenarios.openSendConfirmScreenViaNextButton
|
||||
import com.tangem.scenarios.openSendScreen
|
||||
import com.tangem.screens.*
|
||||
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 SendViaSwapTest : BaseTestCase() {
|
||||
|
||||
@AllureId("3970")
|
||||
@DisplayName("Send via Swap: check unsupported token error")
|
||||
@Test
|
||||
fun unsupportedTokenErrorTest() {
|
||||
val tokenName = "Bitcoin"
|
||||
val stellar = "Stellar"
|
||||
val bitcoinBalanceScenarioName = "bitcoin_utxo"
|
||||
val bitcoinBalanceScenarioState = "Balance"
|
||||
val assetsScenarioName = "express_api_assets"
|
||||
val assetsScenarioState = "BitcoinExchangeEnabled"
|
||||
val warningTitle = getResourceString(R.string.express_swap_not_supported_title, stellar)
|
||||
val warningMessage = getResourceString(R.string.express_swap_not_supported_text)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(bitcoinBalanceScenarioName)
|
||||
resetWireMockScenarioState(assetsScenarioName)
|
||||
}
|
||||
).run {
|
||||
|
||||
step("Set WireMock scenario: '$bitcoinBalanceScenarioName' to state: '$bitcoinBalanceScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = bitcoinBalanceScenarioName, state = bitcoinBalanceScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$assetsScenarioName' to state: '$assetsScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = assetsScenarioName, state = assetsScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
}
|
||||
step("Click on 'Swap to another token button'") {
|
||||
onSendScreen { swapToAnotherTokenButton.performClick() }
|
||||
}
|
||||
step("Click on token: '$stellar'") {
|
||||
onSendViaSwapScreen { tokenItem(stellar).performClick() }
|
||||
}
|
||||
step("Assert warning bottom sheet icon is displayed") {
|
||||
onWarningBottomSheet { icon.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert warning bottom sheet title is displayed") {
|
||||
onWarningBottomSheet { title(warningTitle).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert warning bottom sheet message is displayed") {
|
||||
onWarningBottomSheet { message(warningMessage).assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Ok, Got it!' button") {
|
||||
onWarningBottomSheet { gotItButton.performClick() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("3968")
|
||||
@DisplayName("Send via Swap: flow with token search and data changes")
|
||||
@Test
|
||||
fun sendViaSwapFlowWithTokenSearchAndDataChangesTest() {
|
||||
val tokenName = "Bitcoin"
|
||||
val swapTokenName = "Ethereum"
|
||||
val main = "MAIN"
|
||||
val firstInputAmount = "0.001"
|
||||
val secondInputAmount = "0.002"
|
||||
val bestRateProviderName = "SimpleSwap"
|
||||
val regularProviderName = "ChangeHero"
|
||||
val cexType = "CEX"
|
||||
val fastSelectorItem = getResourceString(R.string.common_fee_selector_option_fast)
|
||||
var capturedFastFee: String? = null
|
||||
val bitcoinBalanceScenarioName = "bitcoin_utxo"
|
||||
val bitcoinBalanceScenarioState = "Balance"
|
||||
val assetsScenarioName = "express_api_assets"
|
||||
val assetsScenarioState = "BitcoinExchangeEnabled"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(bitcoinBalanceScenarioName)
|
||||
resetWireMockScenarioState(assetsScenarioName)
|
||||
}
|
||||
).run {
|
||||
|
||||
step("Set WireMock scenario: '$bitcoinBalanceScenarioName' to state: '$bitcoinBalanceScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = bitcoinBalanceScenarioName, state = bitcoinBalanceScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$assetsScenarioName' to state: '$assetsScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = assetsScenarioName, state = assetsScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
}
|
||||
step("Type '$firstInputAmount' in text field") {
|
||||
onSendScreen { amountInputTextField.performTextInput(firstInputAmount) }
|
||||
}
|
||||
step("Click on 'Swap to another token' button") {
|
||||
onSendScreen { swapToAnotherTokenButton.performClick() }
|
||||
}
|
||||
step("Type '$swapTokenName' in search text field") {
|
||||
onSendViaSwapScreen {
|
||||
searchField.performClick()
|
||||
searchField.performTextInput(swapTokenName)
|
||||
}
|
||||
}
|
||||
step("Click on token: '$swapTokenName'") {
|
||||
onSendViaSwapScreen { tokenItem(swapTokenName).performClick() }
|
||||
}
|
||||
step("Click on '$swapTokenName $main' network") {
|
||||
onChooseNetworkBottomSheet { networkItem(swapTokenName, main).performClick() }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendScreen {
|
||||
nextButton.assertIsEnabled()
|
||||
nextButton.performClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Type recipient address") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(ETHEREUM_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Open 'Send confirm' screen via 'Next' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
openSendConfirmScreenViaNextButton()
|
||||
}
|
||||
}
|
||||
step("Assert 'Best rate' badge is displayed") {
|
||||
onSendConfirmScreen { bestRateBadge.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Provider'") {
|
||||
onSendConfirmScreen { provider.performClick() }
|
||||
}
|
||||
step("Assert '$bestRateProviderName' is displayed") {
|
||||
onSelectSwapProviderBottomSheet {
|
||||
providerItem(
|
||||
name = bestRateProviderName,
|
||||
type = cexType,
|
||||
isBestRate = true
|
||||
).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
step("Click on '$regularProviderName'") {
|
||||
onSelectSwapProviderBottomSheet {
|
||||
providerItem(
|
||||
name = regularProviderName,
|
||||
type = cexType,
|
||||
isBestRate = false
|
||||
).performClick()
|
||||
}
|
||||
}
|
||||
step("Assert provider name is '$regularProviderName'") {
|
||||
onSendConfirmScreen { providerName.assertTextContains(regularProviderName) }
|
||||
}
|
||||
step("Assert 'Best rate' badge is not displayed") {
|
||||
onSendConfirmScreen { bestRateBadge.assertIsNotDisplayed() }
|
||||
}
|
||||
step("Assert provider name is '$regularProviderName'") {
|
||||
onSendConfirmScreen { providerName.assertTextContains(regularProviderName) }
|
||||
}
|
||||
step("Click on fee selector icon") {
|
||||
onSendConfirmScreen { feeSelectorIcon.performClick() }
|
||||
}
|
||||
step("Click on '$fastSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(fastSelectorItem).performClick() }
|
||||
}
|
||||
step("Capture fast fee value") {
|
||||
onSendConfirmScreen { capturedFastFee = feeAmount.extractText() }
|
||||
}
|
||||
step("Click on send amount") {
|
||||
onSendConfirmScreen { primaryAmount.performClick() }
|
||||
}
|
||||
step("Click on swap token '$tokenName'") {
|
||||
onSendScreen { swapTokenName(tokenName).performClick() }
|
||||
}
|
||||
step("Type '$secondInputAmount' in text field") {
|
||||
onSendScreen { amountInputTextField.performTextReplacement(secondInputAmount) }
|
||||
}
|
||||
step("Click on 'Continue' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendScreen {
|
||||
continueButton.assertIsDisplayed()
|
||||
continueButton.assertIsEnabled()
|
||||
continueButton.performClick()
|
||||
}
|
||||
onSendConfirmScreen { sendButton.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Assert 'Best rate' badge is displayed") {
|
||||
onSendConfirmScreen { bestRateBadge.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert provider name is '$bestRateProviderName'") {
|
||||
onSendConfirmScreen { providerName.assertTextContains(bestRateProviderName) }
|
||||
}
|
||||
step("Assert fee is equal to previously captured fast fee") {
|
||||
val expectedFee = requireNotNull(capturedFastFee) { "Fast fee was not captured" }
|
||||
onSendConfirmScreen { feeAmount.assertTextContains(expectedFee) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("3969")
|
||||
@DisplayName("Send via Swap: flow cancel and return")
|
||||
@Test
|
||||
fun sendViaSwapCancelAndReturnFlowTest() {
|
||||
val tokenName = "Bitcoin"
|
||||
val firstSwapTokenName = "Ethereum"
|
||||
val secondSwapTokenName = "Solana"
|
||||
val main = "MAIN"
|
||||
val inputAmount = "0.001"
|
||||
val bitcoinBalanceScenarioName = "bitcoin_utxo"
|
||||
val bitcoinBalanceScenarioState = "Balance"
|
||||
val assetsScenarioName = "express_api_assets"
|
||||
val assetsScenarioState = "BitcoinExchangeEnabled"
|
||||
val dialogTitle = getResourceString(R.string.send_with_swap_change_token_alert_title)
|
||||
val dialogMessage = getResourceString(R.string.send_with_swap_change_token_alert_message)
|
||||
val addressHint = getResourceString(R.string.send_enter_address_field_ens)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(bitcoinBalanceScenarioName)
|
||||
resetWireMockScenarioState(assetsScenarioName)
|
||||
}
|
||||
).run {
|
||||
|
||||
step("Set WireMock scenario: '$bitcoinBalanceScenarioName' to state: '$bitcoinBalanceScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = bitcoinBalanceScenarioName, state = bitcoinBalanceScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$assetsScenarioName' to state: '$assetsScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = assetsScenarioName, state = assetsScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
}
|
||||
step("Type '$inputAmount' in text field") {
|
||||
onSendScreen { amountInputTextField.performTextInput(inputAmount) }
|
||||
}
|
||||
step("Click on 'Swap to another token' button") {
|
||||
onSendScreen { swapToAnotherTokenButton.performClick() }
|
||||
}
|
||||
step("Click on token: '$firstSwapTokenName'") {
|
||||
onSendViaSwapScreen { tokenItem(firstSwapTokenName).performClick() }
|
||||
}
|
||||
step("Click on '$firstSwapTokenName $main' network") {
|
||||
onChooseNetworkBottomSheet { networkItem(firstSwapTokenName, main).performClick() }
|
||||
}
|
||||
step("Click on 'Close convert' button") {
|
||||
onSendScreen { closeConvertIcon.performClick() }
|
||||
}
|
||||
step("Assert 'Swap to another token' button is displayed") {
|
||||
onSendScreen { swapToAnotherTokenButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert amount: '$inputAmount'") {
|
||||
onSendScreen { amountInputTextField.assertTextContains(inputAmount) }
|
||||
}
|
||||
step("Click on 'Swap to another token' button") {
|
||||
onSendScreen { swapToAnotherTokenButton.performClick() }
|
||||
}
|
||||
step("Click on token: '$secondSwapTokenName'") {
|
||||
onSendViaSwapScreen { tokenItem(secondSwapTokenName).performClick() }
|
||||
}
|
||||
step("Click on '$secondSwapTokenName $main' network") {
|
||||
onChooseNetworkBottomSheet { networkItem(secondSwapTokenName, main).performClick() }
|
||||
}
|
||||
step("Click on token '$tokenName'") {
|
||||
onSendScreen { swapTokenName(tokenName).performClick() }
|
||||
}
|
||||
step("Type '$inputAmount' in text field") {
|
||||
onSendScreen { amountInputTextField.performTextInput(inputAmount) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendScreen {
|
||||
nextButton.assertIsEnabled()
|
||||
nextButton.performClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Type recipient address") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(SOLANA_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Open 'Send confirm' screen via 'Next' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
openSendConfirmScreenViaNextButton()
|
||||
}
|
||||
}
|
||||
step("Click on 'Amount to receive'") {
|
||||
onSendConfirmScreen { secondaryAmount.performClick() }
|
||||
}
|
||||
step("Click on token '$secondSwapTokenName' to open 'Send via Swap' screen") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendScreen { swapTokenName(secondSwapTokenName).performClick() }
|
||||
onSendViaSwapScreen { tokenItem(firstSwapTokenName).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Click on token: '$firstSwapTokenName'") {
|
||||
onSendViaSwapScreen { tokenItem(firstSwapTokenName).performClick() }
|
||||
}
|
||||
step("Click on '$firstSwapTokenName $main' network") {
|
||||
onChooseNetworkBottomSheet { networkItem(firstSwapTokenName, main).performClick() }
|
||||
}
|
||||
step("Assert '$dialogTitle' dialog title is displayed") {
|
||||
onDialog { title.assertTextEquals(dialogTitle) }
|
||||
}
|
||||
step("Assert '$dialogMessage' dialog message is displayed") {
|
||||
onDialog { text.assertTextEquals(dialogMessage) }
|
||||
}
|
||||
step("Click on 'Cancel' button") {
|
||||
onDialog { cancelButton.performClick() }
|
||||
}
|
||||
step("Click on 'Close' button") {
|
||||
onSendViaSwapScreen { closeButton.performClick() }
|
||||
}
|
||||
step("Click on 'Continue' button") {
|
||||
onSendScreen { continueButton.performClick() }
|
||||
}
|
||||
step("Assert recipient address is displayed") {
|
||||
onSendConfirmScreen { recipientAddress(SOLANA_RECIPIENT_ADDRESS).assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Amount to receive'") {
|
||||
onSendConfirmScreen { secondaryAmount.performClick() }
|
||||
}
|
||||
step("Click on token '$secondSwapTokenName' to open 'Send via Swap' screen") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendScreen { swapTokenName(secondSwapTokenName).performClick() }
|
||||
onSendViaSwapScreen { tokenItem(firstSwapTokenName).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Click on token: $firstSwapTokenName") {
|
||||
onSendViaSwapScreen { tokenItem(firstSwapTokenName).performClick() }
|
||||
}
|
||||
step("Click on '$firstSwapTokenName $main' network") {
|
||||
onChooseNetworkBottomSheet { networkItem(firstSwapTokenName, main).performClick() }
|
||||
}
|
||||
step("Click on 'Change' button") {
|
||||
onDialog { changeButton.performClick() }
|
||||
}
|
||||
step("Assert '$firstSwapTokenName' is displayed") {
|
||||
onSendScreen { swapTokenName(firstSwapTokenName).assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Next' button to open 'Send address' screen") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendScreen {
|
||||
nextButton.assertIsEnabled()
|
||||
nextButton.performClick()
|
||||
}
|
||||
onSendAddressScreen { container.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Assert address text field is empty and hint is displayed") {
|
||||
onSendAddressScreen { addressTextFieldHint.assertTextContains(addressHint) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
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
|
||||
|
|
@ -32,6 +33,7 @@ import com.tangem.core.ui.extensions.resolveAnnotatedReference
|
|||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.WarningBottomSheetTestTags
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
|
|
@ -99,7 +101,8 @@ private fun ContentContainer(state: MessageBottomSheetUM.InfoBlock, modifier: Mo
|
|||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing24),
|
||||
.padding(top = TangemTheme.dimens.spacing24)
|
||||
.testTag(WarningBottomSheetTestTags.TITLE),
|
||||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography.h3,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
|
|
@ -110,7 +113,8 @@ private fun ContentContainer(state: MessageBottomSheetUM.InfoBlock, modifier: Mo
|
|||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing8),
|
||||
.padding(top = TangemTheme.dimens.spacing8)
|
||||
.testTag(WarningBottomSheetTestTags.MESSAGE),
|
||||
text = body.resolveAnnotatedReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.test.WarningBottomSheetTestTags
|
||||
|
||||
@Composable
|
||||
fun HighlightedIcon(
|
||||
|
|
@ -25,7 +27,8 @@ fun HighlightedIcon(
|
|||
modifier = modifier
|
||||
.size(TangemTheme.dimens.size56)
|
||||
.clip(CircleShape)
|
||||
.background(backgroundColor.copy(alpha = 0.1F)),
|
||||
.background(backgroundColor.copy(alpha = 0.1F))
|
||||
.testTag(WarningBottomSheetTestTags.ICON),
|
||||
contentAlignment = Alignment.Center,
|
||||
content = {
|
||||
Icon(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.core.ui.test
|
||||
|
||||
object ChooseNetworkBottomSheetTestTags {
|
||||
const val NETWORK_ITEM = "CHOOSE_NETWORK_BOTTOM_SHEET_NETWORK_ITEM"
|
||||
const val NETWORK_ICON = "CHOOSE_NETWORK_BOTTOM_SHEET_NETWORK_ICON"
|
||||
const val NETWORK_TITLE = "CHOOSE_NETWORK_BOTTOM_SHEET_NETWORK_TITLE"
|
||||
const val NETWORK_SUBTITLE = "CHOOSE_NETWORK_BOTTOM_SHEET_NETWORK_SUBTITLE"
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.core.ui.test
|
||||
|
||||
object SelectSwapProviderBottomSheetTestTags {
|
||||
|
||||
const val PROVIDER_NAME = "SELECT_SWAP_PROVIDER_BOTTOM_SHEET_PROVIDER_NAME"
|
||||
const val PROVIDER_TYPE = "SELECT_SWAP_PROVIDER_BOTTOM_SHEET_PROVIDER_TYPE"
|
||||
const val BEST_RATE_LABEL = "SELECT_SWAP_PROVIDER_BOTTOM_SHEET_BEST_RATE_LABEL"
|
||||
const val AMOUNT = "SELECT_SWAP_PROVIDER_BOTTOM_SHEET_AMOUNT"
|
||||
const val PROVIDER_ITEM = "SELECT_SWAP_PROVIDER_BOTTOM_SHEET_PROVIDER_ITEM"
|
||||
}
|
||||
|
|
@ -5,4 +5,6 @@ object SendConfirmScreenTestTags {
|
|||
const val RECIPIENT_ADDRESS = "SEND_CONFIRM_SCREEN_RECIPIENT_ADDRESS"
|
||||
const val BLOCKCHAIN_ADDRESS = "SEND_CONFIRM_SCREEN_BLOCKCHAIN_ADDRESS"
|
||||
const val RECIPIENT_ADDRESS_ICON = "SEND_CONFIRM_SCREEN_RECIPIENT_ADDRESS_ICON"
|
||||
const val PROVIDER_NAME = "SEND_CONFIRM_SCREEN_PROVIDER_NAME"
|
||||
const val BEST_RATE_BADGE = "SEND_CONFIRM_SCREEN_BEST_RATE_BADGE"
|
||||
}
|
||||
|
|
@ -14,4 +14,8 @@ object SendScreenTestTags {
|
|||
|
||||
const val MAX_BUTTON = "SEND_SCREEN_MAX_BUTTON"
|
||||
const val PREVIOUS_BUTTON = "SEND_SCREEN_PREVIOUS_BUTTON"
|
||||
|
||||
const val SWAP_TO_ANOTHER_TOKEN_BUTTON = "SEND_SCREEN_SWAP_TO_ANOTHER_TOKEN_BUTTON"
|
||||
const val SWAP_TOKEN_NAME = "SEND_SCREEN_SWAP_TOKEN_NAME"
|
||||
const val CLOSE_CONVERT_ICON = "SEND_SCREEN_CLOSE_CONVERT_ICON"
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.core.ui.test
|
||||
|
||||
object WarningBottomSheetTestTags {
|
||||
const val ICON = "BASE_WARNING_BOTTOM_SHEET_ICON"
|
||||
const val TITLE = "BASE_WARNING_BOTTOM_SHEET_TITLE"
|
||||
const val MESSAGE = "BASE_WARNING_BOTTOM_SHEET_MESSAGE"
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -23,6 +24,7 @@ import com.tangem.core.ui.components.SpacerH
|
|||
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.SendScreenTestTags
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.amount.model.SendAmountClickIntents
|
||||
import com.tangem.features.send.v2.subcomponents.amount.ui.preview.SendAmountClickIntentsStub
|
||||
|
|
@ -65,7 +67,8 @@ private fun SendConvertTokenButton(onConvertToAnother: () -> Unit) {
|
|||
Row(
|
||||
modifier = Modifier
|
||||
.padding(12.dp)
|
||||
.align(Alignment.Center),
|
||||
.align(Alignment.Center)
|
||||
.testTag(SendScreenTestTags.SWAP_TO_ANOTHER_TOKEN_BUTTON),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -39,6 +40,7 @@ import com.tangem.core.ui.extensions.resolveReference
|
|||
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.SendScreenTestTags
|
||||
import com.tangem.domain.express.models.ExpressRateType
|
||||
import com.tangem.features.swap.v2.impl.R
|
||||
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountFieldUM
|
||||
|
|
@ -131,7 +133,9 @@ private fun SwapAmountBlockSeparator(onClick: () -> Unit, modifier: Modifier = M
|
|||
),
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
modifier = Modifier
|
||||
.size(16.dp)
|
||||
.testTag(SendScreenTestTags.CLOSE_CONVERT_ICON),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -333,6 +337,7 @@ private fun SwapAmountInfoMain(
|
|||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
modifier = Modifier.testTag(SendScreenTestTags.SWAP_TOKEN_NAME),
|
||||
)
|
||||
} else {
|
||||
TextShimmer(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -40,6 +41,7 @@ import com.tangem.core.ui.extensions.stringResourceSafe
|
|||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.SendConfirmScreenTestTags
|
||||
import com.tangem.domain.express.models.ExpressProvider
|
||||
import com.tangem.domain.express.models.ExpressProviderType
|
||||
import com.tangem.domain.express.models.ExpressRateType
|
||||
|
|
@ -171,7 +173,8 @@ private fun ProviderInfo(
|
|||
top.linkTo(parent.top)
|
||||
bottom.linkTo(parent.bottom)
|
||||
end.linkTo(iconRef.start, goneMargin = 12.dp)
|
||||
},
|
||||
}
|
||||
.testTag(SendConfirmScreenTestTags.PROVIDER_NAME),
|
||||
)
|
||||
Icon(
|
||||
painter = rememberVectorPainter(
|
||||
|
|
@ -287,7 +290,8 @@ private fun ConstraintLayoutScope.BestRateBadge(
|
|||
tint = TangemTheme.colors.icon.constant,
|
||||
modifier = Modifier
|
||||
.padding(iconHorizontalPaddings, iconVerticalPaddings)
|
||||
.size(iconSize),
|
||||
.size(iconSize)
|
||||
.testTag(SendConfirmScreenTestTags.BEST_RATE_BADGE),
|
||||
)
|
||||
AnimatedVisibility(
|
||||
visibleState = animateState,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -25,6 +26,7 @@ import com.tangem.core.ui.extensions.stringReference
|
|||
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.SelectSwapProviderBottomSheetTestTags
|
||||
import com.tangem.features.swap.v2.impl.chooseprovider.entity.SwapProviderState
|
||||
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
|
||||
|
||||
|
|
@ -45,7 +47,9 @@ internal fun SwapProviderItem(state: SwapProviderState, modifier: Modifier = Mod
|
|||
@Composable
|
||||
private fun ProviderContentState(state: SwapProviderState.Content, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(SelectSwapProviderBottomSheetTestTags.PROVIDER_ITEM),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
SubcomposeAsyncImage(
|
||||
|
|
@ -67,12 +71,15 @@ private fun ProviderContentState(state: SwapProviderState.Content, modifier: Mod
|
|||
text = state.name,
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
modifier = Modifier.testTag(SelectSwapProviderBottomSheetTestTags.PROVIDER_NAME),
|
||||
)
|
||||
Text(
|
||||
text = state.type,
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(start = 4.dp),
|
||||
modifier = Modifier
|
||||
.padding(start = 4.dp)
|
||||
.testTag(SelectSwapProviderBottomSheetTestTags.PROVIDER_TYPE),
|
||||
)
|
||||
val badgeModifier = Modifier.padding(start = 4.dp)
|
||||
when (state.additionalBadge) {
|
||||
|
|
@ -91,6 +98,7 @@ private fun ProviderContentState(state: SwapProviderState.Content, modifier: Mod
|
|||
color = TangemTheme.colors.text.tertiary,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
modifier = Modifier.testTag(SelectSwapProviderBottomSheetTestTags.AMOUNT),
|
||||
)
|
||||
|
||||
if (state.diffPercent is SwapQuoteUM.Content.DifferencePercent.Diff) {
|
||||
|
|
@ -143,7 +151,9 @@ private fun BestTradeItem(modifier: Modifier = Modifier) {
|
|||
text = stringResourceSafe(R.string.express_provider_best_rate),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
modifier = Modifier.padding(horizontal = 6.dp),
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 6.dp)
|
||||
.testTag(SelectSwapProviderBottomSheetTestTags.BEST_RATE_LABEL),
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -31,6 +32,7 @@ import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
|||
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.ChooseNetworkBottomSheetTestTags
|
||||
import com.tangem.features.swap.v2.impl.R
|
||||
import com.tangem.features.swap.v2.impl.choosetoken.fromSupported.entity.SwapChooseNetworkUM
|
||||
import com.tangem.features.swap.v2.impl.choosetoken.fromSupported.entity.SwapChooseTokenNetworkContentUM
|
||||
|
|
@ -116,15 +118,20 @@ private fun SwapChooseTokenNetworkContentList(swapNetworks: ImmutableList<SwapCh
|
|||
indication = ripple(),
|
||||
onClick = { network.onNetworkClick() },
|
||||
)
|
||||
.padding(vertical = 12.dp, horizontal = 14.dp),
|
||||
.padding(vertical = 12.dp, horizontal = 14.dp)
|
||||
.testTag(ChooseNetworkBottomSheetTestTags.NETWORK_ITEM),
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.size(36.dp),
|
||||
modifier = Modifier
|
||||
.size(36.dp)
|
||||
.testTag(ChooseNetworkBottomSheetTestTags.NETWORK_ICON),
|
||||
painter = painterResource(id = network.iconResId),
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 6.dp),
|
||||
modifier = Modifier
|
||||
.padding(start = 6.dp)
|
||||
.testTag(ChooseNetworkBottomSheetTestTags.NETWORK_TITLE),
|
||||
text = network.title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
|
|
@ -137,6 +144,7 @@ private fun SwapChooseTokenNetworkContentList(swapNetworks: ImmutableList<SwapCh
|
|||
} else {
|
||||
TangemTheme.colors.text.tertiary
|
||||
},
|
||||
modifier = Modifier.testTag(ChooseNetworkBottomSheetTestTags.NETWORK_SUBTITLE),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue