Updated on 2026-08-14
This commit is contained in:
parent
82506a1c9c
commit
01b51acd93
13 changed files with 238 additions and 143 deletions
|
|
@ -10,9 +10,14 @@ import com.tangem.common.extensions.assertIsDimmed
|
|||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.screens.*
|
||||
import com.tangem.tap.domain.sdk.mocks.MockContent
|
||||
import io.qameta.allure.kotlin.Allure.step
|
||||
|
||||
fun BaseTestCase.openSendScreen(tokenName: String, mockState: String = "") {
|
||||
fun BaseTestCase.openSendScreen(
|
||||
tokenName: String,
|
||||
mockState: String = "",
|
||||
mockContent: MockContent? = null,
|
||||
) {
|
||||
val scenarioState = mockState.ifEmpty { tokenName }
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$scenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = scenarioState)
|
||||
|
|
@ -21,7 +26,7 @@ fun BaseTestCase.openSendScreen(tokenName: String, mockState: String = "") {
|
|||
setWireMockScenarioState(scenarioName = QUOTES_API_SCENARIO, state = scenarioState)
|
||||
}
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
openMainScreen(mockContent = mockContent)
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
|
|
|
|||
|
|
@ -297,6 +297,15 @@ fun BaseTestCase.checkSwapWarning(
|
|||
}
|
||||
}
|
||||
|
||||
fun BaseTestCase.chooseReceiveToken(tokenName: String) {
|
||||
step("Click on 'Choose token' button") {
|
||||
onSwapTokenScreen { chooseTokenButton.performClick() }
|
||||
}
|
||||
step("Click on token with name '$tokenName'") {
|
||||
onSwapSelectTokenScreen { tokenWithName(tokenName).performClick() }
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SwapEntryPoint {
|
||||
object MainScreen : SwapEntryPoint()
|
||||
object TokenDetails : SwapEntryPoint()
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
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.AppBarWithSearchTestTags
|
||||
import com.tangem.core.ui.test.BuyTokenScreenTestTags
|
||||
import com.tangem.core.ui.test.MarketsTestTags
|
||||
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 SwapChooseTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<SwapChooseTokenPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val title: KNode = child {
|
||||
hasText(getResourceString(R.string.common_choose_token))
|
||||
}
|
||||
|
||||
val myTokensTitle: KNode = child {
|
||||
hasText(getResourceString(R.string.exchange_tokens_available_tokens_header))
|
||||
}
|
||||
|
||||
val searchIcon: KNode = child {
|
||||
hasTestTag(AppBarWithSearchTestTags.SEARCH_ICON)
|
||||
}
|
||||
|
||||
val searchTextField: KNode = child {
|
||||
hasTestTag(AppBarWithSearchTestTags.TEXT_FIELD)
|
||||
}
|
||||
|
||||
val noTokensFoundText: KNode = child {
|
||||
hasText(getResourceString(R.string.express_token_list_empty_search))
|
||||
}
|
||||
|
||||
fun tokenWithTitle(tokenTitle: String, availableForSwap: Boolean = true): KNode = child {
|
||||
hasTestTag(BuyTokenScreenTestTags.LAZY_LIST_ITEM)
|
||||
hasAnyDescendant(withText(tokenTitle))
|
||||
if (!availableForSwap) {
|
||||
hasAnyDescendant(
|
||||
withText(
|
||||
getResourceString(R.string.tokens_list_unavailable_to_swap_source_header)
|
||||
)
|
||||
)
|
||||
}
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun marketsTokenWithTitle(title: String): KNode {
|
||||
return child {
|
||||
hasTestTag(MarketsTestTags.TOKENS_LIST_ITEM)
|
||||
hasText(title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onSwapChooseTokenScreen(function: SwapChooseTokenPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -29,8 +29,8 @@ class SwapSelectTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProv
|
|||
}
|
||||
|
||||
val youSwapBlock: KNode = child {
|
||||
hasTestTag(SwapSelectTokenScreenTestTags.YOU_SWAP_BLOCK)
|
||||
hasAnyDescendant(withText(getResourceString(R.string.action_buttons_you_want_to_swap)))
|
||||
hasTestTag(SwapTokenScreenTestTags.SWAP_CARD)
|
||||
hasAnyDescendant(withText(getResourceString(R.string.swapping_from_title)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
|
@ -40,8 +40,8 @@ class SwapSelectTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProv
|
|||
}
|
||||
|
||||
val youReceiveBlock: KNode = child {
|
||||
hasTestTag(SwapSelectTokenScreenTestTags.YOU_SWAP_BLOCK)
|
||||
hasAnyDescendant(withText(getResourceString(R.string.action_buttons_you_want_to_receive)))
|
||||
hasTestTag(SwapTokenScreenTestTags.RECEIVE_CARD)
|
||||
hasAnyDescendant(withText(getResourceString(R.string.swapping_to_title)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -174,8 +174,16 @@ class SwapTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
hasTestTag(SwapTokenScreenTestTags.SWAP_FIAT_AMOUNT)
|
||||
}
|
||||
|
||||
val selectTokenIcon: KNode = child {
|
||||
val swapSelectTokenIcon: KNode = child {
|
||||
hasAnyAncestor(withTestTag(SwapTokenScreenTestTags.SWAP_CARD))
|
||||
hasTestTag(SwapTokenScreenTestTags.SELECT_TOKEN_ICON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val receiveSelectTokenIcon: KNode = child {
|
||||
hasAnyAncestor(withTestTag(SwapTokenScreenTestTags.RECEIVE_CARD))
|
||||
hasTestTag(SwapTokenScreenTestTags.SELECT_TOKEN_ICON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun swapTokenSymbol(symbol: String): KNode = child {
|
||||
|
|
@ -191,6 +199,11 @@ class SwapTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
hasText(symbol)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val chooseTokenButton: KNode = child {
|
||||
hasText(getResourceString(R.string.common_choose_token))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onSwapTokenScreen(function: SwapTokenPageObject.() -> Unit) =
|
||||
|
|
|
|||
|
|
@ -6,15 +6,16 @@ import com.tangem.common.constants.TestConstants.ETHEREUM_RECIPIENT_ADDRESS
|
|||
import com.tangem.common.constants.TestConstants.POLYGON_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.QUOTES_API_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.SOLANA_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.SVS_SEED_PHRASE_12
|
||||
import com.tangem.common.constants.TestConstants.USER_TOKENS_API_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.SVS_SEED_PHRASE_12
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.extensions.extractText
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.scenarios.*
|
||||
import com.tangem.screens.*
|
||||
import com.tangem.tap.domain.sdk.mocks.content.Wallet2WithDerivationsMockContent
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
import io.qameta.allure.kotlin.AllureId
|
||||
|
|
@ -34,6 +35,7 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
val bitcoinBalanceScenarioState = "Balance"
|
||||
val assetsScenarioName = "express_api_assets"
|
||||
val assetsScenarioState = "BitcoinExchangeEnabled"
|
||||
val userTokensScenarioState = "Wallet2"
|
||||
val warningTitle = getResourceString(R.string.express_swap_not_supported_title, stellar)
|
||||
val warningMessage = getResourceString(R.string.express_swap_not_supported_text)
|
||||
|
||||
|
|
@ -41,6 +43,7 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(bitcoinBalanceScenarioName)
|
||||
resetWireMockScenarioState(assetsScenarioName)
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
|
||||
|
|
@ -50,9 +53,11 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
step("Set WireMock scenario: '$assetsScenarioName' to state: '$assetsScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = assetsScenarioName, state = assetsScenarioState)
|
||||
}
|
||||
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$userTokensScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = userTokensScenarioState)
|
||||
}
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
openSendScreen(tokenName, mockContent = Wallet2WithDerivationsMockContent)
|
||||
}
|
||||
step("Click on 'Swap to another token button'") {
|
||||
onSendScreen { swapToAnotherTokenButton.performClick() }
|
||||
|
|
@ -93,11 +98,13 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
val bitcoinBalanceScenarioState = "Balance"
|
||||
val assetsScenarioName = "express_api_assets"
|
||||
val assetsScenarioState = "BitcoinExchangeEnabled"
|
||||
val userTokensScenarioState = "Wallet2"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(bitcoinBalanceScenarioName)
|
||||
resetWireMockScenarioState(assetsScenarioName)
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
|
||||
|
|
@ -107,9 +114,12 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
step("Set WireMock scenario: '$assetsScenarioName' to state: '$assetsScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = assetsScenarioName, state = assetsScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$userTokensScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = userTokensScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
openSendScreen(tokenName, mockContent = Wallet2WithDerivationsMockContent)
|
||||
}
|
||||
step("Type '$firstInputAmount' in text field") {
|
||||
onSendScreen { amountInputTextField.performTextInput(firstInputAmount) }
|
||||
|
|
@ -178,10 +188,13 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
step("Assert provider name is '$regularProviderName'") {
|
||||
onSendConfirmScreen { providerName.assertTextContains(regularProviderName) }
|
||||
}
|
||||
step("Click on fee selector icon") {
|
||||
onSendConfirmScreen { feeSelectorIcon.performClick() }
|
||||
step("Open fee selector bottom sheet via click on fee selector icon") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendConfirmScreen { feeSelectorIcon.performClick() }
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(fastSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Click on '$fastSelectorItem' selector item is displayed") {
|
||||
step("Click on '$fastSelectorItem' selector item") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(fastSelectorItem).performClick() }
|
||||
}
|
||||
step("Capture fast fee value") {
|
||||
|
|
@ -232,6 +245,7 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
val bitcoinBalanceScenarioState = "Balance"
|
||||
val assetsScenarioName = "express_api_assets"
|
||||
val assetsScenarioState = "BitcoinExchangeEnabled"
|
||||
val userTokensScenarioState = "Wallet2"
|
||||
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)
|
||||
|
|
@ -240,6 +254,7 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(bitcoinBalanceScenarioName)
|
||||
resetWireMockScenarioState(assetsScenarioName)
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
|
||||
|
|
@ -249,9 +264,12 @@ class SendViaSwapTest : BaseTestCase() {
|
|||
step("Set WireMock scenario: '$assetsScenarioName' to state: '$assetsScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = assetsScenarioName, state = assetsScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$userTokensScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = userTokensScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
openSendScreen(tokenName, mockContent = Wallet2WithDerivationsMockContent)
|
||||
}
|
||||
step("Type '$inputAmount' in text field") {
|
||||
onSendScreen { amountInputTextField.performTextInput(inputAmount) }
|
||||
|
|
|
|||
|
|
@ -238,20 +238,17 @@ class SearchAndSwapTest : BaseTestCase() {
|
|||
onSwapTokenScreen { replaceTokensButton.performClick() }
|
||||
}
|
||||
step("Click on 'Select token' icon") {
|
||||
onSwapTokenScreen { selectTokenIcon.performClick() }
|
||||
onSwapTokenScreen { swapSelectTokenIcon.performClick() }
|
||||
}
|
||||
step("Click on 'Search' icon") {
|
||||
onSwapChooseTokenScreen { searchIcon.performClick() }
|
||||
}
|
||||
step("Click on 'Search' text field") {
|
||||
onSwapChooseTokenScreen { searchTextField.performClick() }
|
||||
onSwapSelectTokenScreen { searchBarIcon.performClick() }
|
||||
}
|
||||
step("Type '$swapTokenSymbol' in 'Search' text field") {
|
||||
onSwapChooseTokenScreen { searchTextField.performTextInputInChunks(swapTokenSymbol) }
|
||||
onSwapSelectTokenScreen { searchBarBlock.performTextInputInChunks(swapTokenSymbol) }
|
||||
}
|
||||
step("Click on token with name: '$swapTokenName'") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
onSwapChooseTokenScreen { marketsTokenWithTitle(swapTokenName).performClick() }
|
||||
onSwapSelectTokenScreen { marketsTokenWithName(swapTokenName).performClick() }
|
||||
}
|
||||
}
|
||||
step("Click on 'Add' button") {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.tangem.common.BaseTestCase
|
|||
import com.tangem.common.annotations.ApiEnv
|
||||
import com.tangem.common.annotations.ApiEnvConfig
|
||||
import com.tangem.common.constants.TestConstants.USER_TOKENS_API_SCENARIO
|
||||
import com.tangem.common.extensions.*
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.datasource.api.common.config.ApiConfig
|
||||
|
|
@ -74,22 +74,22 @@ class SwapChooseTokenScreenTest : BaseTestCase() {
|
|||
}
|
||||
}
|
||||
step("Click on 'Select token' icon") {
|
||||
onSwapTokenScreen { selectTokenIcon.performClick() }
|
||||
onSwapTokenScreen { swapSelectTokenIcon.performClick() }
|
||||
}
|
||||
step("Assert '$ethereum' is displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(ethereum).assertIsDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(ethereum).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$polExMatic' is displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(polExMatic).assertIsDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(polExMatic).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$bitcoin' is not displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(bitcoin).assertIsNotDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(bitcoin).assertIsNotDisplayed() }
|
||||
}
|
||||
step("Assert '$jesusCoin' is displayed and unavailable for swap") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(tokenTitle = jesusCoin).assertIsDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(jesusCoin).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert custom token without backend id '$salam' is not displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(salam).assertIsNotDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(salam).assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -136,38 +136,35 @@ class SwapChooseTokenScreenTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Click on 'Select token' icon") {
|
||||
onSwapTokenScreen { selectTokenIcon.performClick() }
|
||||
step("Click on 'Choose token' button") {
|
||||
onSwapTokenScreen { chooseTokenButton.performClick() }
|
||||
}
|
||||
step("Click on 'Search' icon") {
|
||||
onSwapChooseTokenScreen { searchIcon.performClick() }
|
||||
}
|
||||
step("Click on 'Search' text field") {
|
||||
onSwapChooseTokenScreen { searchTextField.performClick() }
|
||||
onSwapSelectTokenScreen { searchBarIcon.performClick() }
|
||||
}
|
||||
step("Type invalid search text: '$invalidSearchText' in 'Search' text field") {
|
||||
onSwapChooseTokenScreen { searchTextField.performTextReplacement(invalidSearchText) }
|
||||
onSwapSelectTokenScreen { searchBarBlock.performTextReplacement(invalidSearchText) }
|
||||
}
|
||||
step("Assert '$ethereum' is not displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(ethereum).assertIsNotDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(ethereum).assertIsNotDisplayed() }
|
||||
}
|
||||
step("Assert '$polExMatic' is not displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(polExMatic).assertIsNotDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(polExMatic).assertIsNotDisplayed() }
|
||||
}
|
||||
step("Press 'Delete' button") {
|
||||
device.uiDevice.pressDelete()
|
||||
}
|
||||
step("Type valid search text: '$validSearchText' in 'Search' text field") {
|
||||
onSwapChooseTokenScreen { searchTextField.performTextReplacement(validSearchText) }
|
||||
onSwapSelectTokenScreen { searchBarBlock.performTextReplacement(validSearchText) }
|
||||
}
|
||||
step("Assert '$ethereum' is not displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(ethereum).assertIsNotDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(ethereum).assertIsNotDisplayed() }
|
||||
}
|
||||
step("Assert '$polExMatic' is displayed") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(polExMatic).assertIsDisplayed() }
|
||||
onSwapSelectTokenScreen { tokenWithName(polExMatic).assertIsDisplayed() }
|
||||
}
|
||||
step("Select new receive token: $polExMatic") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(polExMatic).performClick() }
|
||||
onSwapSelectTokenScreen { tokenWithName(polExMatic).performClick() }
|
||||
}
|
||||
step("Assert new receive token symbol: '$polExMaticSymbol' is displayed") {
|
||||
onSwapTokenScreen { receiveTokenSymbol(polExMaticSymbol).assertIsDisplayed() }
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ class SwapSelectTokenScreenTest : BaseTestCase() {
|
|||
@DisplayName("Open 'Swap select token' screen from 'Main' screen")
|
||||
@Test
|
||||
fun openSwapSelectTokenScreenFromMainScreenTest() {
|
||||
val swapTokenName = "Ethereum"
|
||||
val receiveTokenName = "Polygon"
|
||||
|
||||
setupHooks().run {
|
||||
|
|
@ -37,14 +36,11 @@ class SwapSelectTokenScreenTest : BaseTestCase() {
|
|||
step("Close 'Stories' screen") {
|
||||
onSwapStoriesScreen { closeButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Swap select token' screen title is displayed") {
|
||||
onSwapSelectTokenScreen { title.assertIsDisplayed() }
|
||||
step("Click on 'Choose token' button") {
|
||||
onSwapTokenScreen { chooseTokenButton.performClick() }
|
||||
}
|
||||
step("Assert 'You swap' title is displayed") {
|
||||
onSwapSelectTokenScreen { youSwapTitle.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'You swap' block is displayed") {
|
||||
onSwapSelectTokenScreen { youSwapBlock.assertIsDisplayed() }
|
||||
step("Assert 'You receive' title is displayed") {
|
||||
onSwapSelectTokenScreen { youReceiveTitle.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert search icon is displayed") {
|
||||
onSwapSelectTokenScreen { searchBarIcon.assertIsDisplayed() }
|
||||
|
|
@ -52,15 +48,6 @@ class SwapSelectTokenScreenTest : BaseTestCase() {
|
|||
step("Assert search placeholder is displayed") {
|
||||
onSwapSelectTokenScreen { searchBarPlaceholderText.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on token with name '$swapTokenName'") {
|
||||
onSwapSelectTokenScreen { tokenWithName(swapTokenName).performClick() }
|
||||
}
|
||||
step("Assert 'You receive' title is displayed") {
|
||||
onSwapSelectTokenScreen { youReceiveTitle.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'You receive' block is displayed") {
|
||||
onSwapSelectTokenScreen { youReceiveBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on token with name '$receiveTokenName'") {
|
||||
onSwapSelectTokenScreen { tokenWithName(receiveTokenName).performClick() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
fun networkFeeTest() {
|
||||
val inputAmount = "400"
|
||||
val tokenTitle = "Polygon"
|
||||
val receiveTokenName = "Ethereum"
|
||||
|
||||
setupHooks().run {
|
||||
|
||||
|
|
@ -67,13 +68,6 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
}
|
||||
}
|
||||
}
|
||||
step("Assert receive amount is displayed") {
|
||||
onSwapTokenScreen {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
receiveAmount.assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Input swap amount = '$inputAmount'") {
|
||||
waitForIdle()
|
||||
onSwapTokenScreen {
|
||||
|
|
@ -81,9 +75,19 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert input amount = '$inputAmount'") {
|
||||
onSwapTokenScreen { textInput.assertTextEquals(inputAmount) }
|
||||
}
|
||||
step("Assert receive amount is displayed") {
|
||||
onSwapTokenScreen {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
receiveAmount.assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Assert 'Providers' block is displayed") {
|
||||
onSwapTokenScreen {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
|
|
@ -175,9 +179,10 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
@Test
|
||||
fun changeNetworkFeeTest() {
|
||||
val inputAmount = "400"
|
||||
val tokenTitle = "Polygon"
|
||||
val receiveTokenName = "Ethereum"
|
||||
|
||||
setupHooks().run {
|
||||
val tokenTitle = "Polygon"
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
|
|
@ -207,13 +212,6 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
}
|
||||
}
|
||||
}
|
||||
step("Assert receive amount is displayed") {
|
||||
onSwapTokenScreen {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
receiveAmount.assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Input swap amount = '$inputAmount'") {
|
||||
waitForIdle()
|
||||
onSwapTokenScreen {
|
||||
|
|
@ -224,6 +222,16 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
step("Assert input amount = '$inputAmount'") {
|
||||
onSwapTokenScreen { textInput.assertTextEquals(inputAmount) }
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert receive amount is displayed") {
|
||||
onSwapTokenScreen {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
receiveAmount.assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Assert 'Network fee' block is displayed") {
|
||||
onSwapTokenScreen {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
|
|
@ -270,11 +278,10 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
ApiEnvConfig(ApiConfig.ID.Express, ApiEnvironment.PROD)
|
||||
)
|
||||
@AllureId("2828")
|
||||
@DisplayName("Swap: network fee")
|
||||
@DisplayName("Swap: go to token swap")
|
||||
@Test
|
||||
fun goToTokenSwapTest() {
|
||||
val swapTokenSymbol = "POL"
|
||||
val receiveTokenSymbol = "ETH"
|
||||
val tokenTitle = "Polygon"
|
||||
|
||||
setupHooks().run {
|
||||
|
|
@ -314,8 +321,8 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
step("Assert token symbol: '$swapTokenSymbol' is displayed") {
|
||||
onSwapTokenScreen { swapTokenSymbol(swapTokenSymbol).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert token symbol: '$receiveTokenSymbol' is displayed") {
|
||||
onSwapTokenScreen { receiveTokenSymbol(receiveTokenSymbol).assertIsDisplayed() }
|
||||
step("Assert 'Choose token' button is displayed") {
|
||||
onSwapTokenScreen { chooseTokenButton.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -329,6 +336,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
fun checkSwapUiTest() {
|
||||
val swapTokenSymbol = "POL"
|
||||
val receiveTokenSymbol = "ETH"
|
||||
val receiveTokenName = "Ethereum"
|
||||
val newReceiveToken = "POL (ex-MATIC)"
|
||||
val tokenTitle = "Polygon"
|
||||
val inputAmount = "1"
|
||||
|
|
@ -356,14 +364,17 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
step("Assert swap token symbol: '$swapTokenSymbol' is displayed") {
|
||||
onSwapTokenScreen { swapTokenSymbol(swapTokenSymbol).assertIsDisplayed() }
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert receive token symbol: '$receiveTokenSymbol' is displayed") {
|
||||
onSwapTokenScreen { receiveTokenSymbol(receiveTokenSymbol).assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Select token' icon") {
|
||||
onSwapTokenScreen { selectTokenIcon.performClick() }
|
||||
step("Click on receive 'Select token' icon") {
|
||||
onSwapTokenScreen { receiveSelectTokenIcon.performClick() }
|
||||
}
|
||||
step("Select new receive token: $newReceiveToken") {
|
||||
onSwapChooseTokenScreen { tokenWithTitle(newReceiveToken).performClick() }
|
||||
onSwapSelectTokenScreen { tokenWithName(newReceiveToken).performClick() }
|
||||
}
|
||||
step("Assert new receive token symbol: '$swapTokenSymbol' is displayed") {
|
||||
onSwapTokenScreen { receiveTokenSymbol(swapTokenSymbol).assertIsDisplayed() }
|
||||
|
|
@ -392,7 +403,11 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
onSwapTokenScreen { swapFiatAmount.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert receive token fiat amount is displayed") {
|
||||
onSwapTokenScreen { receiveFiatAmount.assertIsDisplayed() }
|
||||
onSwapTokenScreen {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
receiveFiatAmount.assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Assert 'Swap tokens on screen' button is displayed") {
|
||||
onSwapTokenScreen {
|
||||
|
|
@ -416,6 +431,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
fun checkSwapTokensSwitchTest() {
|
||||
val swapTokenSymbol = "POL"
|
||||
val receiveTokenSymbol = "ETH"
|
||||
val receiveTokenName = "Ethereum"
|
||||
val tokenTitle = "Polygon"
|
||||
|
||||
setupHooks().run {
|
||||
|
|
@ -438,6 +454,9 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
step("Assert swap token symbol: '$swapTokenSymbol' is displayed") {
|
||||
onSwapTokenScreen { swapTokenSymbol(swapTokenSymbol).assertIsDisplayed() }
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert receive token symbol: '$receiveTokenSymbol' is displayed") {
|
||||
onSwapTokenScreen { receiveTokenSymbol(receiveTokenSymbol).assertIsDisplayed() }
|
||||
}
|
||||
|
|
@ -514,6 +533,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
@Test
|
||||
fun enableToCoverMarketAndFastFeeTest() {
|
||||
val tokenName = "Ethereum"
|
||||
val receiveTokenName = "Polygon"
|
||||
val inputAmount = "0.99"
|
||||
val market = "Market"
|
||||
val fast = "Fast"
|
||||
|
|
@ -544,6 +564,9 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Select '$market' fee type") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
selectFeeType(FeeType.Market, selectedFeeAmount = marketFeeAmount)
|
||||
|
|
@ -562,6 +585,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
@Test
|
||||
fun unableToCoverMarketAndFastFeeTest() {
|
||||
val tokenName = "POL (ex-MATIC)"
|
||||
val receiveTokenName = "Ethereum"
|
||||
val inputAmount = "0.0001"
|
||||
val marketFeeType = "Market"
|
||||
val fastFeeType = "Fast"
|
||||
|
|
@ -587,6 +611,9 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Swipe up") {
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
}
|
||||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
||||
}
|
||||
|
|
@ -603,6 +630,9 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Select '$marketFeeType' fee type") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
selectFeeType(feeType = FeeType.Market, feeAmount)
|
||||
|
|
@ -633,6 +663,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
@Test
|
||||
fun unableToCoverFastFeeTest() {
|
||||
val tokenName = "POL (ex-MATIC)"
|
||||
val receiveTokenName = "Ethereum"
|
||||
val inputAmount = "3000"
|
||||
val fastFeeType = "Fast"
|
||||
val fastFeeAmount = "$2,"
|
||||
|
|
@ -660,6 +691,9 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Swipe up") {
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
}
|
||||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
||||
}
|
||||
|
|
@ -676,6 +710,9 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert 'Swap' button is enabled") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSwapTokenScreen { swapButton.assertIsEnabled() }
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.tangem.datasource.api.common.config.ApiEnvironment
|
|||
import com.tangem.scenarios.SwapEntryPoint
|
||||
import com.tangem.scenarios.chackUnableToCoverFeeNotification
|
||||
import com.tangem.scenarios.checkSwapWarning
|
||||
import com.tangem.scenarios.chooseReceiveToken
|
||||
import com.tangem.scenarios.openMainScreen
|
||||
import com.tangem.scenarios.openSwapScreen
|
||||
import com.tangem.scenarios.synchronizeAddresses
|
||||
|
|
@ -36,6 +37,7 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
@Test
|
||||
fun checkSwapInsufficientFundsWarningTest() {
|
||||
val tokenTitle = "Polygon"
|
||||
val receiveTokenTitle = "Ethereum"
|
||||
val inputAmount = "1000"
|
||||
|
||||
setupHooks().run {
|
||||
|
|
@ -65,6 +67,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenTitle)
|
||||
}
|
||||
step("Assert 'Insufficient funds' error is displayed") {
|
||||
waitForIdle()
|
||||
onSwapTokenScreen { insufficientFundsErrorTitle.assertIsDisplayed() }
|
||||
|
|
@ -127,6 +132,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(networkName)
|
||||
}
|
||||
step("Check 'Unable to cover '$networkName' fee notification") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
chackUnableToCoverFeeNotification(networkName = networkName, currencySymbol = currencySymbol)
|
||||
|
|
@ -143,6 +151,7 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
@Test
|
||||
fun checkHighPriceImpactWarningCEXTest() {
|
||||
val tokenTitle = "USDC"
|
||||
val receiveTokenName = "Solana"
|
||||
val inputAmount = "100"
|
||||
val currencySymbol = "SOL"
|
||||
val slippagePercent = "5%"
|
||||
|
|
@ -202,6 +211,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert fiat amount with warning is displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSwapTokenScreen {
|
||||
|
|
@ -236,6 +248,7 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
@Test
|
||||
fun checkHighPriceImpactWarningDEXTest() {
|
||||
val tokenTitle = "Polygon"
|
||||
val receiveTokenName = "Ethereum"
|
||||
val inputAmount = "1000"
|
||||
val slippagePercent = "3.5%"
|
||||
val dialogTitle = getResourceString(R.string.swapping_alert_title)
|
||||
|
|
@ -287,6 +300,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert fiat amount with warning is displayed") {
|
||||
onSwapTokenScreen { receiveFiatAmount.assertTextContains("%", substring = true) }
|
||||
}
|
||||
|
|
@ -323,6 +339,7 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
@Test
|
||||
fun solanaRemainingBalanceEqualToZeroWarningTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val receiveTokenName = "USDC"
|
||||
val inputAmount = "0.00168933"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
|
|
@ -371,6 +388,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is not displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
|
|
@ -388,6 +408,7 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
@Test
|
||||
fun solanaRemainingBalanceEqualToRentAmountTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val receiveTokenName = "USDC"
|
||||
val inputAmount = "0.001689338"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
|
|
@ -436,6 +457,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is not displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
|
|
@ -454,6 +478,7 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
@Test
|
||||
fun solanaRemainingBalanceMoreThanRentAmountTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val receiveTokenName = "USDC"
|
||||
val inputAmount = "0.0000941"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
|
|
@ -502,6 +527,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is not displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
|
|
@ -519,6 +547,7 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
@Test
|
||||
fun solanaRemainingBalanceLessThanRentAmountTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val receiveTokenName = "USDC"
|
||||
val inputAmount = "0.0016941"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
|
|
@ -567,6 +596,9 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Choose receive token") {
|
||||
chooseReceiveToken(receiveTokenName)
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ object MockProvider {
|
|||
"Wallet 2 (No Backup)" to Wallet2NoBackupMockContent,
|
||||
"Wallet 2 (No Backup, No Wallets)" to Wallet2NoBackupNoWalletsMockContent,
|
||||
"Wallet 2 (Seed Phrase)" to Wallet2WithSeedPhraseMockContent,
|
||||
"Wallet 2 (With derivations)" to Wallet2WithDerivationsMockContent,
|
||||
"Shiba" to ShibaMockContent,
|
||||
"Shiba (No Backup)" to ShibaNoBackupMockContent,
|
||||
"Shiba (No Backup, No Wallets)" to ShibaNoBackupNoWalletsMockContent,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
package com.tangem.tap.domain.sdk.mocks.content
|
||||
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.extensions.ByteArrayKey
|
||||
import com.tangem.operations.derivation.DerivationTaskResponse
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import com.tangem.sdk.api.CreateProductWalletTaskResponse
|
||||
import com.tangem.tap.domain.sdk.mocks.MockContent
|
||||
|
||||
/**
|
||||
* Mock content for UI tests that need the Wallet 2 derivation style (V3) AND the full set of derivations
|
||||
* provided by [WalletMockContent].
|
||||
*
|
||||
* Why it exists:
|
||||
* - [WalletMockContent] is Wallet 1 (derivation style V2), so for Bitcoin the card's default path resolves to
|
||||
* `m/44'/0'/0'/0/0`. WireMock `/user-tokens` stubs send `m/84'/0'/0'/0/0` → the path does not match the card default
|
||||
* → `Network.DerivationPath.Custom` → `CryptoCurrency.isCustom == true`. That hides the swap-to-another-token button
|
||||
* introduced in the Send flow and causes the Swap receive card to stay in Empty/Loading state.
|
||||
* - [Wallet2MockContent] is V3 (matches WireMock) but its `derivationTaskResponse` is keyed by the wrong wallet
|
||||
* public key (inherited from [WalletMockContent]) and only contains a handful of derivation paths. As a result
|
||||
* address synchronisation fails in tests that need more than BTC/ETH/BCH/DOGE.
|
||||
*
|
||||
* This mock combines both: Wallet 2 card DTO from [Wallet2MockContent] (V3 derivation style) + full derivation
|
||||
* entries from [WalletMockContent] re-keyed to [Wallet2MockContent]'s own wallet public keys.
|
||||
*/
|
||||
object Wallet2WithDerivationsMockContent : MockContent by Wallet2MockContent {
|
||||
|
||||
private val secp256k1Pubkey: ByteArray =
|
||||
Wallet2MockContent.cardDto.wallets.first { it.curve == EllipticCurve.Secp256k1 }.publicKey
|
||||
|
||||
private val ed25519Pubkey: ByteArray =
|
||||
Wallet2MockContent.cardDto.wallets.first { it.curve == EllipticCurve.Ed25519 }.publicKey
|
||||
|
||||
override val derivationTaskResponse: DerivationTaskResponse = DerivationTaskResponse(
|
||||
entries = rekey(WalletMockContent.derivationTaskResponse.entries),
|
||||
)
|
||||
|
||||
override val createProductWalletTaskResponse: CreateProductWalletTaskResponse =
|
||||
CreateProductWalletTaskResponse(
|
||||
card = Wallet2MockContent.cardDto,
|
||||
derivedKeys = rekey(WalletMockContent.createProductWalletTaskResponse.derivedKeys),
|
||||
primaryCard = Wallet2MockContent.createProductWalletTaskResponse.primaryCard,
|
||||
)
|
||||
|
||||
/**
|
||||
* Takes an entry map keyed by [WalletMockContent]'s wallet public keys (Secp256k1 first, Ed25519 second in
|
||||
* insertion order) and re-keys it to [Wallet2MockContent]'s own wallet public keys so that
|
||||
* [com.tangem.data.wallets.derivations.DerivationsSource] lookups by card wallet pubkey succeed.
|
||||
*/
|
||||
private fun rekey(
|
||||
sourceEntries: Map<ByteArrayKey, ExtendedPublicKeysMap>,
|
||||
): Map<ByteArrayKey, ExtendedPublicKeysMap> {
|
||||
val values = sourceEntries.values.toList()
|
||||
return buildMap {
|
||||
values.getOrNull(index = 0)?.let { put(ByteArrayKey(secp256k1Pubkey), it) }
|
||||
values.getOrNull(index = 1)?.let { put(ByteArrayKey(ed25519Pubkey), it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue