Updated on 2026-08-14

This commit is contained in:
Tangem 2026-05-06 16:41:08 +03:00
parent 08514bf020
commit 9f7f0b519f
11 changed files with 100 additions and 64 deletions

View file

@ -188,6 +188,7 @@ abstract class BaseTestCase : TestCase(
"ACCOUNTS_FEATURE_ENABLED" to true,
"GASLESS_APPROVAL_ENABLED" to true,
"MAIN_SCREEN_QR_SCANNING_ENABLED" to true,
"ADD_AND_MANAGE_TOKENS_ENABLED" to true,
)
)
}

View file

@ -30,11 +30,6 @@ fun BaseTestCase.verifyAddresses(seedPhrase: String, apiAddressesJson: String) {
runCatching { onMainScreen { totalBalanceText.assertTextContains(DASH_SIGN) } }.isSuccess
}
}
step("Assert 'Organize tokens' button is enabled") {
composeTestRule.waitUntil(timeoutMillis = WAIT_UNTIL_TIMEOUT_VERY_LONG) {
runCatching { onMainScreen { organizeTokensButton().assertIsEnabled() } }.isSuccess
}
}
step("Wait for all wallet managers to initialize") {
awaitWalletManagersStabilized()
}

View file

@ -72,8 +72,8 @@ fun BaseTestCase.checkSingleCurrencyMainScreen(
onMainScreen { emptyTransactionBlockExploreButton.assertIsDisplayed() }
}
}
step("Assert 'Organize tokens' button is not displayed") {
onMainScreen { organizeTokensButtonWithoutLazySearch.assertIsNotDisplayed() }
step("Assert 'Add & Manage' button is not displayed") {
onMainScreen { addAndManageButtonWithoutLazySearch.assertIsNotDisplayed() }
}
}
@ -112,8 +112,8 @@ fun BaseTestCase.checkMultiCurrencyMainScreen(
step("Assert 'Receive' button is not displayed") {
onMainScreen { receiveButton.assertIsNotDisplayed() }
}
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
step("Assert 'Add & Manage' button is displayed") {
onMainScreen { addAndManageButton().assertIsDisplayed() }
}
}

View file

@ -0,0 +1,22 @@
package com.tangem.scenarios
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.onAddAndManageBottomSheet
import com.tangem.screens.onMainScreen
import io.qameta.allure.kotlin.Allure.step
fun BaseTestCase.openOrganizeTokensScreen() {
step("Swipe to 'Add & Manage' button") {
swipeVertical(SwipeDirection.UP)
swipeVertical(SwipeDirection.UP)
}
step("Click on 'Add & Manage' button") {
onMainScreen { addAndManageButton().clickWithAssertion() }
}
step("Click on 'Organize tokens' button in bottom sheet") {
onAddAndManageBottomSheet { organizeTokensButton.clickWithAssertion() }
}
}

View file

@ -0,0 +1,31 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
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 com.tangem.core.res.R as CoreResR
class AddAndManageBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<AddAndManageBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
val title: KNode = child {
hasText(getResourceString(CoreResR.string.main_add_and_manage_tokens))
useUnmergedTree = true
}
val addTokensButton: KNode = child {
hasText(getResourceString(CoreResR.string.add_and_manage_sheet_manage_title))
useUnmergedTree = true
}
val organizeTokensButton: KNode = child {
hasText(getResourceString(CoreResR.string.add_and_manage_sheet_organize_title))
useUnmergedTree = true
}
}
internal fun BaseTestCase.onAddAndManageBottomSheet(function: AddAndManageBottomSheetPageObject.() -> Unit) =
onComposeScreen(composeTestRule, function)

View file

