Updated on 2026-08-14
This commit is contained in:
parent
557e8eceb6
commit
5fda020fc3
58 changed files with 587 additions and 557 deletions
|
|
@ -186,6 +186,7 @@ abstract class BaseTestCase : TestCase(
|
|||
"VISA_ONBOARDING_ENABLED" to true,
|
||||
"AND_15101_TANGEM_PAY_HOT_WALLET_ONBOARDING" to true,
|
||||
"AND_15310_ADD_FUNDS_STAGE1" to true,
|
||||
"APP_REDESIGN_ENABLED" to true,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,5 +115,13 @@ private fun extractText(node: SemanticsNode): String? {
|
|||
|
||||
private fun parseVolume(node: SemanticsNode): Double? {
|
||||
val text = extractText(node) ?: return null
|
||||
return text.replace("[^0-9.]".toRegex(), "").toDoubleOrNull()
|
||||
val multiplier = when {
|
||||
text.contains('T', ignoreCase = true) -> 1_000_000_000_000.0
|
||||
text.contains('B', ignoreCase = true) -> 1_000_000_000.0
|
||||
text.contains('M', ignoreCase = true) -> 1_000_000.0
|
||||
text.contains('K', ignoreCase = true) -> 1_000.0
|
||||
else -> 1.0
|
||||
}
|
||||
val number = text.replace("[^0-9.]".toRegex(), "").toDoubleOrNull() ?: return null
|
||||
return number * multiplier
|
||||
}
|
||||
|
|
@ -11,6 +11,11 @@ fun KNode.clickWithAssertion() {
|
|||
performClick()
|
||||
}
|
||||
|
||||
fun KNode.clickWhenEnabled() {
|
||||
assertIsEnabled()
|
||||
performClick()
|
||||
}
|
||||
|
||||
fun KNode.assertTextContainsSafe(
|
||||
text: String,
|
||||
substring: Boolean = false,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import androidx.test.uiautomator.By
|
|||
import androidx.test.uiautomator.Until
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.wallet.R
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
|
||||
fun BaseTestCase.swipeVertical(
|
||||
direction: SwipeDirection,
|
||||
|
|
@ -31,21 +29,6 @@ fun BaseTestCase.pullToRefresh(steps: Int = 1000) {
|
|||
)
|
||||
}
|
||||
|
||||
fun BaseTestCase.swipeMarketsBlock(direction: SwipeDirection) {
|
||||
val searchBarText = device.uiDevice
|
||||
.findObject(By.textContains(getResourceString(R.string.markets_search_header_title)))
|
||||
val bounds = searchBarText.visibleBounds
|
||||
|
||||
val centerX = bounds.centerX()
|
||||
val startY = bounds.centerY()
|
||||
val endY = when (direction) {
|
||||
SwipeDirection.UP -> 50
|
||||
SwipeDirection.DOWN -> device.uiDevice.displayHeight - 100
|
||||
}
|
||||
|
||||
device.uiDevice.swipe(centerX, startY, centerX, endY, 100)
|
||||
}
|
||||
|
||||
fun BaseTestCase.openTheAppFromRecents() {
|
||||
device.uiDevice.waitForIdle()
|
||||
|
||||
|
|
|
|||
|
|
@ -6,97 +6,33 @@ import com.tangem.common.extensions.swipeVertical
|
|||
import com.tangem.screens.onMainScreen
|
||||
import io.qameta.allure.kotlin.Allure.step
|
||||
|
||||
fun BaseTestCase.checkSingleCurrencyMainScreen(
|
||||
cardBlockchain: String,
|
||||
cardTitle: String,
|
||||
withTransactions: Boolean = false,
|
||||
withWalletImage: Boolean = true
|
||||
) {
|
||||
fun BaseTestCase.checkSingleCurrencyMainScreen(cardTitle: String) {
|
||||
step("Assert card title equal '$cardTitle'") {
|
||||
onMainScreen { walletNameText.assertTextEquals(cardTitle) }
|
||||
}
|
||||
if (withWalletImage) {
|
||||
step("Assert card image is displayed") { //TODO: create assertion method for checking images
|
||||
onMainScreen { walletImage.assertIsDisplayed() }
|
||||
}
|
||||
} else {
|
||||
step("Assert card image is not displayed") {
|
||||
onMainScreen { walletImage.assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Assert 'Receive' button is displayed") {
|
||||
onMainScreen { receiveButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Buy' button is displayed") {
|
||||
onMainScreen { buyButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Send' button is displayed") {
|
||||
onMainScreen { sendButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Sell' button is displayed") {
|
||||
onMainScreen { sellButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Swap' button is not displayed") {
|
||||
onMainScreen { swapButton.assertIsNotDisplayed() }
|
||||
}
|
||||
step("Assert 'Market Price' on single card main screen is displayed") {
|
||||
onMainScreen { marketPriceBlock().assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Market Price' title equals $cardBlockchain Market Price") {
|
||||
onMainScreen { marketPriceText.assertTextContains("$cardBlockchain Market Price") }
|
||||
}
|
||||
step("Swipe up") {
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
}
|
||||
if (withTransactions) {
|
||||
step("Assert 'Transactions' block is displayed") {
|
||||
onMainScreen { transactionsExplorerText.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Transactions' title is displayed") {
|
||||
onMainScreen { transactionsTitle.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Explorer' icon is displayed") {
|
||||
onMainScreen { transactionsExplorerIcon.assertIsDisplayed() }
|
||||
}
|
||||
} else {
|
||||
step("Assert empty 'Transactions' block is displayed") {
|
||||
onMainScreen { emptyTransactionBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert empty 'Transactions' block icon is displayed") {
|
||||
onMainScreen { emptyTransactionBlockIcon.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert empty 'Transactions' block text is displayed") {
|
||||
onMainScreen { emptyTransactionBlockText.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert empty 'Transactions' block 'Explore' button is displayed") {
|
||||
onMainScreen { emptyTransactionBlockExploreButton.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Assert 'Add & Manage' button is not displayed") {
|
||||
onMainScreen { addAndManageButtonWithoutLazySearch.assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
|
||||
fun BaseTestCase.checkMultiCurrencyMainScreen(
|
||||
devicesCount: String,
|
||||
cardTitle: String,
|
||||
withWalletImage: Boolean = true
|
||||
) {
|
||||
step("Assert card title equal '$cardTitle'") {
|
||||
onMainScreen { walletNameText.assertTextEquals(cardTitle) }
|
||||
}
|
||||
if (withWalletImage) {
|
||||
step("Assert card image is displayed") {
|
||||
onMainScreen { walletImage.assertIsDisplayed() }
|
||||
}
|
||||
} else {
|
||||
step("Assert card image is not displayed") {
|
||||
onMainScreen { walletImage.assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Assert devices count equal to '$devicesCount'") {
|
||||
onMainScreen { walletDevicesCount.assertTextContains(devicesCount) }
|
||||
}
|
||||
step("Assert 'Buy' button is displayed") {
|
||||
onMainScreen { buyButton.assertIsDisplayed() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
package com.tangem.scenarios
|
||||
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.extensions.SwipeDirection
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.extensions.swipeVertical
|
||||
import com.tangem.screens.onMainScreen
|
||||
import com.tangem.screens.onMarketsExchangesScreen
|
||||
import com.tangem.screens.onMarketsScreen
|
||||
import com.tangem.screens.onMarketsTokenDetailsScreen
|
||||
import io.qameta.allure.kotlin.Allure.step
|
||||
|
||||
fun BaseTestCase.openMarketTokenDetailsScreen(blockchainName: String, tokenName: String) {
|
||||
fun BaseTestCase.openTokenDetailsFromMarketsScreen(blockchainName: String, tokenName: String) {
|
||||
step("Open 'Markets' screen") {
|
||||
onMainScreen { searchThroughMarketPlaceholder.performClick() }
|
||||
waitForIdle()
|
||||
}
|
||||
step("Click on 'Search' placeholder") {
|
||||
onMarketsScreen { searchThroughMarketPlaceholder.performClick() }
|
||||
}
|
||||
step("Click on $blockchainName blockchain") {
|
||||
waitForIdle()
|
||||
onMarketsScreen { tokenWithTitle(blockchainName).clickWithAssertion() }
|
||||
}
|
||||
step("Click on $tokenName token") {
|
||||
step("Click on 'In your portfolio' block") {
|
||||
waitForIdle()
|
||||
onMarketsTokenDetailsScreen { inYourPortfolioBlock.clickWithAssertion() }
|
||||
}
|
||||
step("Click on $tokenName token in 'Your portfolio' bottom sheet") {
|
||||
waitForIdle()
|
||||
onMarketsTokenDetailsScreen { tokenWithTitle(tokenName).clickWithAssertion() }
|
||||
}
|
||||
|
|
@ -59,6 +59,7 @@ fun BaseTestCase.openMarketsScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun BaseTestCase.openMarketsExchangesScreen(tokenName: String, shouldClickSeeAllButton: Boolean = false) {
|
||||
openMarketsScreen()
|
||||
if (shouldClickSeeAllButton)
|
||||
|
|
@ -69,9 +70,8 @@ fun BaseTestCase.openMarketsExchangesScreen(tokenName: String, shouldClickSeeAll
|
|||
onMarketsScreen { tokenWithTitle(tokenName).clickWithAssertion() }
|
||||
waitForIdle()
|
||||
}
|
||||
step("Scroll down") {
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
step("Scroll to 'Listed on exchanges' block") {
|
||||
onMarketsScreen { scrollToListedOnBlock() }
|
||||
}
|
||||
step("Click on 'Listed on exchanges' block") {
|
||||
onMarketsScreen { listedOnBlockContainer.performClick() }
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import com.tangem.common.constants.TestConstants.HOLD_DURATION_MS
|
|||
import com.tangem.common.constants.TestConstants.QUOTES_API_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.USER_TOKENS_API_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.common.extensions.assertIsDimmed
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.screens.*
|
||||
|
|
@ -34,8 +33,11 @@ fun BaseTestCase.openSendScreen(
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button") {
|
||||
onTokenDetailsScreen { sendButton().performClick() }
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button in bottom sheet") {
|
||||
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,11 +93,11 @@ fun BaseTestCase.openSendAddressScreen(
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Send' button is not dimmed") {
|
||||
onTokenDetailsScreen { sendButton().assertIsDimmed(false) }
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button") {
|
||||
onTokenDetailsScreen { sendButton().performClick() }
|
||||
step("Click on 'Send' button in bottom sheet") {
|
||||
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type '$inputAmount' in input text field") {
|
||||
onSendScreen {
|
||||
|
|
@ -109,6 +111,13 @@ fun BaseTestCase.openSendAddressScreen(
|
|||
step("Assert 'Send Address' container is displayed") {
|
||||
onSendAddressScreen { container.assertIsDisplayed() }
|
||||
}
|
||||
step("Wait for recipient list to load") {
|
||||
composeTestRule.waitUntil(timeoutMillis = WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
runCatching {
|
||||
onSendAddressScreen { addressesShimmer.assertIsNotDisplayed() }
|
||||
}.isSuccess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun BaseTestCase.checkScanQrScreen(emptyClipboard: Boolean = true) {
|
||||
|
|
@ -244,8 +253,11 @@ fun BaseTestCase.selectTokenToSendViaSwap(
|
|||
networkName: String,
|
||||
networkType: String? = null,
|
||||
) {
|
||||
step("Click on 'Send' button") {
|
||||
onTokenDetailsScreen { sendButton().performClick() }
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button in bottom sheet") {
|
||||
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Swap to another token' button") {
|
||||
onSendScreen { swapToAnotherTokenButton.performClick() }
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.common.BaseTestCase
|
|||
import com.tangem.common.constants.TestConstants.HOLD_DURATION_MS
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.common.extensions.assertVisibility
|
||||
import com.tangem.common.extensions.clickWhenEnabled
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.extensions.isDisplayedSafely
|
||||
import com.tangem.core.ui.R as CoreUiR
|
||||
|
|
@ -43,8 +44,8 @@ fun BaseTestCase.openSwapScreen(
|
|||
}
|
||||
|
||||
SwapEntryPoint.TokenDetails -> step("Click on 'Swap' button on 'Token details' screen") {
|
||||
onTokenDetailsScreen { swapButton().performClick() }
|
||||
}
|
||||
onTokenDetailsScreen { swapButton.clickWhenEnabled() }
|
||||
}
|
||||
|
||||
SwapEntryPoint.MarketsTokenDetails -> step("Click on 'Swap' button on 'Markets' token details screen") {
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.performClick() }
|
||||
|
|
|
|||
|
|
@ -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.BaseBottomSheetTestTags
|
||||
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 AddFundsBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<AddFundsBottomSheetPageObject>(
|
||||
semanticsProvider = semanticsProvider,
|
||||
viewBuilderAction = { hasTestTag(BaseBottomSheetTestTags.CONTAINER) },
|
||||
) {
|
||||
|
||||
val buyButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_buy)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val swapButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_swap)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val receiveButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_receive)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val closeButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_close)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onAddFundsBottomSheet(function: AddFundsBottomSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -11,7 +11,10 @@ import io.github.kakaocup.compose.node.element.KNode
|
|||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
|
||||
class AddTokenBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<AddTokenBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
|
||||
ComposeScreen<AddTokenBottomSheetPageObject>(
|
||||
semanticsProvider = semanticsProvider,
|
||||
viewBuilderAction = { hasTestTag(BaseBottomSheetTestTags.CONTAINER) },
|
||||
) {
|
||||
|
||||
val title: KNode = child {
|
||||
hasTestTag(BaseBottomSheetTestTags.TITLE)
|
||||
|
|
@ -23,6 +26,12 @@ class AddTokenBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractions
|
|||
hasText(getResourceString(R.string.common_add))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val laterButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasText(getResourceString(R.string.common_later))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onAddTokenBottomSheet(function: AddTokenBottomSheetPageObject.() -> Unit) =
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import androidx.compose.ui.test.ExperimentalTestApi
|
|||
import androidx.compose.ui.test.SemanticsMatcher
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
import androidx.compose.ui.test.swipeUp
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.extensions.getQuantityString
|
||||
import com.tangem.common.extensions.hasLazyListItemPosition
|
||||
|
|
@ -49,27 +50,32 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
|
||||
val buyButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_buy))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_buy)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val sendButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_send))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_send)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val receiveButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_receive))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_receive)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val sellButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_sell))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_sell)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val swapButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_swap))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_swap)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val walletNameText: KNode = child {
|
||||
|
|
@ -82,13 +88,21 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val walletDevicesCount: KNode = child {
|
||||
hasTestTag(MainScreenTestTags.DEVICES_COUNT)
|
||||
useUnmergedTree = true
|
||||
/**
|
||||
* Collapses the collapsing header via a touch-based swipe so that items near the bottom
|
||||
* of the lazy list fall within screen bounds before programmatic childWith scroll.
|
||||
* Required because TangemCollapsingTopBar places the body at y=collapsingHeight, which
|
||||
* pushes lower list items off-screen when the header is expanded.
|
||||
*/
|
||||
private fun collapseHeader() {
|
||||
screenContainer {
|
||||
performTouchInput { swipeUp(startY = visibleSize.height * 0.6f, endY = visibleSize.height * 0.1f) }
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun marketPriceBlock(): LazyListItemNode {
|
||||
collapseHeader()
|
||||
return lazyList.childWith<LazyListItemNode> {
|
||||
hasTestTag(MarketPriceBlockTestTags.BLOCK)
|
||||
useUnmergedTree = true
|
||||
|
|
@ -231,6 +245,7 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
*/
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun accountWithName(name: String): LazyListItemNode {
|
||||
collapseHeader()
|
||||
return lazyList.childWith<LazyListItemNode> {
|
||||
hasTestTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
||||
hasAnyDescendant(withText(name))
|
||||
|
|
@ -243,6 +258,7 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
*/
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun tokenWithTitleAndAddress(tokenTitle: String): KNode {
|
||||
collapseHeader()
|
||||
return lazyList.childWith<LazyListItemNode> {
|
||||
hasTestTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
||||
hasText(tokenTitle)
|
||||
|
|
@ -255,6 +271,7 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun tokenWithCustomDerivationIcon(tokenTitle: String): KNode {
|
||||
collapseHeader()
|
||||
return lazyList.childWith<LazyListItemNode> {
|
||||
hasTestTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
||||
hasText(tokenTitle)
|
||||
|
|
@ -267,6 +284,7 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun addAndManageButton(): KNode {
|
||||
collapseHeader()
|
||||
return lazyList.childWith<LazyListItemNode> {
|
||||
hasTestTag(MainScreenTestTags.ADD_AND_MANAGE_BUTTON)
|
||||
}.child<KNode> {
|
||||
|
|
@ -282,11 +300,12 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
}
|
||||
|
||||
val searchThroughMarketPlaceholder: KNode = child {
|
||||
hasText(getResourceString(R.string.markets_search_header_title))
|
||||
hasText(getResourceString(R.string.markets_search_title_placeholder))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun tokenNetworkGroupTitle(tokenNetwork: String): KNode {
|
||||
collapseHeader()
|
||||
return lazyList.child {
|
||||
hasTestTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
||||
hasAnyChild(withText(tokenNetwork))
|
||||
|
|
@ -296,6 +315,7 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun tokenWithTitleAndPosition(tokenTitle: String, index: Int): KNode {
|
||||
collapseHeader()
|
||||
return lazyList.childWith<LazyListItemNode> {
|
||||
hasTestTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
||||
hasText(tokenTitle)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,9 @@ package com.tangem.screens
|
|||
|
||||
import androidx.compose.ui.semantics.SemanticsNode
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import androidx.compose.ui.test.hasParent
|
||||
import androidx.compose.ui.test.hasTestTag
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.TokenElementsTestTags
|
||||
import com.tangem.core.ui.test.TopAppBarTestTags
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
|
||||
|
|
@ -23,16 +21,15 @@ class MarketsExchangesPageObject(private val provider: SemanticsNodeInteractions
|
|||
|
||||
fun allExchangeTypeNodes(): List<SemanticsNode> =
|
||||
provider
|
||||
.onAllNodes(hasParent(hasParent(hasTestTag(TokenElementsTestTags.TOKEN_PRICE))))
|
||||
.onAllNodes(hasTestTag(TokenElementsTestTags.TOKEN_PRICE))
|
||||
.fetchSemanticsNodes()
|
||||
|
||||
fun allTrustScoreNodes(): List<SemanticsNode> =
|
||||
provider
|
||||
.onAllNodes(hasParent(hasTestTag(TokenElementsTestTags.TOKEN_CRYPTO_AMOUNT)))
|
||||
.onAllNodes(hasTestTag(TokenElementsTestTags.TOKEN_CRYPTO_AMOUNT))
|
||||
.fetchSemanticsNodes()
|
||||
|
||||
val exchangesTitle: KNode = child {
|
||||
hasTestTag(TopAppBarTestTags.TITLE)
|
||||
hasText(getResourceString(R.string.markets_token_details_exchanges_title))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import androidx.compose.ui.test.hasTestTag
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.MARKETS_MAIN_NETWORK_SUFFIX
|
||||
import com.tangem.core.ui.test.BaseButtonTestTags
|
||||
|
|
@ -15,9 +17,9 @@ import io.github.kakaocup.kakao.common.utilities.getResourceString
|
|||
class MarketsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<MarketsPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val addToPortfolioButton: KNode = child {
|
||||
val addButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasText(getResourceString(R.string.common_add_to_portfolio))
|
||||
hasText(getResourceString(R.string.common_add))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +33,12 @@ class MarketsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
|||
}
|
||||
|
||||
val searchThroughMarketPlaceholder: KNode = child {
|
||||
hasText(getResourceString(R.string.markets_search_header_title))
|
||||
hasText(getResourceString(R.string.markets_search_title_placeholder))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val tokenDetailsContent: KNode = child {
|
||||
hasTestTag(MarketsTestTags.TOKEN_DETAILS_CONTENT)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +48,8 @@ class MarketsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
|||
}
|
||||
|
||||
val listedOnBlockContainer: KNode = child {
|
||||
hasText(getResourceString(R.string.markets_token_details_listed_on), substring = true)
|
||||
hasTestTag(MarketsTestTags.LISTED_ON_BLOCK)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val listedOnEmptyText: KNode = child {
|
||||
|
|
@ -60,6 +68,13 @@ class MarketsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
|||
hasText(title)
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalTestApi
|
||||
fun scrollToListedOnBlock() {
|
||||
tokenDetailsContent {
|
||||
performScrollToNode(hasTestTag(MarketsTestTags.LISTED_ON_BLOCK))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onMarketsScreen(function: MarketsPageObject.() -> Unit) =
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@ package com.tangem.screens
|
|||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.MarketTokenDetailsBottomSheetTestTags
|
||||
import com.tangem.core.ui.test.TokenElementsTestTags
|
||||
import com.tangem.features.onramp.impl.R
|
||||
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.hasTestTag as withTestTag
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
import com.tangem.core.ui.R as CoreUiR
|
||||
|
||||
class MarketsTokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<MarketsTokenDetailsPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
|
@ -20,11 +19,14 @@ class MarketsTokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractions
|
|||
hasText(getResourceString(R.string.common_swap), substring = true)
|
||||
}
|
||||
|
||||
val inYourPortfolioBlock: KNode = child {
|
||||
hasText(getResourceString(CoreUiR.string.markets_portfolio_block_subtitle), substring = true)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun tokenWithTitle(title: String): KNode = child {
|
||||
hasAnyAncestor(withTestTag(MarketTokenDetailsBottomSheetTestTags.PORTFOLIO_TOKEN_ITEM))
|
||||
hasTestTag(TokenElementsTestTags.TOKEN_TITLE)
|
||||
hasAnySibling(withTestTag(TokenElementsTestTags.TOKEN_ICON))
|
||||
hasAnyChild(withText(title))
|
||||
hasClickAction()
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,23 +28,18 @@ class OrganizeTokensPageObject(semanticsProvider: SemanticsNodeInteractionsProvi
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
private val topBarGroupButton: KNode = child {
|
||||
hasTestTag(OrganizeTokensScreenTestTags.GROUP_BUTTON)
|
||||
val organizeMenuButton: KNode = child {
|
||||
hasTestTag(OrganizeTokensScreenTestTags.MENU_BUTTON)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val groupButton: KNode = topBarGroupButton.child {
|
||||
val groupButton: KNode = child {
|
||||
hasText(getResourceString(R.string.organize_tokens_group))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val ungroupButton: KNode = topBarGroupButton.child {
|
||||
hasText(getResourceString(R.string.organize_tokens_ungroup))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val sortByBalanceButton: KNode = child {
|
||||
hasTestTag(OrganizeTokensScreenTestTags.SORT_BY_BALANCE_BUTTON)
|
||||
hasText(getResourceString(R.string.organize_tokens_sort_by_balance))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
// endregion TopBar
|
||||
|
|
@ -84,7 +79,7 @@ class OrganizeTokensPageObject(semanticsProvider: SemanticsNodeInteractionsProvi
|
|||
fun tokenNetworkGroupTitle(tokenNetwork: String): KNode {
|
||||
return lazyList.child {
|
||||
hasTestTag(OrganizeTokensScreenTestTags.GROUP_TITLE_ITEM)
|
||||
hasAnyChild(withText(tokenNetwork))
|
||||
hasAnyDescendant(withText(tokenNetwork))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class SendAddressPageObject(semanticsProvider: SemanticsNodeInteractionsProvider
|
|||
): KNode = child {
|
||||
hasTestTag(SendAddressScreenTestTags.RECENT_ADDRESS_ITEM)
|
||||
hasAnyChild(withTestTag(SendAddressScreenTestTags.RECENT_ADDRESS_ICON))
|
||||
hasAnyDescendant(withText(recipientAddress))
|
||||
hasAnyDescendant(withText(recipientAddress, substring = true))
|
||||
hasAnyDescendant(withTestTag(SendAddressScreenTestTags.RECENT_ADDRESS_TEXT))
|
||||
useUnmergedTree = true
|
||||
if (description != null) {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,15 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.SemanticsMatcher
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.utils.LazyListItemNode
|
||||
import com.tangem.core.ui.test.BaseActionButtonsBlockTestTags
|
||||
import com.tangem.core.ui.test.BaseButtonTestTags
|
||||
import com.tangem.core.ui.test.NotificationTestTags
|
||||
import com.tangem.core.ui.test.TokenDetailsScreenTestTags
|
||||
import com.tangem.core.ui.utils.LazyListItemPositionSemantics
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
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.compose.node.element.lazylist.KLazyListNode
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
import androidx.compose.ui.test.hasTestTag as withTestTag
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
|
|
@ -36,18 +31,8 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val availableStakingBlockTitle: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.STAKING_SERVICE_TITLE)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val availableStakingBlockText: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.STAKING_SERVICE_TEXT)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val availableStakingBlockCurrencyIcon: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.STAKING_CURRENCY_ICON)
|
||||
fun availableStakingBlockText(apy: String): KNode = child {
|
||||
hasText(getResourceString(R.string.token_details_earn_staking_subtitle, apy))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
|
@ -62,69 +47,39 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val stakingDot: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.STAKING_DOT)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val stakingTokenAmount: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.STAKING_TOKEN_AMOUNT)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val stakingChevronIcon: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.STAKING_CHEVRON_ICON)
|
||||
useUnmergedTree = true
|
||||
val stakingTitle: KNode = child {
|
||||
hasText(getResourceString(R.string.common_staking))
|
||||
}
|
||||
|
||||
val stakingTitle: KNode = child {
|
||||
hasText(getResourceString(R.string.staking_native))
|
||||
val stakingEnabledTitle: KNode = child {
|
||||
hasText(getResourceString(R.string.staking_enabled))
|
||||
}
|
||||
|
||||
val title: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.TOKEN_TITLE)
|
||||
}
|
||||
|
||||
private val horizontalActionChips = KLazyListNode(
|
||||
semanticsProvider = semanticsProvider,
|
||||
viewBuilderAction = { hasTestTag(BaseActionButtonsBlockTestTags.HORIZONTAL_ACTION_CHIPS) },
|
||||
itemTypeBuilder = { itemType(::LazyListItemNode) },
|
||||
positionMatcher = { position ->
|
||||
SemanticsMatcher.expectValue(
|
||||
LazyListItemPositionSemantics,
|
||||
position
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun receiveButton(): LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
|
||||
val addFundsButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_receive))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.tangempay_card_details_add_funds)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun swapButton(): LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
|
||||
val swapButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_swap))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_swap)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun sellButton(): LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
|
||||
val transferButton: KNode = child {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_sell))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun buyButton(): LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_buy))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun sendButton(): LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
|
||||
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
hasText(getResourceString(R.string.common_send))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_transfer)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun networkFeeNotificationIcon(feeCurrencyName: String): KNode = child {
|
||||
|
|
@ -204,7 +159,6 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
|
|||
hasAnyDescendant(withTestTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_SWAP_ICON))
|
||||
hasAnyDescendant(withTestTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_TO_ICON))
|
||||
hasAnyDescendant(withTestTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_TO_AMOUNT))
|
||||
hasAnyDescendant(withTestTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_CHEVRON_ICON))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.BaseBottomSheetTestTags
|
||||
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 TransferBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<TransferBottomSheetPageObject>(
|
||||
semanticsProvider = semanticsProvider,
|
||||
viewBuilderAction = { hasTestTag(BaseBottomSheetTestTags.CONTAINER) },
|
||||
) {
|
||||
|
||||
val sendButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_send)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val swapButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_swap)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val sellButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_sell)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val closeButton: KNode = child {
|
||||
hasAnyChild(withText(getResourceString(R.string.common_close)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onTransferBottomSheet(function: TransferBottomSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -27,6 +27,7 @@ import com.tangem.screens.onSendScreen
|
|||
import com.tangem.screens.onStoriesScreen
|
||||
import com.tangem.screens.onTokenDetailsScreen
|
||||
import com.tangem.screens.onMainScreenTopBar
|
||||
import com.tangem.screens.onTransferBottomSheet
|
||||
import com.tangem.tap.domain.sdk.mocks.MockProvider
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.qameta.allure.kotlin.AllureId
|
||||
|
|
@ -94,8 +95,11 @@ class FeedbackTest : BaseTestCase() {
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
||||
}
|
||||
step("Click 'Send' button") {
|
||||
onTokenDetailsScreen { sendButton().performClick() }
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button in bottom sheet") {
|
||||
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type '$sendAmount' in input text field") {
|
||||
onSendScreen {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ class OrganizeTokensTest : BaseTestCase() {
|
|||
fun groupTokensTest() {
|
||||
setupHooks().run {
|
||||
val tokenTitle = "Ethereum"
|
||||
val tokenNetwork = "Ethereum network"
|
||||
val networkTitleOrganize = "Ethereum"
|
||||
val networkTitleMain = "Ethereum network"
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
|
|
@ -39,17 +40,20 @@ class OrganizeTokensTest : BaseTestCase() {
|
|||
tokenWithTitle(tokenTitle).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
step("Open organize menu") {
|
||||
onOrganizeTokensScreen { organizeMenuButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click 'Group' button") {
|
||||
onOrganizeTokensScreen { groupButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert tokens were grouped on 'Organize tokens' screen") {
|
||||
onOrganizeTokensScreen { tokenNetworkGroupTitle(tokenNetwork).assertIsDisplayed() }
|
||||
onOrganizeTokensScreen { tokenNetworkGroupTitle(networkTitleOrganize).assertIsDisplayed() }
|
||||
}
|
||||
step("Click 'Apply' button") {
|
||||
onOrganizeTokensScreen { applyButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert tokens were grouped on 'Main screen'") {
|
||||
onMainScreen { tokenNetworkGroupTitle(tokenNetwork).assertIsDisplayed() }
|
||||
onMainScreen { tokenNetworkGroupTitle(networkTitleMain).assertIsDisplayed() }
|
||||
}
|
||||
step("Open 'Organize tokens' screen") {
|
||||
openOrganizeTokensScreen()
|
||||
|
|
@ -60,17 +64,20 @@ class OrganizeTokensTest : BaseTestCase() {
|
|||
tokenWithTitle(tokenTitle).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
step("Click 'Ungroup' button") {
|
||||
onOrganizeTokensScreen { ungroupButton.clickWithAssertion() }
|
||||
step("Open organize menu") {
|
||||
onOrganizeTokensScreen { organizeMenuButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click 'Group' checkbox again to ungroup") {
|
||||
onOrganizeTokensScreen { groupButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert tokens were ungrouped on 'Organize tokens' screen") {
|
||||
onOrganizeTokensScreen { tokenNetworkGroupTitle(tokenNetwork).assertIsNotDisplayed() }
|
||||
onOrganizeTokensScreen { tokenNetworkGroupTitle(networkTitleOrganize).assertIsNotDisplayed() }
|
||||
}
|
||||
step("Click 'Apply' button") {
|
||||
onOrganizeTokensScreen { applyButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert tokens were ungrouped on 'Main screen'") {
|
||||
onMainScreen { tokenNetworkGroupTitle(tokenNetwork).assertIsNotDisplayed() }
|
||||
onMainScreen { tokenNetworkGroupTitle(networkTitleMain).assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -185,6 +192,9 @@ class OrganizeTokensTest : BaseTestCase() {
|
|||
tokenWithTitleAndPosition(polExMaticTitle, 3).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
step("Open organize menu") {
|
||||
onOrganizeTokensScreen { organizeMenuButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click 'By Balance' button") {
|
||||
onOrganizeTokensScreen {
|
||||
sortByBalanceButton.clickWithAssertion()
|
||||
|
|
|
|||
|
|
@ -35,11 +35,7 @@ class ScanCardTest : BaseTestCase() {
|
|||
openMainScreen(cardType)
|
||||
}
|
||||
step("Check 'Main' screen for '${cardType.name}' $cardBlockchain card") {
|
||||
checkSingleCurrencyMainScreen(
|
||||
cardBlockchain = cardBlockchain,
|
||||
cardTitle = cardType.name,
|
||||
withTransactions = true
|
||||
)
|
||||
checkSingleCurrencyMainScreen(cardTitle = cardType.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,7 +53,7 @@ class ScanCardTest : BaseTestCase() {
|
|||
openMainScreen(mockContent = cardType, isTwinsCard = true)
|
||||
}
|
||||
step("Check 'Main' screen for '$cardName' $cardBlockchain card") {
|
||||
checkSingleCurrencyMainScreen(cardBlockchain = cardBlockchain, cardTitle = cardName)
|
||||
checkSingleCurrencyMainScreen(cardTitle = cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -66,7 +62,6 @@ class ScanCardTest : BaseTestCase() {
|
|||
@DisplayName("Scan: Card with Secp256k1 curve")
|
||||
@Test
|
||||
fun secpk1CurveCardScanTest() {
|
||||
val devicesCount = "1 device"
|
||||
val cardType: MockContent = Secpk1CurveMockContent
|
||||
val cardName = "Wallet"
|
||||
val card = "card with Secp256k1 curve"
|
||||
|
|
@ -75,12 +70,8 @@ class ScanCardTest : BaseTestCase() {
|
|||
step("Open 'Main Screen' on $card") {
|
||||
openMainScreen(mockContent = cardType)
|
||||
}
|
||||
step("Check 'Main' screen for $card curve with devices count = '$devicesCount'") {
|
||||
checkMultiCurrencyMainScreen(
|
||||
devicesCount = devicesCount,
|
||||
cardTitle = cardName,
|
||||
withWalletImage = false
|
||||
)
|
||||
step("Check 'Main' screen for $card curve") {
|
||||
checkMultiCurrencyMainScreen(cardTitle = cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -99,11 +90,7 @@ class ScanCardTest : BaseTestCase() {
|
|||
openMainScreen(mockContent = cardType)
|
||||
}
|
||||
step("Check 'Main' screen for $card with blockchain: '$cardBlockchain'") {
|
||||
checkSingleCurrencyMainScreen(
|
||||
cardBlockchain = cardBlockchain,
|
||||
cardTitle = cardName,
|
||||
withWalletImage = false
|
||||
)
|
||||
checkSingleCurrencyMainScreen(cardTitle = cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -112,7 +99,6 @@ class ScanCardTest : BaseTestCase() {
|
|||
@DisplayName("Scan: 'Shiba' card")
|
||||
@Test
|
||||
fun shibaCardScanTest() {
|
||||
val devicesCount = "2 devices"
|
||||
val cardType: MockContent = ShibaMockContent
|
||||
val cardName = "Wallet"
|
||||
val card = "Shiba"
|
||||
|
|
@ -121,8 +107,8 @@ class ScanCardTest : BaseTestCase() {
|
|||
step("Open 'Main Screen' on '$card' card") {
|
||||
openMainScreen(mockContent = cardType)
|
||||
}
|
||||
step("Check 'Main' screen for '$card' card with devices count = '$devicesCount'") {
|
||||
checkMultiCurrencyMainScreen(devicesCount, cardName)
|
||||
step("Check 'Main' screen for '$card' card") {
|
||||
checkMultiCurrencyMainScreen(cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -131,7 +117,6 @@ class ScanCardTest : BaseTestCase() {
|
|||
@DisplayName("Scan: 'Ring'")
|
||||
@Test
|
||||
fun ringScanTest() {
|
||||
val devicesCount = "3 devices"
|
||||
val cardType: ProductType = ProductType.Ring
|
||||
val cardName = "Wallet"
|
||||
val ring = "Ring"
|
||||
|
|
@ -140,8 +125,8 @@ class ScanCardTest : BaseTestCase() {
|
|||
step("Open 'Main Screen' on '$ring'") {
|
||||
openMainScreen(productType = cardType)
|
||||
}
|
||||
step("Check 'Main' screen for '$ring' with devices count = '$devicesCount'") {
|
||||
checkMultiCurrencyMainScreen(devicesCount, cardName)
|
||||
step("Check 'Main' screen for '$ring'") {
|
||||
checkMultiCurrencyMainScreen(cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -150,7 +135,6 @@ class ScanCardTest : BaseTestCase() {
|
|||
@DisplayName("Scan: 'Wallet' card")
|
||||
@Test
|
||||
fun walletCardScanTest() {
|
||||
val devicesCount = "1 device"
|
||||
val cardType: ProductType = ProductType.Wallet
|
||||
val cardName = "Wallet"
|
||||
|
||||
|
|
@ -158,8 +142,8 @@ class ScanCardTest : BaseTestCase() {
|
|||
step("Open 'Main Screen' on '$cardName' card") {
|
||||
openMainScreen(productType = cardType)
|
||||
}
|
||||
step("Check 'Main' screen for '$cardName' card with devices count = '$devicesCount'") {
|
||||
checkMultiCurrencyMainScreen(devicesCount, cardName)
|
||||
step("Check 'Main' screen for '$cardName' card") {
|
||||
checkMultiCurrencyMainScreen(cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,7 +152,6 @@ class ScanCardTest : BaseTestCase() {
|
|||
@DisplayName("Scan: 'Wallet 2' card")
|
||||
@Test
|
||||
fun wallet2ScanTest() {
|
||||
val devicesCount = "2 devices"
|
||||
val cardType: MockContent = Wallet2MockContent
|
||||
val cardName = "Wallet"
|
||||
val card = "Wallet 2"
|
||||
|
|
@ -177,8 +160,8 @@ class ScanCardTest : BaseTestCase() {
|
|||
step("Open 'Main Screen' on '$card' card") {
|
||||
openMainScreen(mockContent = cardType)
|
||||
}
|
||||
step("Check 'Main' screen for '$card' card with devices count = '$devicesCount'") {
|
||||
checkMultiCurrencyMainScreen(devicesCount, cardName)
|
||||
step("Check 'Main' screen for '$card' card") {
|
||||
checkMultiCurrencyMainScreen(cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -187,7 +170,6 @@ class ScanCardTest : BaseTestCase() {
|
|||
@DisplayName("Scan: Card with 4.12 firmware")
|
||||
@Test
|
||||
fun firmware412CardScanTest() {
|
||||
val devicesCount = "1 device"
|
||||
val cardType: MockContent = Firmware412MockContent
|
||||
val cardName = "Tangem card"
|
||||
val card = "card with 4.12 firmware"
|
||||
|
|
@ -196,8 +178,8 @@ class ScanCardTest : BaseTestCase() {
|
|||
step("Open 'Main Screen' on '$card'") {
|
||||
openMainScreen(mockContent = cardType)
|
||||
}
|
||||
step("Check 'Main' screen for '$card' with devices count = '$devicesCount'") {
|
||||
checkMultiCurrencyMainScreen(devicesCount, cardName)
|
||||
step("Check 'Main' screen for '$card'") {
|
||||
checkMultiCurrencyMainScreen(cardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,20 +56,14 @@ class StakingTest : BaseTestCase() {
|
|||
onTokenDetailsScreen { stakingBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Staking title' is displayed") {
|
||||
onTokenDetailsScreen { stakingTitle.assertIsDisplayed() }
|
||||
onTokenDetailsScreen { stakingEnabledTitle.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Staking fiat amount' is displayed") {
|
||||
onTokenDetailsScreen { stakingFiatAmount.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Staking dot' is displayed") {
|
||||
onTokenDetailsScreen { stakingDot.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Staking token amount' is displayed") {
|
||||
onTokenDetailsScreen { stakingTokenAmount.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Staking block chevron icon' is displayed") {
|
||||
onTokenDetailsScreen { stakingChevronIcon.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +133,7 @@ class StakingTest : BaseTestCase() {
|
|||
val scenarioName = "staking_eth_pol_balances_android"
|
||||
val scenarioState = "Started"
|
||||
val stakingAmount = "1"
|
||||
val stakingApy = "2.84%"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
|
|
@ -172,13 +167,10 @@ class StakingTest : BaseTestCase() {
|
|||
onTokenDetailsScreen { availableStakingBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Available staking block' title is displayed") {
|
||||
onTokenDetailsScreen { availableStakingBlockTitle.assertIsDisplayed() }
|
||||
onTokenDetailsScreen { stakingTitle.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Available staking block' text is displayed") {
|
||||
onTokenDetailsScreen { availableStakingBlockText.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Available staking block' currency icon is displayed") {
|
||||
onTokenDetailsScreen { availableStakingBlockCurrencyIcon.assertIsDisplayed() }
|
||||
onTokenDetailsScreen { availableStakingBlockText(stakingApy).assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Stake' button") {
|
||||
onTokenDetailsScreen { stakeButton.clickWithAssertion() }
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
package com.tangem.tests
|
||||
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.scenarios.openMainScreen
|
||||
import com.tangem.screens.onMainScreen
|
||||
import com.tangem.tap.domain.sdk.mocks.content.DevWalletMockContent
|
||||
import com.tangem.tap.domain.sdk.mocks.content.Wallet2WithSeedPhraseMockContent
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.qameta.allure.kotlin.Allure.step
|
||||
import io.qameta.allure.kotlin.AllureId
|
||||
import io.qameta.allure.kotlin.junit4.DisplayName
|
||||
import org.junit.Test
|
||||
|
|
|
|||
|
|
@ -389,6 +389,9 @@ class MainScreenActionButtonsTest : BaseTestCase() {
|
|||
step("Click on 'Buy' button") {
|
||||
onMainScreen { buyButton.performClick() }
|
||||
}
|
||||
step("Click on token: '$tokenTitle'") {
|
||||
onBuyTokenScreen { tokenWithTitleAndFiatAmount(tokenTitle).performClick() }
|
||||
}
|
||||
step("Click on 'Confirm' button in 'Dialog'") {
|
||||
waitForIdle()
|
||||
onDialog { confirmButton.clickWithAssertion() }
|
||||
|
|
|
|||
|
|
@ -2,16 +2,17 @@ package com.tangem.tests.actionButtons
|
|||
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
|
||||
import com.tangem.common.extensions.assertIsDimmed
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.scenarios.checkQrCodeBottomSheetScenario
|
||||
import com.tangem.scenarios.goToQrCodeBottomSheet
|
||||
import com.tangem.scenarios.openMainScreen
|
||||
import com.tangem.scenarios.synchronizeAddresses
|
||||
import com.tangem.screens.onAddFundsBottomSheet
|
||||
import com.tangem.screens.onMainScreen
|
||||
import com.tangem.screens.onSwapStoriesScreen
|
||||
import com.tangem.screens.onSwapTokenScreen
|
||||
import com.tangem.screens.onTokenDetailsScreen
|
||||
import com.tangem.screens.onTransferBottomSheet
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.qameta.allure.kotlin.AllureId
|
||||
import io.qameta.allure.kotlin.junit4.DisplayName
|
||||
|
|
@ -37,20 +38,41 @@ class TokenDetailsScreenActionButtonsTest : BaseTestCase() {
|
|||
waitForIdle()
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).performClick() }
|
||||
}
|
||||
step("Assert 'Receive' button is displayed") {
|
||||
onTokenDetailsScreen { receiveButton().assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Buy' button is displayed") {
|
||||
onTokenDetailsScreen { buyButton().assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Send' button is displayed") {
|
||||
onTokenDetailsScreen { sendButton().assertIsDisplayed() }
|
||||
step("Assert 'Add funds' button is displayed") {
|
||||
onTokenDetailsScreen { addFundsButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Swap' button is displayed") {
|
||||
onTokenDetailsScreen { swapButton().assertIsDisplayed() }
|
||||
onTokenDetailsScreen { swapButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Sell' button is displayed") {
|
||||
onTokenDetailsScreen { sellButton().assertIsDisplayed() }
|
||||
step("Assert 'Transfer' button is displayed") {
|
||||
onTokenDetailsScreen { transferButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Add funds' button") {
|
||||
onTokenDetailsScreen { addFundsButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Buy' button in bottom sheet is displayed") {
|
||||
onAddFundsBottomSheet { buyButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Swap' button in bottom sheet is displayed") {
|
||||
onAddFundsBottomSheet { swapButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Receive' button in bottom sheet is displayed") {
|
||||
onAddFundsBottomSheet { receiveButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Close' button in bottom sheet") {
|
||||
onAddFundsBottomSheet { closeButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Send' button in bottom sheet is displayed") {
|
||||
onTransferBottomSheet { sendButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Swap' button in bottom sheet is displayed") {
|
||||
onTransferBottomSheet { swapButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Sell' button in bottom sheet is displayed") {
|
||||
onTransferBottomSheet { sellButton.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -72,20 +94,41 @@ class TokenDetailsScreenActionButtonsTest : BaseTestCase() {
|
|||
waitForIdle()
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).performClick() }
|
||||
}
|
||||
step("Assert 'Receive' button is not dimmed") {
|
||||
onTokenDetailsScreen { receiveButton().assertIsDimmed(false) }
|
||||
step("Assert 'Add funds' button is enabled") {
|
||||
onTokenDetailsScreen { addFundsButton.assertIsEnabled() }
|
||||
}
|
||||
step("Assert 'Buy' button is not dimmed") {
|
||||
onTokenDetailsScreen { buyButton().assertIsDimmed(false) }
|
||||
step("Assert 'Swap' button is disabled") {
|
||||
onTokenDetailsScreen { swapButton.assertIsNotEnabled() }
|
||||
}
|
||||
step("Assert 'Send' button is not dimmed") {
|
||||
onTokenDetailsScreen { sendButton().assertIsDimmed(false) }
|
||||
step("Assert 'Transfer' button is enabled") {
|
||||
onTokenDetailsScreen { transferButton.assertIsEnabled() }
|
||||
}
|
||||
step("Assert 'Swap' button is dimmed") {
|
||||
onTokenDetailsScreen { swapButton().assertIsDimmed() }
|
||||
step("Click on 'Add funds' button") {
|
||||
onTokenDetailsScreen { addFundsButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Sell' button is dimmed") {
|
||||
onTokenDetailsScreen { sellButton().assertIsDimmed() }
|
||||
step("Assert 'Buy' button in bottom sheet is enabled") {
|
||||
onAddFundsBottomSheet { buyButton.assertIsEnabled() }
|
||||
}
|
||||
step("Assert 'Swap' button in bottom sheet is disabled") {
|
||||
onAddFundsBottomSheet { swapButton.assertIsNotEnabled() }
|
||||
}
|
||||
step("Assert 'Receive' button in bottom sheet is enabled") {
|
||||
onAddFundsBottomSheet { receiveButton.assertIsEnabled() }
|
||||
}
|
||||
step("Click on 'Close' button in bottom sheet") {
|
||||
onAddFundsBottomSheet { closeButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Send' button in bottom sheet is enabled") {
|
||||
onTransferBottomSheet { sendButton.assertIsEnabled() }
|
||||
}
|
||||
step("Assert 'Swap' button in bottom sheet is disabled") {
|
||||
onTransferBottomSheet { swapButton.assertIsNotEnabled() }
|
||||
}
|
||||
step("Assert 'Sell' button in bottom sheet is disabled") {
|
||||
onTransferBottomSheet { sellButton.assertIsNotEnabled() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +152,7 @@ class TokenDetailsScreenActionButtonsTest : BaseTestCase() {
|
|||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).performClick() }
|
||||
}
|
||||
step("Click on 'Swap' button") {
|
||||
onTokenDetailsScreen { swapButton().performClick() }
|
||||
onTokenDetailsScreen { swapButton.performClick() }
|
||||
}
|
||||
step("Close 'Stories' screen") {
|
||||
onSwapStoriesScreen { closeButton.clickWithAssertion() }
|
||||
|
|
@ -140,8 +183,11 @@ class TokenDetailsScreenActionButtonsTest : BaseTestCase() {
|
|||
waitForIdle()
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).performClick() }
|
||||
}
|
||||
step("Click on 'Receive' button") {
|
||||
onTokenDetailsScreen { receiveButton().performClick() }
|
||||
step("Click on 'Add funds' button") {
|
||||
onTokenDetailsScreen { addFundsButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Receive' button in bottom sheet") {
|
||||
onAddFundsBottomSheet { receiveButton.clickWithAssertion() }
|
||||
}
|
||||
step("Go to QR code bottom sheet") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
package com.tangem.tests.balance
|
||||
|
||||
import androidx.compose.ui.test.longClick
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.scenarios.openMainScreen
|
||||
import com.tangem.scenarios.synchronizeAddresses
|
||||
import com.tangem.screens.onMainScreen
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.qameta.allure.kotlin.AllureId
|
||||
import io.qameta.allure.kotlin.junit4.DisplayName
|
||||
import org.junit.Test
|
||||
|
||||
@HiltAndroidTest
|
||||
class TotalBalanceLongTapTest : BaseTestCase() {
|
||||
|
||||
@Test
|
||||
@AllureId("3965")
|
||||
@DisplayName("Total balance: check long tap on block without biometry")
|
||||
fun whenBiometryIsOffTest() {
|
||||
setupHooks().run {
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Long tap on total balance block") {
|
||||
onMainScreen {
|
||||
totalBalanceContainer.performTouchInput {
|
||||
longClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Assert 'Rename' button is displayed") {
|
||||
onMainScreen { totalBalanceMenuRenameWallet.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Delete' button is not displayed") {
|
||||
onMainScreen { totalBalanceMenuDeleteWallet.assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.tests.balance
|
|||
import androidx.compose.ui.test.longClick
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.TOTAL_BALANCE
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
|
||||
import com.tangem.common.extensions.*
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
|
|
@ -82,28 +83,27 @@ class TotalBalanceUpdateTest : BaseTestCase() {
|
|||
step("Set WireMock scenario: '$scenarioName' to state: '$scenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = scenarioName, state = scenarioState)
|
||||
}
|
||||
step("Click on 'Add to portfolio' button") {
|
||||
onMarketsScreen { addToPortfolioButton.clickWithAssertion() }
|
||||
step("Click on 'Add' button in 'Markets' bottom sheet") {
|
||||
onMarketsScreen { addButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on main network") {
|
||||
onMarketsScreen { mainNetworkSuffix.performClick() }
|
||||
}
|
||||
step("Click on 'Add' button") {
|
||||
onDialog { addButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Continue' is not displayed") {
|
||||
onDialog { addButton.assertIsNotDisplayed() }
|
||||
step("Click on 'Add' button in 'Add token' bottom sheet") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
onAddTokenBottomSheet {
|
||||
addButton.performClick()
|
||||
}
|
||||
onAddTokenBottomSheet { laterButton.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Click on 'Later' button") {
|
||||
onDialog { laterButton.clickWithAssertion() }
|
||||
onAddTokenBottomSheet { laterButton.performClick() }
|
||||
}
|
||||
step("Go back to 'Markets: tokens list'") {
|
||||
step("Press 'Back' button") {
|
||||
waitForIdle()
|
||||
onMarketsScreen { topBarBackButton.clickWithAssertion() }
|
||||
device.uiDevice.pressBack()
|
||||
}
|
||||
step("Close 'Markets screen'") {
|
||||
onSearchBar { searchField.assertIsDisplayed() }
|
||||
swipeMarketsBlock(SwipeDirection.DOWN)
|
||||
step("Press 'Back' button") {
|
||||
waitForIdle()
|
||||
device.uiDevice.pressBack()
|
||||
}
|
||||
step("Assert $updatedBalance is displayed in total balance") {
|
||||
onMainScreen { totalBalanceText.assertTextContains(updatedBalance) }
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package com.tangem.tests.main
|
|||
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.USER_TOKENS_API_SCENARIO
|
||||
import com.tangem.common.extensions.SwipeDirection
|
||||
import com.tangem.common.extensions.swipeVertical
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.scenarios.openMainScreen
|
||||
|
|
@ -35,7 +37,7 @@ class MainScreenTest : BaseTestCase() {
|
|||
}
|
||||
|
||||
@AllureId("8748")
|
||||
@DisplayName("Main: check 'Organize tokens' button with single token no accounts")
|
||||
@DisplayName("Main: check 'Add & Manage' button with single token no accounts")
|
||||
@Test
|
||||
fun checkOrganizeTokensButtonWithSingleTokenNoAccountsTest() {
|
||||
val scenarioState = "Cardano"
|
||||
|
|
@ -56,14 +58,14 @@ class MainScreenTest : BaseTestCase() {
|
|||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Assert 'Add & Manage' button is not displayed") {
|
||||
onMainScreen { addAndManageButtonNode.assertIsNotDisplayed()}
|
||||
step("Assert 'Add & Manage' button is displayed") {
|
||||
onMainScreen { addAndManageButtonNode.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("8749")
|
||||
@DisplayName("Main: check 'Organize tokens' button with single token two accounts")
|
||||
@DisplayName("Main: check 'Add & Manage' button with single token two accounts")
|
||||
@Test
|
||||
fun checkOrganizeTokensButtonWithSingleTokenMultiAccountsTest() {
|
||||
val scenarioState = "TwoAccountsSingleTokenEach"
|
||||
|
|
@ -81,14 +83,14 @@ class MainScreenTest : BaseTestCase() {
|
|||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Assert 'Add & Manage' button is not displayed") {
|
||||
onMainScreen { addAndManageButtonNode.assertIsNotDisplayed()}
|
||||
step("Assert 'Add & Manage' button is displayed") {
|
||||
onMainScreen { addAndManageButtonNode.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("8750")
|
||||
@DisplayName("Main: check 'Organize tokens' button with multiple tokens two accounts")
|
||||
@DisplayName("Main: check 'Add & Manage' button with multiple tokens two accounts")
|
||||
@Test
|
||||
fun checkOrganizeTokensButtonWithMultipleTokensMultiAccountsTest() {
|
||||
val scenarioState = "TwoAccountsMixed"
|
||||
|
|
@ -106,8 +108,11 @@ class MainScreenTest : BaseTestCase() {
|
|||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Swipe up") {
|
||||
swipeVertical(SwipeDirection.UP, startHeightRatio = 0.6f, endHeightRatio = 0.1f)
|
||||
}
|
||||
step("Assert 'Add & Manage' button is displayed") {
|
||||
onMainScreen { addAndManageButtonNode.assertIsDisplayed()}
|
||||
onMainScreen { addAndManageButtonNode.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import org.junit.Test
|
|||
class WarningsTest : BaseTestCase() {
|
||||
|
||||
@AllureId("184")
|
||||
@DisplayName("Token list: hide token by long tap")
|
||||
@DisplayName("Warnings: missing address warning")
|
||||
@Test
|
||||
fun checkUnavailableNetworksWarningTest() {
|
||||
val scenarioState = "MissingDerivation"
|
||||
|
|
@ -38,9 +38,6 @@ class WarningsTest : BaseTestCase() {
|
|||
step("Synchronize addresses") {
|
||||
synchronizeAddresses(isBalanceAvailable = false)
|
||||
}
|
||||
step("Assert 'Missing addresses' notification icon is displayed") {
|
||||
onMainScreen { missingAddressNotificationIcon.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Missing addresses' notification title is displayed") {
|
||||
onMainScreen { missingAddressNotificationTitle.assertIsDisplayed() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tests.markets
|
||||
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.annotations.ApiEnv
|
||||
import com.tangem.common.annotations.ApiEnvConfig
|
||||
|
|
@ -39,6 +40,7 @@ class MarketsExchangesTest : BaseTestCase() {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
@Test
|
||||
@AllureId("56")
|
||||
@ApiEnv(ApiEnvConfig(ApiConfig.ID.TangemTech, ApiEnvironment.PROD))
|
||||
|
|
@ -60,9 +62,8 @@ class MarketsExchangesTest : BaseTestCase() {
|
|||
onMarketsScreen { tokenWithTitle(tokenName).clickWithAssertion() }
|
||||
waitForIdle()
|
||||
}
|
||||
step("Scroll down") {
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
step("Scroll to 'Listed on exchanges' block") {
|
||||
onMarketsScreen { scrollToListedOnBlock() }
|
||||
}
|
||||
step("Assert 'Listed on exchanges' block has title") {
|
||||
onMarketsScreen { listedOnBlockContainer.assertIsDisplayed() }
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ class RecentBlockTest : BaseTestCase() {
|
|||
val sendAmount = "1"
|
||||
val txHistoryScenarioState = "11OutgoingTransactions"
|
||||
val recipientAddressBase = "DJ2TaZ5vvp3mBLugUpKjVM3pRBLi4uYaq"
|
||||
val shortenedRecipientAddress = "DJ2TaZ5vvp3mBLugU...Li4uYaq123456789b"
|
||||
val longRecipientAddress = recipientAddressBase + "123456789b"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
|
|
@ -261,7 +261,7 @@ class RecentBlockTest : BaseTestCase() {
|
|||
checkRecentAddressItem(address = DOGECOIN_ADDRESS, description = recentTransactionAmount1)
|
||||
}
|
||||
step("Check recent address item №2") {
|
||||
checkRecentAddressItem(address = shortenedRecipientAddress, description = recentTransactionAmount2)
|
||||
checkRecentAddressItem(address = longRecipientAddress, description = recentTransactionAmount2)
|
||||
}
|
||||
step("Check recent address item №3") {
|
||||
checkRecentAddressItem(address = recipientAddressBase + "k", description = recentTransactionAmount2)
|
||||
|
|
|
|||
|
|
@ -246,8 +246,11 @@ class SendAddressScreenTest : BaseTestCase() {
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).performClick() }
|
||||
}
|
||||
step("Click on 'Send' button") {
|
||||
onTokenDetailsScreen { sendButton().performClick() }
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button in bottom sheet") {
|
||||
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
||||
}
|
||||
step("Set WireMock scenario: '$scenarioName' to state: '$scenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = scenarioName, state = scenarioState)
|
||||
|
|
|
|||
|
|
@ -46,8 +46,11 @@ class SendConfirmScreenTest : BaseTestCase() {
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button") {
|
||||
onTokenDetailsScreen { sendButton().performClick() }
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button in bottom sheet") {
|
||||
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type '$inputAmount' in input text field") {
|
||||
onSendScreen {
|
||||
|
|
@ -123,8 +126,11 @@ class SendConfirmScreenTest : BaseTestCase() {
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button") {
|
||||
onTokenDetailsScreen { sendButton().performClick() }
|
||||
step("Click on 'Transfer' button") {
|
||||
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Send' button in bottom sheet") {
|
||||
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type '$inputAmount' in input text field") {
|
||||
onSendScreen {
|
||||
|
|
|
|||
|
|
@ -281,13 +281,13 @@ class SendFeeScreenTest : BaseTestCase() {
|
|||
fun checkNetworkFeeBottomSheetForBitcoinTest() {
|
||||
val tokenName = "Bitcoin"
|
||||
val tokenAmount = "0.00000001"
|
||||
val feeAmount = "$2.86"
|
||||
val feeAmount = "$0.48"
|
||||
val fiatFeeAmount = "$0.24"
|
||||
val marketSelectorItem = getResourceString(R.string.common_fee_selector_option_market)
|
||||
val fastSelectorItem = getResourceString(R.string.common_fee_selector_option_fast)
|
||||
val slowSelectorItem = getResourceString(R.string.common_fee_selector_option_slow)
|
||||
val feeUpTo = getResourceString(R.string.send_max_fee)
|
||||
val feeUpToValue = "0.0000264 BTC"
|
||||
val feeUpToValue = "0.0000044 BTC"
|
||||
val newFeeUpToValue = "0.0000022 BTC"
|
||||
val satoshi = getResourceString(R.string.send_satoshi_per_byte_title)
|
||||
val satoshiValue = "2"
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ import com.tangem.common.BaseTestCase
|
|||
import com.tangem.common.constants.TestConstants.KASPA_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.QUOTES_API_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.USER_TOKENS_API_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.scenarios.checkSendWarning
|
||||
import com.tangem.scenarios.openSendConfirmScreenViaNextButton
|
||||
import com.tangem.scenarios.openSendScreen
|
||||
import com.tangem.screens.onSendAddressScreen
|
||||
import com.tangem.screens.onSendScreen
|
||||
|
|
@ -145,8 +147,10 @@ class KaspaWarningsTest : BaseTestCase() {
|
|||
step("Type address in input text field") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(KASPA_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen { nextButton.clickWithAssertion() }
|
||||
step("Click 'Next' button until 'Send Confirm' screen opens") {
|
||||
composeTestRule.waitUntil(timeoutMillis = WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
runCatching { openSendConfirmScreenViaNextButton() }.isSuccess
|
||||
}
|
||||
}
|
||||
step("Assert 'UTXO limit warning' is displayed") {
|
||||
checkSendWarning(
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ package com.tangem.tests.swap
|
|||
import androidx.compose.ui.test.longClick
|
||||
import androidx.test.InstrumentationRegistry.getTargetContext
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
|
||||
import com.tangem.common.extensions.assertHasBadge
|
||||
import com.tangem.common.extensions.restartApp
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
|
|
@ -18,101 +16,6 @@ import org.junit.Test
|
|||
@HiltAndroidTest
|
||||
class SwapStoriesTest : BaseTestCase() {
|
||||
|
||||
@AllureId("5453")
|
||||
@DisplayName("Check 'Swap' button badge on 'Main' screen")
|
||||
@Test
|
||||
fun checkMainScreenSwapButtonBadgeTest() {
|
||||
|
||||
setupHooks().run {
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Assert 'Swap' button has badge") {
|
||||
onMainScreen { swapButton.assertHasBadge() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.MainScreen)
|
||||
}
|
||||
step("Click on 'Close' button") {
|
||||
onSwapTokenScreen { closeButton.performClick() }
|
||||
}
|
||||
step("Assert 'Swap' button has not badge") {
|
||||
onMainScreen { swapButton.assertHasBadge(false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("5454")
|
||||
@DisplayName("Check 'Swap' button badge on token details screen")
|
||||
@Test
|
||||
fun checkTokenDetailsScreenSwapButtonTest() {
|
||||
val tokenName = "Ethereum"
|
||||
|
||||
setupHooks().run {
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).performClick() }
|
||||
}
|
||||
step("Assert 'Swap' button has badge") {
|
||||
onTokenDetailsScreen { swapButton().assertHasBadge() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails)
|
||||
}
|
||||
step("Click on 'Close' button") {
|
||||
onSwapTokenScreen { closeButton.performClick() }
|
||||
}
|
||||
step("Assert 'Swap' button has not badge") {
|
||||
onTokenDetailsScreen { swapButton().assertHasBadge(false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("5455")
|
||||
@DisplayName("Check 'Swap' button badge on token details in 'Market' screen")
|
||||
@Test
|
||||
fun checkMarketTokenDetailsScreenSwapButtonTest() {
|
||||
val tokenName = "Ethereum"
|
||||
val badgeShown = "Badge shown"
|
||||
val badgeHidden = "Badge hidden"
|
||||
|
||||
setupHooks().run {
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Open 'Markets' token details screen for token '$tokenName'") {
|
||||
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
|
||||
}
|
||||
step("Assert 'Swap' button has badge") {
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertIsDisplayed() }
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertContentDescriptionEquals(badgeShown) }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails)
|
||||
}
|
||||
step("Click on 'Close' button") {
|
||||
onSwapTokenScreen { closeButton.performClick() }
|
||||
}
|
||||
step("Assert 'Swap' button has not badge") {
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertContentDescriptionEquals(badgeHidden) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("5469")
|
||||
@DisplayName("Check unavailable swap stories on 'Main' screen")
|
||||
@Test
|
||||
|
|
@ -136,9 +39,6 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Assert 'Swap' button has not badge") {
|
||||
onMainScreen { swapButton.assertHasBadge(false) }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.MainScreen, storiesExist = false)
|
||||
}
|
||||
|
|
@ -155,9 +55,6 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
waitForIdle()
|
||||
onMainScreen { swapButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Swap' button has badge") {
|
||||
onMainScreen { swapButton.assertHasBadge() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.MainScreen, storiesExist = true)
|
||||
}
|
||||
|
|
@ -192,9 +89,6 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).performClick() }
|
||||
}
|
||||
step("Assert 'Swap' button has not badge") {
|
||||
onTokenDetailsScreen { swapButton().assertHasBadge(false) }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = false)
|
||||
}
|
||||
|
|
@ -207,13 +101,6 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Restart app") {
|
||||
restartApp(packageName)
|
||||
}
|
||||
step("Assert 'Swap' button has badge") {
|
||||
waitForIdle()
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
composeTestRule.mainClock.advanceTimeBy(500)
|
||||
onMainScreen { swapButton.assertHasBadge() }
|
||||
}
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = true)
|
||||
}
|
||||
|
|
@ -228,8 +115,6 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
val scenarioErrorState = "Error"
|
||||
val packageName = getTargetContext().packageName
|
||||
val tokenName = "Ethereum"
|
||||
val badgeShown = "Badge shown"
|
||||
val badgeHidden = "Badge hidden"
|
||||
|
||||
setupHooks(
|
||||
additionalBeforeAppLaunchSection = {
|
||||
|
|
@ -246,16 +131,15 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Open 'Markets' token details screen for token '$tokenName'") {
|
||||
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
|
||||
step("Open 'Token details' from 'Markets' screen for token '$tokenName'") {
|
||||
openTokenDetailsFromMarketsScreen(blockchainName = tokenName, tokenName = tokenName)
|
||||
}
|
||||
step("Assert 'Swap' button has not badge") {
|
||||
step("Assert 'Swap' button is displayed") {
|
||||
waitForIdle()
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertIsDisplayed() }
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertContentDescriptionEquals(badgeHidden) }
|
||||
onTokenDetailsScreen { swapButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails, storiesExist = false)
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = false)
|
||||
}
|
||||
step("Click on 'Close' button") {
|
||||
onSwapTokenScreen { closeButton.performClick() }
|
||||
|
|
@ -266,16 +150,12 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Restart app") {
|
||||
restartApp(packageName)
|
||||
}
|
||||
step("Open 'Markets' token details screen for token '$tokenName'") {
|
||||
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
|
||||
}
|
||||
step("Assert 'Swap' button has badge") {
|
||||
step("Assert 'Swap' button is displayed") {
|
||||
waitForIdle()
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertIsDisplayed() }
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertContentDescriptionEquals(badgeShown) }
|
||||
onTokenDetailsScreen { swapButton.assertIsDisplayed() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails, storiesExist = true)
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -331,11 +211,8 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Click on token with name: '$tokenName'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenName).performClick() }
|
||||
}
|
||||
step("Assert 'Swap' button has badge") {
|
||||
onTokenDetailsScreen { swapButton().assertHasBadge() }
|
||||
}
|
||||
step("Click on 'Swap' button on 'Token details' screen") {
|
||||
onTokenDetailsScreen { swapButton().performClick() }
|
||||
onTokenDetailsScreen { swapButton.performClick() }
|
||||
}
|
||||
step("Check stories changes") {
|
||||
checkStoriesChanges()
|
||||
|
|
@ -369,11 +246,11 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Open 'Markets' token details screen for token '$tokenName'") {
|
||||
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
|
||||
step("Open 'Token details' from 'Markets' screen for token '$tokenName'") {
|
||||
openTokenDetailsFromMarketsScreen(blockchainName = tokenName, tokenName = tokenName)
|
||||
}
|
||||
step("Click on 'Swap' button on 'Markets' token details screen") {
|
||||
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.performClick() }
|
||||
onTokenDetailsScreen { swapButton.performClick() }
|
||||
}
|
||||
step("Check stories changes") {
|
||||
checkStoriesChanges()
|
||||
|
|
@ -388,7 +265,7 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
onSwapTokenScreen { closeButton.performClick() }
|
||||
}
|
||||
step("Open 'Swap' screen without stories") {
|
||||
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails, storiesExist = false)
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -433,6 +310,17 @@ class SwapStoriesTest : BaseTestCase() {
|
|||
step("Click on 'Close' button") {
|
||||
onSwapTokenScreen { closeButton.performClick() }
|
||||
}
|
||||
step("Long click on token with name: '$tokenName' again to reopen actions menu") {
|
||||
waitForIdle()
|
||||
onMainScreen {
|
||||
tokenWithTitleAndAddress(tokenName).performTouchInput {
|
||||
longClick(
|
||||
position = center,
|
||||
durationMillis = 1000L,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
step("Open 'Swap' screen without stories") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenActionsBottomSheet, storiesExist = false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
onTokenDetailsScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Swap' button") {
|
||||
onTokenDetailsScreen { swapButton().performClick() }
|
||||
onTokenDetailsScreen { swapButton.performClick() }
|
||||
}
|
||||
step("Close 'Stories' screen") {
|
||||
onSwapStoriesScreen { closeButton.clickWithAssertion() }
|
||||
|
|
@ -147,7 +147,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
disableMobileData()
|
||||
}
|
||||
step("Click on 'Swap' button") {
|
||||
onTokenDetailsScreen { swapButton().performClick() }
|
||||
onTokenDetailsScreen { swapButton.performClick() }
|
||||
}
|
||||
step("Close 'Stories' screen") {
|
||||
onSwapStoriesScreen { closeButton.clickWithAssertion() }
|
||||
|
|
@ -201,7 +201,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
onTokenDetailsScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Swap' button") {
|
||||
onTokenDetailsScreen { swapButton().performClick() }
|
||||
onTokenDetailsScreen { swapButton.performClick() }
|
||||
}
|
||||
step("Close 'Stories' screen") {
|
||||
onSwapStoriesScreen { closeButton.clickWithAssertion() }
|
||||
|
|
@ -304,7 +304,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
onTokenDetailsScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Swap' button") {
|
||||
onTokenDetailsScreen { swapButton().performClick() }
|
||||
onTokenDetailsScreen { swapButton.performClick() }
|
||||
}
|
||||
step("Close 'Stories' screen") {
|
||||
onSwapStoriesScreen { closeButton.clickWithAssertion() }
|
||||
|
|
@ -510,7 +510,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
onMainScreen { tokenWithTitleAndAddress(polygon).clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Swap' button is not dimmed. Swap available") {
|
||||
onTokenDetailsScreen { swapButton().assertIsDimmed(false) }
|
||||
onTokenDetailsScreen { swapButton.assertIsEnabled() }
|
||||
}
|
||||
step("Press 'Back' button") {
|
||||
device.uiDevice.pressBack()
|
||||
|
|
@ -519,7 +519,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
onMainScreen { tokenWithTitleAndAddress(bitcoin).clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Swap' button is dimmed") {
|
||||
onTokenDetailsScreen { swapButton().assertIsDimmed(true) }
|
||||
onTokenDetailsScreen { swapButton.assertIsNotEnabled() }
|
||||
}
|
||||
step("Press 'Back' button") {
|
||||
device.uiDevice.pressBack()
|
||||
|
|
@ -528,7 +528,7 @@ class SwapTokenScreenTest : BaseTestCase() {
|
|||
onMainScreen { tokenWithTitleAndAddress(salam).clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Swap' button is dimmed") {
|
||||
onTokenDetailsScreen { swapButton().assertIsDimmed(true) }
|
||||
onTokenDetailsScreen { swapButton.assertIsNotEnabled() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import androidx.compose.ui.draw.BlurredEdgeTreatment
|
|||
import androidx.compose.ui.draw.blur
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.innerShadow
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.graphics.shadow.Shadow
|
||||
|
|
@ -38,6 +39,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.TokenDetailsScreenTestTags
|
||||
import com.tangem.core.res.R as CoreResR
|
||||
|
||||
private const val TINTED_BACKGROUND_ALPHA = 0.1f
|
||||
|
|
@ -179,17 +181,23 @@ private fun EarnBlockTrailing(type: Type, trailingUM: EarnBlockUM.TrailingUM?, o
|
|||
}
|
||||
is EarnBlockUM.TrailingUM.Balance -> {
|
||||
if (!trailingUM.isBalanceHidden) {
|
||||
val fiatModifier = Modifier.layoutId(TangemRowLayoutId.END_TOP).let {
|
||||
if (type == Type.Staking) it.testTag(TokenDetailsScreenTestTags.STAKING_FIAT_AMOUNT) else it
|
||||
}
|
||||
val cryptoModifier = Modifier.layoutId(TangemRowLayoutId.END_BOTTOM).let {
|
||||
if (type == Type.Staking) it.testTag(TokenDetailsScreenTestTags.STAKING_TOKEN_AMOUNT) else it
|
||||
}
|
||||
Text(
|
||||
text = trailingUM.fiatValue.resolveAnnotatedReference(),
|
||||
style = TangemTheme.typography2.bodySemibold16,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
modifier = Modifier.layoutId(TangemRowLayoutId.END_TOP),
|
||||
modifier = fiatModifier,
|
||||
)
|
||||
Text(
|
||||
text = trailingUM.cryptoValue.resolveReference(),
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
modifier = Modifier.layoutId(TangemRowLayoutId.END_BOTTOM),
|
||||
modifier = cryptoModifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,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.tooling.preview.Preview
|
||||
import com.tangem.common.ui.R
|
||||
|
|
@ -35,6 +36,7 @@ import com.tangem.core.ui.extensions.resolveReference
|
|||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.TokenDetailsScreenTestTags
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -78,7 +80,8 @@ private fun ExpressTransactionItem(
|
|||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(TangemTheme.colors2.surface.level3)
|
||||
.clickable(onClick = info.onClick)
|
||||
.padding(TangemTheme.dimens2.x4),
|
||||
.padding(TangemTheme.dimens2.x4)
|
||||
.testTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM),
|
||||
) {
|
||||
TitleRow(
|
||||
title = info.title.resolveReference(),
|
||||
|
|
@ -104,7 +107,9 @@ private fun TitleRow(title: String, infoIconRes: Int?, infoIconTint: Color?) {
|
|||
text = title,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
modifier = Modifier.weight(1f),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.testTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_TITLE),
|
||||
)
|
||||
if (infoIconRes != null && infoIconTint != null) {
|
||||
Icon(
|
||||
|
|
@ -126,32 +131,42 @@ private fun AmountsRow(info: ExpressTransactionStateInfoUM) {
|
|||
CurrencyIcon(
|
||||
state = info.fromCurrencyIcon,
|
||||
shouldDisplayNetwork = false,
|
||||
modifier = Modifier.size(TangemTheme.dimens.size18),
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size18)
|
||||
.testTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_FROM_ICON),
|
||||
)
|
||||
EllipsisText(
|
||||
text = info.fromAmount.resolveReference(),
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
ellipsis = TextEllipsis.OffsetEnd(info.fromAmountSymbol.length),
|
||||
modifier = Modifier.weight(weight = 1f, fill = false),
|
||||
modifier = Modifier
|
||||
.weight(weight = 1f, fill = false)
|
||||
.testTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_FROM_AMOUNT),
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_forward_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors3.icon.tertiary,
|
||||
modifier = Modifier.size(TangemTheme.dimens.size18),
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size18)
|
||||
.testTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_SWAP_ICON),
|
||||
)
|
||||
CurrencyIcon(
|
||||
state = info.toCurrencyIcon,
|
||||
shouldDisplayNetwork = false,
|
||||
modifier = Modifier.size(TangemTheme.dimens.size18),
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size18)
|
||||
.testTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_TO_ICON),
|
||||
)
|
||||
EllipsisText(
|
||||
text = info.toAmount.resolveReference(),
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
ellipsis = TextEllipsis.OffsetEnd(info.toAmountSymbol.length),
|
||||
modifier = Modifier.weight(weight = 1f, fill = false),
|
||||
modifier = Modifier
|
||||
.weight(weight = 1f, fill = false)
|
||||
.testTag(TokenDetailsScreenTestTags.EXPRESS_STATUS_ITEM_TO_AMOUNT),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.semantics.disabled
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.ds.row.TangemRowContainer
|
||||
|
|
@ -68,7 +70,8 @@ fun TokenActionRow(
|
|||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
hapticManager = hapticManager,
|
||||
),
|
||||
)
|
||||
.semantics { if (!isEnabled) disabled() },
|
||||
) {
|
||||
LeadingIcon(iconRes = iconRes, accentColor = accentColor)
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
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
|
||||
|
|
@ -39,6 +40,7 @@ import com.tangem.core.ui.res.LocalBottomSheetAlwaysVisible
|
|||
import com.tangem.core.ui.res.LocalWindowSize
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.BaseBottomSheetTestTags
|
||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||
|
||||
/**
|
||||
|
|
@ -253,7 +255,8 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicBottomSheet(
|
|||
Column(
|
||||
modifier = contentModifier
|
||||
.background(containerColor)
|
||||
.heightIn(max = maxHeight),
|
||||
.heightIn(max = maxHeight)
|
||||
.testTag(BaseBottomSheetTestTags.CONTAINER),
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
title(model)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
|||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
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
|
||||
|
|
@ -40,6 +41,7 @@ import com.tangem.core.ui.components.sheetscaffold.TangemSheetState
|
|||
import com.tangem.core.ui.components.sheetscaffold.TangemSheetValue
|
||||
import com.tangem.core.ui.components.sheetscaffold.rememberSheetState
|
||||
import com.tangem.core.ui.res.*
|
||||
import com.tangem.core.ui.test.BaseBottomSheetTestTags
|
||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||
|
||||
const val MODAL_SHEET_MAX_HEIGHT = 0.8f
|
||||
|
|
@ -205,7 +207,8 @@ inline fun <reified T : TangemBottomSheetConfigContent> BsContent(
|
|||
.background(containerColor)
|
||||
.heightIn(max = maxHeight.dp)
|
||||
.fillMaxWidth()
|
||||
.nestedScroll(nestedScrollConnection),
|
||||
.nestedScroll(nestedScrollConnection)
|
||||
.testTag(BaseBottomSheetTestTags.CONTAINER),
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
title(model)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.semantics.disabled
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
|
@ -25,6 +28,7 @@ import com.tangem.core.ui.extensions.resolveReference
|
|||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.BaseActionButtonsBlockTestTags
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -51,7 +55,10 @@ fun ActionButtons(buttons: ImmutableList<TangemButtonUM>, modifier: Modifier = M
|
|||
TangemTheme.colors2.text.status.disabled
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x2_5),
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens2.x2_5)
|
||||
.testTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
|
||||
.semantics { if (!button.isEnabled) disabled() },
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.test.NotificationTestTags
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig.ButtonsState
|
||||
import com.tangem.core.ui.ds.button.*
|
||||
|
|
@ -66,7 +68,8 @@ fun TangemMessage(
|
|||
Alignment.Top
|
||||
},
|
||||
)
|
||||
.size(messageUM.iconSize),
|
||||
.size(messageUM.iconSize)
|
||||
.testTag(NotificationTestTags.ICON),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -115,14 +118,14 @@ fun TangemMessage(
|
|||
Image(
|
||||
painter = painterResource(config.iconResId),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(config.iconSize),
|
||||
modifier = Modifier.size(config.iconSize).testTag(NotificationTestTags.ICON),
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(config.iconResId),
|
||||
contentDescription = null,
|
||||
tint = iconTint,
|
||||
modifier = Modifier.size(config.iconSize),
|
||||
modifier = Modifier.size(config.iconSize).testTag(NotificationTestTags.ICON),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -166,7 +169,7 @@ fun TangemMessage(
|
|||
} else {
|
||||
Alignment.Start
|
||||
}
|
||||
Box(modifier = modifier) {
|
||||
Box(modifier = modifier.testTag(NotificationTestTags.CONTAINER)) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.matchParentSize()
|
||||
|
|
@ -244,6 +247,7 @@ private fun TangemMessageContent(
|
|||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
maxLines = 1,
|
||||
textAlign = textAlign,
|
||||
modifier = Modifier.testTag(NotificationTestTags.TITLE),
|
||||
)
|
||||
}
|
||||
if (subtitle != null) {
|
||||
|
|
@ -252,6 +256,7 @@ private fun TangemMessageContent(
|
|||
text = subtitle.resolveAnnotatedReference(),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
modifier = Modifier.testTag(NotificationTestTags.MESSAGE),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.core.ui.test
|
||||
|
||||
object BaseBottomSheetTestTags {
|
||||
const val CONTAINER = "BASE_BOTTOM_SHEET_CONTAINER"
|
||||
const val ACTION_BUTTON = "BASE_BOTTOM_SHEET_ACTION_BUTTON"
|
||||
const val ACTION_ICON = "BASE_BOTTOM_SHEET_ACTION_ICON"
|
||||
const val TITLE = "BASE_BOTTOM_SHEET_TITLE"
|
||||
|
|
|
|||
|
|
@ -4,4 +4,6 @@ object MarketsTestTags {
|
|||
const val TOKENS_LIST = "MARKETS_TOKENS_LIST"
|
||||
const val TOKENS_LIST_ITEM = "MARKETS_TOKENS_LIST_ITEM"
|
||||
const val LISTED_ON_EXCHANGES_COUNT = "MARKETS_LISTED_ON_EXCHANGES_COUNT"
|
||||
const val LISTED_ON_BLOCK = "MARKETS_LISTED_ON_BLOCK"
|
||||
const val TOKEN_DETAILS_CONTENT = "MARKETS_TOKEN_DETAILS_CONTENT"
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.core.ui.test
|
|||
|
||||
object OrganizeTokensScreenTestTags {
|
||||
// region OrganizeTokensTopBar
|
||||
const val MENU_BUTTON = "ORGANIZE_TOKENS_MENU_BUTTON"
|
||||
const val GROUP_BUTTON = "ORGANIZE_TOKENS_GROUP_BUTTON"
|
||||
const val SORT_BY_BALANCE_BUTTON = "SORT_BY_BALANCE_BUTTON"
|
||||
// endregion OrganizeTokensTopBar
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import androidx.compose.ui.draw.drawBehind
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import com.tangem.core.ui.test.MarketsTestTags
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
|
@ -116,6 +118,7 @@ private fun Content(
|
|||
LazyColumn(
|
||||
state = lazyListState,
|
||||
contentPadding = PaddingValues(bottom = bottomBarHeight, top = contentPadding.calculateTopPadding()),
|
||||
modifier = Modifier.testTag(MarketsTestTags.TOKEN_DETAILS_CONTENT),
|
||||
) {
|
||||
item("header") {
|
||||
Header(state = state)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
|
|
@ -48,6 +49,7 @@ import com.tangem.core.ui.ds.topbar.TangemTopBar
|
|||
import com.tangem.core.ui.ds.topbar.TangemTopBarType
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.res.LocalRedesignEnabled
|
||||
import com.tangem.core.ui.test.TokenElementsTestTags
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
|
|
@ -314,13 +316,15 @@ private fun ExchangeItemRowContent(exchangeItemUM: ExchangeItemUM.Content, modif
|
|||
tangemIconUM = exchangeItemUM.icon,
|
||||
modifier = Modifier
|
||||
.layoutId(layoutId = TangemRowLayoutId.HEAD)
|
||||
.size(TangemTheme.dimens2.x10),
|
||||
.size(TangemTheme.dimens2.x10)
|
||||
.testTag(TokenElementsTestTags.TOKEN_ICON),
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens2.x2)
|
||||
.layoutId(TangemRowLayoutId.START_TOP),
|
||||
.layoutId(TangemRowLayoutId.START_TOP)
|
||||
.testTag(TokenElementsTestTags.TOKEN_TITLE),
|
||||
text = exchangeItemUM.title.resolveReference(),
|
||||
style = TangemTheme.typography2.bodySemibold16,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
|
|
@ -329,7 +333,8 @@ private fun ExchangeItemRowContent(exchangeItemUM: ExchangeItemUM.Content, modif
|
|||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens2.x2)
|
||||
.layoutId(TangemRowLayoutId.START_BOTTOM),
|
||||
.layoutId(TangemRowLayoutId.START_BOTTOM)
|
||||
.testTag(TokenElementsTestTags.TOKEN_PRICE),
|
||||
text = exchangeItemUM.subTitle.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
|
|
@ -338,7 +343,8 @@ private fun ExchangeItemRowContent(exchangeItemUM: ExchangeItemUM.Content, modif
|
|||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens2.x2)
|
||||
.layoutId(TangemRowLayoutId.END_TOP),
|
||||
.layoutId(TangemRowLayoutId.END_TOP)
|
||||
.testTag(TokenElementsTestTags.TOKEN_FIAT_AMOUNT_TEXT),
|
||||
text = exchangeItemUM.volumeInUsd.resolveReference(),
|
||||
style = TangemTheme.typography2.bodySemibold16,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
|
|
@ -351,7 +357,8 @@ private fun ExchangeItemRowContent(exchangeItemUM: ExchangeItemUM.Content, modif
|
|||
shape = CircleShape,
|
||||
)
|
||||
.padding(vertical = 2.dp, horizontal = 6.dp)
|
||||
.layoutId(TangemRowLayoutId.END_BOTTOM),
|
||||
.layoutId(TangemRowLayoutId.END_BOTTOM)
|
||||
.testTag(TokenElementsTestTags.TOKEN_CRYPTO_AMOUNT),
|
||||
text = exchangeItemUM.auditLabel.text.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold11,
|
||||
color = getColorByTrustValue(exchangeItemUM.auditLabel.type),
|
||||
|
|
|
|||
|
|
@ -10,10 +10,9 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.testTag
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -65,7 +64,8 @@ private fun ListedOnBlockV1(state: ListedOnUM, modifier: Modifier = Modifier) {
|
|||
.clip(shape = TangemTheme.shapes.roundedCornersXMedium)
|
||||
.clickable(enabled = state is ListedOnUM.Content) {
|
||||
(state as? ListedOnUM.Content)?.onClick?.invoke()
|
||||
},
|
||||
}
|
||||
.testTag(MarketsTestTags.LISTED_ON_BLOCK),
|
||||
) {
|
||||
Description(
|
||||
state = state,
|
||||
|
|
@ -89,9 +89,11 @@ private fun ListedOnBlockV1(state: ListedOnUM, modifier: Modifier = Modifier) {
|
|||
@Composable
|
||||
private fun ListedOnBlockV2(state: ListedOnUM, modifier: Modifier = Modifier) {
|
||||
TokenMarketInformationBlock(
|
||||
modifier = modifier.clickable(enabled = state is ListedOnUM.Content) {
|
||||
(state as? ListedOnUM.Content)?.onClick?.invoke()
|
||||
},
|
||||
modifier = modifier
|
||||
.clickable(enabled = state is ListedOnUM.Content) {
|
||||
(state as? ListedOnUM.Content)?.onClick?.invoke()
|
||||
}
|
||||
.testTag(MarketsTestTags.LISTED_ON_BLOCK),
|
||||
title = {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1)) {
|
||||
|
|
@ -103,6 +105,7 @@ private fun ListedOnBlockV2(state: ListedOnUM, modifier: Modifier = Modifier) {
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.testTag(MarketsTestTags.LISTED_ON_EXCHANGES_COUNT),
|
||||
text = state.description.resolveReference(),
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
|
|
@ -178,7 +181,7 @@ internal fun ListedOnBlockPlaceholderV2(modifier: Modifier = Modifier) {
|
|||
private fun Description(state: ListedOnUM, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = state.description.resolveReference(),
|
||||
modifier = modifier.semantics { testTag = MarketsTestTags.LISTED_ON_EXCHANGES_COUNT },
|
||||
modifier = modifier.testTag(MarketsTestTags.LISTED_ON_EXCHANGES_COUNT),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.common.ui.account.AccountIconUM
|
||||
import com.tangem.common.ui.earn.EarnBlock
|
||||
import com.tangem.common.ui.earn.EarnBlockUM
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||
import com.tangem.common.ui.notifications.notifications
|
||||
|
|
@ -35,6 +37,7 @@ import com.tangem.core.ui.ds.button.TangemButtonUM
|
|||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.themedColor
|
||||
import com.tangem.core.ui.res.LocalHazeState
|
||||
import com.tangem.core.ui.test.TokenDetailsScreenTestTags
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.domain.models.account.CryptoPortfolioIcon
|
||||
|
|
@ -140,7 +143,7 @@ private fun BoxScope.TokenDetailsMarketBlockOverlay(
|
|||
)
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LongMethod")
|
||||
@Composable
|
||||
private fun TokenDetailsBody(
|
||||
tokenDetailsUM: TokenDetailsUM,
|
||||
|
|
@ -165,6 +168,7 @@ private fun TokenDetailsBody(
|
|||
|
||||
LazyColumn(
|
||||
modifier = modifier
|
||||
.testTag(TokenDetailsScreenTestTags.SCREEN_CONTAINER)
|
||||
.hazeSourceTangem(state = LocalHazeState.current)
|
||||
.topFade(
|
||||
height = topContentPadding,
|
||||
|
|
@ -190,9 +194,18 @@ private fun TokenDetailsBody(
|
|||
)
|
||||
tokenDetailsUM.earnBlockState?.let { earnBlock ->
|
||||
item(key = "staking_block") {
|
||||
val stakingTag = when {
|
||||
earnBlock is EarnBlockUM.Content &&
|
||||
earnBlock.type == EarnBlockUM.Type.Staking &&
|
||||
earnBlock.trailingUM is EarnBlockUM.TrailingUM.Button ->
|
||||
TokenDetailsScreenTestTags.STAKING_AVAILABLE_BLOCK
|
||||
else -> TokenDetailsScreenTestTags.STAKING_BLOCK
|
||||
}
|
||||
EarnBlock(
|
||||
state = earnBlock,
|
||||
modifier = itemModifier.padding(vertical = TangemTheme.dimens2.x3),
|
||||
modifier = itemModifier
|
||||
.padding(vertical = TangemTheme.dimens2.x3)
|
||||
.testTag(stakingTag),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,18 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.text.*
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import com.tangem.core.ui.test.TokenDetailsScreenTestTags
|
||||
import com.tangem.core.ui.test.TokenDetailsTopBarTestTags
|
||||
import androidx.compose.ui.text.Placeholder
|
||||
import androidx.compose.ui.text.PlaceholderVerticalAlign
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.rememberTextMeasurer
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
|
@ -58,7 +67,9 @@ internal fun TokenDetailsTopBar(topAppBarUM: TokenDetailsTopAppBarUM, modifier:
|
|||
.clip(CircleShape)
|
||||
.hazeEffectTangem { blurRadius = ACTION_BLUR_RADIUS }
|
||||
TangemTopBar(
|
||||
modifier = modifier.statusBarsPadding(),
|
||||
modifier = modifier
|
||||
.statusBarsPadding()
|
||||
.testTag(TokenDetailsTopBarTestTags.BACK_BUTTON),
|
||||
startContent = {
|
||||
TangemTopBarActionContent(
|
||||
modifier = actionModifier,
|
||||
|
|
@ -73,7 +84,7 @@ internal fun TokenDetailsTopBar(topAppBarUM: TokenDetailsTopAppBarUM, modifier:
|
|||
var isDropdownMenuShown by rememberSaveable { mutableStateOf(false) }
|
||||
Box {
|
||||
TangemTopBarActionContent(
|
||||
modifier = actionModifier,
|
||||
modifier = actionModifier.testTag(TokenDetailsTopBarTestTags.MORE_BUTTON),
|
||||
actionUM = TangemTopBarActionUM(
|
||||
iconRes = CoreUiR.drawable.ic_more_default_24,
|
||||
onClick = { isDropdownMenuShown = true },
|
||||
|
|
@ -105,7 +116,9 @@ internal fun TokenDetailsTopBar(topAppBarUM: TokenDetailsTopAppBarUM, modifier:
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x0_5),
|
||||
) {
|
||||
TokenDetailsTitle(titleState = topAppBarUM.titleState)
|
||||
Box(modifier = Modifier.testTag(TokenDetailsScreenTestTags.TOKEN_TITLE)) {
|
||||
TokenDetailsTitle(titleState = topAppBarUM.titleState)
|
||||
}
|
||||
Text(
|
||||
text = topAppBarUM.subtitle.resolveAnnotatedReference(),
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ internal fun OrganizeTokensContent(
|
|||
onClick = { isShowDropdownMenu = true },
|
||||
ghostModeProgress = 0f,
|
||||
),
|
||||
modifier = Modifier.testTag(OrganizeTokensScreenTestTags.MENU_BUTTON),
|
||||
type = TangemTopBarType.BottomSheet,
|
||||
)
|
||||
OrganizeDropDownMenu(
|
||||
|
|
@ -161,8 +162,7 @@ private fun TokenList(
|
|||
modifier = Modifier
|
||||
.align(Alignment.TopCenter)
|
||||
.reorderable(reorderableListState)
|
||||
.testTag(OrganizeTokensScreenTestTags.TOKENS_LAZY_LIST)
|
||||
.hazeSourceTangem(zIndex = 1f),
|
||||
.testTag(OrganizeTokensScreenTestTags.TOKENS_LAZY_LIST),
|
||||
state = reorderableListState.listState,
|
||||
contentPadding = listContentPadding,
|
||||
) {
|
||||
|
|
@ -221,7 +221,7 @@ private fun LazyItemScope.DraggableItem(
|
|||
|
||||
when (item) {
|
||||
is OrganizeRowItemUM.Network -> TangemHeaderRow(
|
||||
modifier = modifierWithBackground,
|
||||
modifier = modifierWithBackground.testTag(OrganizeTokensScreenTestTags.GROUP_TITLE_ITEM),
|
||||
reorderableState = reorderableState,
|
||||
headerRowUM = item.headerRowUM,
|
||||
)
|
||||
|
|
@ -231,7 +231,7 @@ private fun LazyItemScope.DraggableItem(
|
|||
isBalanceHidden = isBalanceHidden,
|
||||
)
|
||||
is OrganizeRowItemUM.Token -> OrganizeTokenRow(
|
||||
modifier = modifierWithBackground,
|
||||
modifier = modifierWithBackground.testTag(OrganizeTokensScreenTestTags.TOKEN_LIST_ITEM),
|
||||
tokenRowUM = item.tokenRowUM,
|
||||
reorderableState = reorderableState,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
|
|
@ -262,11 +262,15 @@ private fun BoxScope.BottomButtons(organizeTokensUM: OrganizeTokensUM) {
|
|||
) {
|
||||
TangemButton(
|
||||
buttonUM = organizeTokensUM.cancelButton,
|
||||
modifier = Modifier.weight(1f),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.testTag(OrganizeTokensScreenTestTags.CANCEL_BUTTON),
|
||||
)
|
||||
TangemButton(
|
||||
buttonUM = organizeTokensUM.applyButton,
|
||||
modifier = Modifier.weight(1f),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.testTag(OrganizeTokensScreenTestTags.APPLY_BUTTON),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import com.tangem.core.ui.test.BaseBottomSheetTestTags
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
|
|
@ -101,6 +103,7 @@ private fun TokenActionContextMenuContent(actions: ImmutableList<TokenActionButt
|
|||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
|
||||
modifier = Modifier
|
||||
.testTag(BaseBottomSheetTestTags.ACTION_BUTTON)
|
||||
.clickable(
|
||||
enabled = item.isEnabled,
|
||||
onClick = {
|
||||
|
|
@ -123,7 +126,9 @@ private fun TokenActionContextMenuContent(actions: ImmutableList<TokenActionButt
|
|||
} else {
|
||||
TangemTheme.colors2.graphic.neutral.primary
|
||||
},
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens2.x5)
|
||||
.testTag(BaseBottomSheetTestTags.ACTION_ICON),
|
||||
)
|
||||
Text(
|
||||
text = item.text.resolveReference(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ package com.tangem.feature.wallet.presentation.wallet.ui.components
|
|||
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import com.tangem.core.ui.ds.button.TangemButton
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.test.MainScreenTestTags
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
import com.tangem.features.tangempay.component.TangemPayMainBlockComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayMainUM
|
||||
|
|
@ -25,9 +29,14 @@ internal fun LazyListScope.organizeTokens2(state: WalletUM, itemModifier: Modifi
|
|||
key = "OrganizeTokensButton",
|
||||
contentType = "OrganizeTokensButton",
|
||||
) {
|
||||
val testTag = if (organizeButton.text == resourceReference(R.string.main_add_and_manage_tokens)) {
|
||||
MainScreenTestTags.ADD_AND_MANAGE_BUTTON
|
||||
} else {
|
||||
MainScreenTestTags.ORGANIZE_TOKENS_BUTTON
|
||||
}
|
||||
TangemButton(
|
||||
buttonUM = organizeButton,
|
||||
modifier = itemModifier,
|
||||
modifier = itemModifier.testTag(testTag),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ internal fun WalletBalance(
|
|||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = modifier
|
||||
.testTag(MainScreenTestTags.WALLET_LIST_ITEM)
|
||||
.alpha(alpha)
|
||||
.scale(scale)
|
||||
.snapToExitUntilCollapsed(behavior)
|
||||
|
|
@ -150,8 +151,12 @@ private fun SubtitleRow(walletBalanceUM: WalletBalanceUM, modifier: Modifier = M
|
|||
text = walletBalanceUM.name,
|
||||
style = TangemTheme.typography2.bodyRegular14,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
modifier = Modifier.testTag(MainScreenTestTags.CARD_TITLE),
|
||||
)
|
||||
TangemDeviceIcon(
|
||||
state = walletBalanceUM.deviceIcon,
|
||||
modifier = Modifier.testTag(MainScreenTestTags.CARD_IMAGE),
|
||||
)
|
||||
TangemDeviceIcon(state = walletBalanceUM.deviceIcon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,14 @@ import androidx.compose.foundation.rememberOverscrollEffect
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.paging.compose.LazyPagingItems
|
||||
import com.tangem.common.ui.notifications.notifications
|
||||
import com.tangem.common.ui.notifications.notificationsCarousel
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.components.transactions.txHistoryItems
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.test.MainScreenTestTags
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency.tokensListItems
|
||||
|
|
@ -40,7 +42,7 @@ internal fun WalletListContent(
|
|||
val itemModifier = movableItemModifier.padding(top = TangemTheme.dimens2.x3)
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier,
|
||||
modifier = modifier.testTag(MainScreenTestTags.SCREEN_CONTAINER),
|
||||
state = listState,
|
||||
contentPadding = contentPadding,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
|
|
|
|||
|
|
@ -93,7 +93,10 @@ internal fun WalletTopBar(
|
|||
),
|
||||
) {
|
||||
topBarConfig.endActions.forEach { action ->
|
||||
TangemTopBarActionContent(action)
|
||||
TangemTopBarActionContent(
|
||||
action,
|
||||
modifier = Modifier.testTag(MainScreenTestTags.MORE_BUTTON),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue