diff --git a/app/src/androidTest/kotlin/com/tangem/scenarios/CheckMainScreenScenarios.kt b/app/src/androidTest/kotlin/com/tangem/scenarios/CheckMainScreenScenarios.kt index b8baf03580..75e7af6d4d 100644 --- a/app/src/androidTest/kotlin/com/tangem/scenarios/CheckMainScreenScenarios.kt +++ b/app/src/androidTest/kotlin/com/tangem/scenarios/CheckMainScreenScenarios.kt @@ -97,8 +97,8 @@ fun BaseTestCase.checkMultiCurrencyMainScreen( step("Assert devices count equal to '$devicesCount'") { onMainScreen { walletDevicesCount.assertTextContains(devicesCount) } } - step("Assert 'Buy' button is displayed") { - onMainScreen { buyButton.assertIsDisplayed() } + step("Assert 'Add funds' button is displayed") { + onMainScreen { addFundsButton.assertIsDisplayed() } } step("Assert 'Swap' button is displayed") { onMainScreen { swapButton.assertIsDisplayed() } @@ -119,8 +119,8 @@ fun BaseTestCase.checkMultiCurrencyMainScreen( fun BaseTestCase.assertActionButtonsForMultiCurrencyWallet(isEnabled: Boolean = true) { if (isEnabled) { - step("Assert 'Buy' button is enabled") { - onMainScreen { buyButton.assertIsEnabled() } + step("Assert 'Add funds' button is enabled") { + onMainScreen { addFundsButton.assertIsEnabled() } } step("Assert 'Swap' button is enabled") { onMainScreen { swapButton.assertIsEnabled() } @@ -129,8 +129,8 @@ fun BaseTestCase.assertActionButtonsForMultiCurrencyWallet(isEnabled: Boolean = onMainScreen { sellButton.assertIsEnabled() } } } else { - step("Assert 'Buy' button is not enabled") { - onMainScreen { buyButton.assertIsNotEnabled() } + step("Assert 'Add funds' button is not enabled") { + onMainScreen { addFundsButton.assertIsNotEnabled() } } step("Assert 'Swap' button is not enabled") { onMainScreen { swapButton.assertIsNotEnabled() } diff --git a/app/src/androidTest/kotlin/com/tangem/screens/ChooseTokenPageObject.kt b/app/src/androidTest/kotlin/com/tangem/screens/ChooseTokenPageObject.kt new file mode 100644 index 0000000000..28ebe26a4a --- /dev/null +++ b/app/src/androidTest/kotlin/com/tangem/screens/ChooseTokenPageObject.kt @@ -0,0 +1,39 @@ +package com.tangem.screens + +import androidx.compose.ui.test.SemanticsNodeInteractionsProvider +import com.tangem.common.BaseTestCase +import com.tangem.core.ui.test.BaseSearchBarTestTags +import com.tangem.core.ui.test.BuyTokenScreenTestTags +import com.tangem.core.ui.test.TokenElementsTestTags +import com.tangem.core.ui.test.TopAppBarTestTags +import io.github.kakaocup.compose.node.element.ComposeScreen +import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen +import io.github.kakaocup.compose.node.element.KNode +import androidx.compose.ui.test.hasTestTag as withTestTag +import androidx.compose.ui.test.hasText as withText + +/** + * "You receive" token chooser opened from the main-screen "Add funds" button. + */ +class ChooseTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) : + ComposeScreen(semanticsProvider = semanticsProvider) { + + val topAppBarTitle: KNode = child { + hasTestTag(TopAppBarTestTags.TITLE) + useUnmergedTree = true + } + + val searchBar: KNode = child { + hasTestTag(BaseSearchBarTestTags.SEARCH_BAR) + } + + fun tokenWithTitle(tokenTitle: String): KNode = child { + hasTestTag(BuyTokenScreenTestTags.LAZY_LIST_ITEM) + hasAnyDescendant(withTestTag(TokenElementsTestTags.TOKEN_TITLE)) + hasAnyDescendant(withText(tokenTitle)) + useUnmergedTree = true + } +} + +internal fun BaseTestCase.onChooseTokenScreen(function: ChooseTokenPageObject.() -> Unit) = + onComposeScreen(composeTestRule, function) \ No newline at end of file diff --git a/app/src/androidTest/kotlin/com/tangem/screens/GetTokenBottomSheetPageObject.kt b/app/src/androidTest/kotlin/com/tangem/screens/GetTokenBottomSheetPageObject.kt new file mode 100644 index 0000000000..508f0a1676 --- /dev/null +++ b/app/src/androidTest/kotlin/com/tangem/screens/GetTokenBottomSheetPageObject.kt @@ -0,0 +1,45 @@ +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 + +/** + * "Get token" bottom sheet shown after picking a token in the Add funds flow. + * Contains quick actions (Buy / Receive / …) and the "Go to token" button. + */ +class GetTokenBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) : + ComposeScreen(semanticsProvider = semanticsProvider) { + + val title: KNode = child { + hasTestTag(BaseBottomSheetTestTags.TITLE) + } + + val closeButton: KNode = child { + hasTestTag(BaseBottomSheetTestTags.CLOSE_BUTTON) + } + + // The "Get token" sheet action rows use combinedClickable; the row's testTag lands on a + // separate zero-bounds semantics node that fails assertIsDisplayed. Matching the merged node + // by its title text yields the displayed, clickable row (performClick injects a touch at its + // center, which the row's clickable handles). + val buyButton: KNode = child { + hasText(getResourceString(R.string.common_buy)) + } + + val receiveButton: KNode = child { + hasText(getResourceString(R.string.common_receive)) + } + + val goToTokenButton: KNode = child { + hasText(getResourceString(R.string.common_go_to_token)) + } +} + +internal fun BaseTestCase.onGetTokenBottomSheet(function: GetTokenBottomSheetPageObject.() -> Unit) = + onComposeScreen(composeTestRule, function) \ No newline at end of file diff --git a/app/src/androidTest/kotlin/com/tangem/screens/MainScreenPageObject.kt b/app/src/androidTest/kotlin/com/tangem/screens/MainScreenPageObject.kt index 82defdf7f0..db62a6786a 100644 --- a/app/src/androidTest/kotlin/com/tangem/screens/MainScreenPageObject.kt +++ b/app/src/androidTest/kotlin/com/tangem/screens/MainScreenPageObject.kt @@ -52,6 +52,11 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) hasText(getResourceString(R.string.common_buy)) } + val addFundsButton: KNode = child { + hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON) + hasText(getResourceString(R.string.common_add_funds)) + } + val sendButton: KNode = child { hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON) hasText(getResourceString(R.string.common_send)) diff --git a/app/src/androidTest/kotlin/com/tangem/screens/tangempay/TangemPayAddFundsSheetPageObject.kt b/app/src/androidTest/kotlin/com/tangem/screens/tangempay/TangemPayAddFundsSheetPageObject.kt index 599c234915..ba66970bb8 100644 --- a/app/src/androidTest/kotlin/com/tangem/screens/tangempay/TangemPayAddFundsSheetPageObject.kt +++ b/app/src/androidTest/kotlin/com/tangem/screens/tangempay/TangemPayAddFundsSheetPageObject.kt @@ -12,7 +12,7 @@ class TangemPayAddFundsSheetPageObject(semanticsProvider: SemanticsNodeInteracti ComposeScreen(semanticsProvider = semanticsProvider) { val swapOption: KNode = child { - hasText(getResourceString(CoreResR.string.common_exchange)) + hasText(getResourceString(CoreResR.string.tangempay_topup_swap_title)) useUnmergedTree = true } diff --git a/app/src/androidTest/kotlin/com/tangem/tests/BuyTokenTest.kt b/app/src/androidTest/kotlin/com/tangem/tests/BuyTokenTest.kt index 3c44cb4154..becda76ceb 100644 --- a/app/src/androidTest/kotlin/com/tangem/tests/BuyTokenTest.kt +++ b/app/src/androidTest/kotlin/com/tangem/tests/BuyTokenTest.kt @@ -40,15 +40,18 @@ class BuyTokenTest : BaseTestCase() { step("Synchronize addresses") { synchronizeAddresses() } - step("Click on 'Buy' button") { - onMainScreen { buyButton.clickWithAssertion() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.clickWithAssertion() } } step("Click on token with name: '$tokenTitle'") { - onBuyTokenScreen { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() - tokenWithTitleAndFiatAmount(tokenTitle).clickWithAssertion() + tokenWithTitle(tokenTitle).clickWithAssertion() } } + step("Click on 'Buy' in 'Get token' bottom sheet") { + onGetTokenBottomSheet { buyButton.clickWithAssertion() } + } step("Assert error notification title is displayed") { onBuyTokenDetailsScreen { errorNotificationTitle.assertIsDisplayed() } } @@ -84,15 +87,18 @@ class BuyTokenTest : BaseTestCase() { step("Synchronize addresses") { synchronizeAddresses() } - step("Click on 'Buy' button") { - onMainScreen { buyButton.clickWithAssertion() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.clickWithAssertion() } } step("Click on token with name: '$tokenTitle'") { - onBuyTokenScreen { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() - tokenWithTitleAndFiatAmount(tokenTitle).clickWithAssertion() + tokenWithTitle(tokenTitle).clickWithAssertion() } } + step("Click on 'Buy' in 'Get token' bottom sheet") { + onGetTokenBottomSheet { buyButton.clickWithAssertion() } + } step("Click on 'Confirm' button in 'Dialog'") { onDialog { confirmButton.clickWithAssertion() } } @@ -155,15 +161,18 @@ class BuyTokenTest : BaseTestCase() { step("Synchronize addresses") { synchronizeAddresses() } - step("Click on 'Buy' button") { - onMainScreen { buyButton.clickWithAssertion() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.clickWithAssertion() } } step("Click on token with name: '$tokenTitle'") { - onBuyTokenScreen { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() - tokenWithTitleAndFiatAmount(tokenTitle).clickWithAssertion() + tokenWithTitle(tokenTitle).clickWithAssertion() } } + step("Click on 'Buy' in 'Get token' bottom sheet") { + onGetTokenBottomSheet { buyButton.clickWithAssertion() } + } step("Click on 'Confirm' button in 'Dialog'") { onDialog { confirmButton.clickWithAssertion() } } @@ -238,15 +247,18 @@ class BuyTokenTest : BaseTestCase() { step("Synchronize addresses") { synchronizeAddresses() } - step("Click on 'Buy' button") { - onMainScreen { buyButton.clickWithAssertion() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.clickWithAssertion() } } step("Click on token with name: '$tokenTitle'") { - onBuyTokenScreen { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() - tokenWithTitleAndFiatAmount(tokenTitle).clickWithAssertion() + tokenWithTitle(tokenTitle).clickWithAssertion() } } + step("Click on 'Buy' in 'Get token' bottom sheet") { + onGetTokenBottomSheet { buyButton.clickWithAssertion() } + } step("Click on 'Confirm' button in 'Dialog'") { onDialog { confirmButton.clickWithAssertion() } } @@ -320,15 +332,18 @@ class BuyTokenTest : BaseTestCase() { step("Synchronize addresses") { synchronizeAddresses() } - step("Click on 'Buy' button") { - onMainScreen { buyButton.clickWithAssertion() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.clickWithAssertion() } } step("Click on token with name: '$tokenTitle'") { - onBuyTokenScreen { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() - tokenWithTitleAndFiatAmount(tokenTitle).clickWithAssertion() + tokenWithTitle(tokenTitle).clickWithAssertion() } } + step("Click on 'Buy' in 'Get token' bottom sheet") { + onGetTokenBottomSheet { buyButton.clickWithAssertion() } + } step("Click on 'Confirm' button in 'Dialog'") { onDialog { confirmButton.clickWithAssertion() } } @@ -406,15 +421,18 @@ class BuyTokenTest : BaseTestCase() { step("Synchronize addresses") { synchronizeAddresses() } - step("Click on 'Buy' button") { - onMainScreen { buyButton.clickWithAssertion() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.clickWithAssertion() } } step("Click on token with name: '$tokenTitle'") { - onBuyTokenScreen { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() - tokenWithTitleAndFiatAmount(tokenTitle).clickWithAssertion() + tokenWithTitle(tokenTitle).clickWithAssertion() } } + step("Click on 'Buy' in 'Get token' bottom sheet") { + onGetTokenBottomSheet { buyButton.clickWithAssertion() } + } step("Click on 'Confirm' button in 'Dialog'") { onDialog { confirmButton.clickWithAssertion() } } diff --git a/app/src/androidTest/kotlin/com/tangem/tests/actionButtons/MainScreenActionButtonsTest.kt b/app/src/androidTest/kotlin/com/tangem/tests/actionButtons/MainScreenActionButtonsTest.kt index 1f795cadce..5e8dd103e2 100644 --- a/app/src/androidTest/kotlin/com/tangem/tests/actionButtons/MainScreenActionButtonsTest.kt +++ b/app/src/androidTest/kotlin/com/tangem/tests/actionButtons/MainScreenActionButtonsTest.kt @@ -419,17 +419,17 @@ class MainScreenActionButtonsTest : BaseTestCase() { step("Synchronize addresses") { synchronizeAddresses() } - step("Assert 'Buy' button is displayed") { - onMainScreen { buyButton.assertIsDisplayed() } + step("Assert 'Add funds' button is displayed") { + onMainScreen { addFundsButton.assertIsDisplayed() } } - step("Click on 'Buy' button") { - onMainScreen { buyButton.performClick() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.performClick() } } - step("Assert 'Buy' screen title is displayed") { - onBuyTokenScreen { topAppBarTitle.assertIsDisplayed() } + step("Assert 'Choose token' screen title is displayed") { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() } } step("Assert token with title: '$tokenTitle' is displayed") { - onBuyTokenScreen { tokenWithTitleAndFiatAmount(tokenTitle).assertIsDisplayed() } + onChooseTokenScreen { tokenWithTitle(tokenTitle).assertIsDisplayed() } } step("Press 'Back' button") { device.uiDevice.pressBack() @@ -478,17 +478,18 @@ class MainScreenActionButtonsTest : BaseTestCase() { step("Open 'Main Screen'") { openMainScreen() } - step("Assert 'Buy' button is displayed") { - onMainScreen { buyButton.assertIsDisplayed() } + step("Assert 'Add funds' button is displayed") { + onMainScreen { addFundsButton.assertIsDisplayed() } } - step("Click on 'Buy' button") { - onMainScreen { buyButton.performClick() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.performClick() } } - step("Check 'Action is unavailable' dialog") { - checkActionIsUnavailableDialog() + step("Assert 'Choose token' screen opens (Add funds is always available)") { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() } } - step("Click on 'Ok' button") { - onDialog { okButton.performClick() } + step("Press 'Back' to return to main screen") { + device.uiDevice.pressBack() + waitForIdle() } step("Assert 'Swap' button is displayed") { onMainScreen { swapButton.assertIsDisplayed() } @@ -535,17 +536,18 @@ class MainScreenActionButtonsTest : BaseTestCase() { step("Open 'Main Screen'") { openMainScreen() } - step("Assert 'Buy' button is displayed") { - onMainScreen { buyButton.assertIsDisplayed() } + step("Assert 'Add funds' button is displayed") { + onMainScreen { addFundsButton.assertIsDisplayed() } } - step("Click on 'Buy' button") { - onMainScreen { buyButton.performClick() } + step("Click on 'Add funds' button") { + onMainScreen { addFundsButton.performClick() } } - step("Check 'Action is unavailable' dialog") { - checkActionIsUnavailableDialog() + step("Assert 'Choose token' screen opens (Add funds is always available)") { + onChooseTokenScreen { topAppBarTitle.assertIsDisplayed() } } - step("Click on 'Ok' button") { - onDialog { okButton.performClick() } + step("Press 'Back' to return to main screen") { + device.uiDevice.pressBack() + waitForIdle() } step("Assert 'Swap' button is displayed") { onMainScreen { swapButton.assertIsDisplayed() } diff --git a/app/src/androidTest/kotlin/com/tangem/tests/main/HideTokenTest.kt b/app/src/androidTest/kotlin/com/tangem/tests/main/HideTokenTest.kt index a576c9e327..33185d7a8b 100644 --- a/app/src/androidTest/kotlin/com/tangem/tests/main/HideTokenTest.kt +++ b/app/src/androidTest/kotlin/com/tangem/tests/main/HideTokenTest.kt @@ -51,9 +51,12 @@ class HideTokenTest : BaseTestCase() { dialogContainer.assertIsDisplayed() okButton.clickWithAssertion() } + waitForIdle() } step("Assert token: '$tokenTitle' is not displayed") { - onMainScreen { assertTokenDoesNotExist(tokenTitle) } + flakySafely { + onMainScreen { assertTokenDoesNotExist(tokenTitle) } + } } } } diff --git a/app/src/androidTest/kotlin/com/tangem/tests/main/MainScreenTest.kt b/app/src/androidTest/kotlin/com/tangem/tests/main/MainScreenTest.kt index ac99d2e42e..32dfdd1b1b 100644 --- a/app/src/androidTest/kotlin/com/tangem/tests/main/MainScreenTest.kt +++ b/app/src/androidTest/kotlin/com/tangem/tests/main/MainScreenTest.kt @@ -2,10 +2,12 @@ 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.clickWithAssertion import com.tangem.common.utils.resetWireMockScenarioState import com.tangem.common.utils.setWireMockScenarioState import com.tangem.scenarios.openMainScreen import com.tangem.scenarios.synchronizeAddresses +import com.tangem.screens.onAddAndManageBottomSheet import com.tangem.screens.onMainScreen import dagger.hilt.android.testing.HiltAndroidTest import io.qameta.allure.kotlin.AllureId @@ -81,8 +83,17 @@ 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() } + } + step("Click 'Add & Manage' button") { + onMainScreen { addAndManageButtonNode.clickWithAssertion() } + } + step("Assert 'Organize tokens' option is not displayed (nothing to organize)") { + onAddAndManageBottomSheet { organizeTokensButton.assertIsNotDisplayed() } + } + step("Assert 'Add tokens' option is displayed") { + onAddAndManageBottomSheet { addTokensButton.assertIsDisplayed() } } } }