@ -19,6 +19,7 @@ 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
import com.tangem.core.res.R as CoreResR
import com.tangem.core.ui.R as CoreUiR
class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
@ -214,8 +215,8 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
hasText(getResourceString(CoreUiR.string.wallet_notification_address_copied))
}
val organizeTokensButtonNode: KNode = child {
hasTestTag(MainScreenTestTags.ORGANIZE_TOKENS_BUTTON)
val addAndManageButtonNode: KNode = child {
hasTestTag(MainScreenTestTags.ADD_AND_MANAGE_BUTTON)
useUnmergedTree = true
}
@ -265,18 +266,18 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
}
@OptIn(ExperimentalTestApi::class)
fun organizeTokensButton(): KNode {
fun addAndManageButton(): KNode {
return lazyList.childWith<LazyListItemNode> {
hasTestTag(MainScreenTestTags.ORGANIZE_TOKENS_BUTTON)
hasTestTag(MainScreenTestTags.ADD_AND_MANAGE_BUTTON)
}.child<KNode> {
hasText(getResourceString(R.string.organize_tokens_title))
hasText(getResourceString(CoreResR.string.main_add_and_manage_tokens))
useUnmergedTree = true
}
}
val organizeTokensButtonWithoutLazySearch: KNode = child {
hasTestTag(MainScreenTestTags.ORGANIZE_TOKENS_BUTTON)
hasText(getResourceString(R.string.organize_tokens_title))
val addAndManageButtonWithoutLazySearch: KNode = child {
hasTestTag(MainScreenTestTags.ADD_AND_MANAGE_BUTTON)
hasText(getResourceString(CoreResR.string.main_add_and_manage_tokens))
useUnmergedTree = true
}

View file

@ -2,10 +2,9 @@ package com.tangem.tests
import androidx.compose.ui.test.onAllNodesWithText
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.scenarios.openMainScreen
import com.tangem.scenarios.openOrganizeTokensScreen
import com.tangem.scenarios.synchronizeAddresses
import com.tangem.screens.onMainScreen
import com.tangem.screens.onOrganizeTokensScreen
@ -31,12 +30,8 @@ class OrganizeTokensTest : BaseTestCase() {
step("Click on 'Synchronize addresses' button") {
onMainScreen { synchronizeAddressesButton.clickWithAssertion() }
}
step("Swipe to 'Organize tokens' button") {
swipeVertical(SwipeDirection.UP)
swipeVertical(SwipeDirection.UP)
}
step("Click 'Organize tokens' button") {
onMainScreen { organizeTokensButton().clickWithAssertion() }
step("Open 'Organize tokens' screen") {
openOrganizeTokensScreen()
}
step("Assert 'Organize tokens' screen is opened") {
onOrganizeTokensScreen {
@ -56,12 +51,8 @@ class OrganizeTokensTest : BaseTestCase() {
step("Assert tokens were grouped on 'Main screen'") {
onMainScreen { tokenNetworkGroupTitle(tokenNetwork).assertIsDisplayed() }
}
step("Swipe to 'Organize tokens' button") {
swipeVertical(SwipeDirection.UP)
swipeVertical(SwipeDirection.UP)
}
step("Click 'Organize tokens' button") {
onMainScreen { organizeTokensButton().clickWithAssertion() }
step("Open 'Organize tokens' screen") {
openOrganizeTokensScreen()
}
step("Assert 'Organize tokens' screen is opened") {
onOrganizeTokensScreen {
@ -104,12 +95,8 @@ class OrganizeTokensTest : BaseTestCase() {
tokenWithTitleAndPosition(ethereumTitle, 1).assertIsDisplayed()
}
}
step("Swipe to 'Organize tokens' button") {
swipeVertical(SwipeDirection.UP)
swipeVertical(SwipeDirection.UP)
}
step("Click 'Organize tokens' button") {
onMainScreen { organizeTokensButton().clickWithAssertion() }
step("Open 'Organize tokens' screen") {
openOrganizeTokensScreen()
}
step("Check positions of tokens on 'Organize tokens' screen") {
onOrganizeTokensScreen {
@ -141,12 +128,8 @@ class OrganizeTokensTest : BaseTestCase() {
tokenWithTitleAndPosition(ethereumTitle, 1).assertIsDisplayed()
}
}
step("Swipe to 'Organize tokens' button") {
swipeVertical(SwipeDirection.UP)
swipeVertical(SwipeDirection.UP)
}
step("Click 'Organize tokens' button") {
onMainScreen { organizeTokensButton().clickWithAssertion() }
step("Open 'Organize tokens' screen") {
openOrganizeTokensScreen()
}
step("Drag $bitcoinTitle down on 'Organize tokens' screen") {
composeTestRule.waitUntil(timeoutMillis = 100_000) {
@ -191,12 +174,8 @@ class OrganizeTokensTest : BaseTestCase() {
tokenWithTitleAndPosition(polygonTitle, 2).assertIsDisplayed()
}
}
step("Swipe to 'Organize tokens' button") {
swipeVertical(SwipeDirection.UP)
swipeVertical(SwipeDirection.UP)
}
step("Click 'Organize tokens' button") {
onMainScreen { organizeTokensButton().clickWithAssertion() }
step("Open 'Organize tokens' screen") {
openOrganizeTokensScreen()
}
step("Check positions of tokens on 'Organize tokens' screen") {
onOrganizeTokensScreen {

View file

@ -40,8 +40,8 @@ class StakingTest : BaseTestCase() {
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
step("Assert 'Add & Manage' button is displayed") {
onMainScreen { addAndManageButton().assertIsDisplayed() }
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)
@ -98,8 +98,8 @@ class StakingTest : BaseTestCase() {
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
step("Assert 'Add & Manage' button is displayed") {
onMainScreen { addAndManageButton().assertIsDisplayed() }
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)
@ -156,8 +156,8 @@ class StakingTest : BaseTestCase() {
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
step("Assert 'Add & Manage' button is displayed") {
onMainScreen { addAndManageButton().assertIsDisplayed() }
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)

View file

@ -28,8 +28,8 @@ class MainScreenTest : BaseTestCase() {
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
step("Assert 'Add & Manage' button is displayed") {
onMainScreen { addAndManageButton().assertIsDisplayed() }
}
}
}
@ -56,8 +56,8 @@ class MainScreenTest : BaseTestCase() {
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Assert 'Organize tokens' button is not displayed") {
onMainScreen { organizeTokensButtonNode.assertIsNotDisplayed()}
step("Assert 'Add & Manage' button is not displayed") {
onMainScreen { addAndManageButtonNode.assertIsNotDisplayed()}
}
}
}
@ -81,8 +81,8 @@ class MainScreenTest : BaseTestCase() {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Assert 'Organize tokens' button is not displayed") {
onMainScreen { organizeTokensButtonNode.assertIsNotDisplayed()}
step("Assert 'Add & Manage' button is not displayed") {
onMainScreen { addAndManageButtonNode.assertIsNotDisplayed()}
}
}
}
@ -106,8 +106,8 @@ class MainScreenTest : BaseTestCase() {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Assert 'Organize tokens' button is not displayed") {
onMainScreen { organizeTokensButtonNode.assertIsDisplayed()}
step("Assert 'Add & Manage' button is displayed") {
onMainScreen { addAndManageButtonNode.assertIsDisplayed()}
}
}
}

View file

@ -7,6 +7,7 @@ object MainScreenTestTags {
const val TOKEN_LIST_ITEM = "MAIN_SCREEN_TOKEN_LIST_ITEM"
const val WALLET_LIST_ITEM = "MAIN_SCREEN_WALLET_LIST_ITEM"
const val ORGANIZE_TOKENS_BUTTON = "MAIN_SCREEN_ORGANIZE_TOKENS_BUTTON"
const val ADD_AND_MANAGE_BUTTON = "MAIN_SCREEN_ADD_AND_MANAGE_BUTTON"
const val CARD_TITLE = "MAIN_SCREEN_CARD_TITLE"
const val CARD_IMAGE = "MAIN_SCREEN_CARD_IMAGE"
const val DEVICES_COUNT = "MAIN_SCREEN_DEVICES_COUNT"

View file

@ -7,6 +7,7 @@ import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
import com.tangem.core.ui.components.buttons.actions.RoundedActionButton
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.WalletTokensListState
private const val ORGANIZE_BUTTON_CONTENT_TYPE = "OrganizeTokensButton"
@ -24,8 +25,13 @@ internal fun LazyListScope.organizeTokensButton(
modifier: Modifier = Modifier,
) {
item(key = ORGANIZE_BUTTON_CONTENT_TYPE, contentType = ORGANIZE_BUTTON_CONTENT_TYPE) {
val testTag = if (config.textRes == R.string.main_add_and_manage_tokens) {
MainScreenTestTags.ADD_AND_MANAGE_BUTTON
} else {
MainScreenTestTags.ORGANIZE_TOKENS_BUTTON
}
RoundedActionButton(
modifier = modifier.testTag(MainScreenTestTags.ORGANIZE_TOKENS_BUTTON),
modifier = modifier.testTag(testTag),
config = ActionButtonConfig(
text = resourceReference(id = config.textRes),
iconResId = config.iconRes,