diff --git a/app/src/androidTest/kotlin/com/tangem/screens/SendPageObject.kt b/app/src/androidTest/kotlin/com/tangem/screens/SendPageObject.kt index 1e1f1da9d2..6cc240110b 100644 --- a/app/src/androidTest/kotlin/com/tangem/screens/SendPageObject.kt +++ b/app/src/androidTest/kotlin/com/tangem/screens/SendPageObject.kt @@ -10,6 +10,7 @@ import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onCompose import io.github.kakaocup.compose.node.element.KNode import io.github.kakaocup.kakao.common.utilities.getResourceString import com.tangem.features.send.v2.impl.R as SendR +import androidx.compose.ui.test.hasText as withText class SendPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) : ComposeScreen(semanticsProvider = semanticsProvider) { @@ -38,6 +39,11 @@ class SendPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) : useUnmergedTree = true } + val amountErrorText: KNode = child { + hasTestTag(SendScreenTestTags.AMOUNT_ERROR_TEXT) + useUnmergedTree = true + } + val equivalentInputAmount: KNode = child { hasTestTag(SendScreenTestTags.EQUIVALENT_INPUT_AMOUNT) useUnmergedTree = true @@ -69,8 +75,8 @@ class SendPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) : } val nextButton: KNode = child { - hasTestTag(BaseButtonTestTags.TEXT) - hasText(getResourceString(SendR.string.common_next)) + hasTestTag(BaseButtonTestTags.BUTTON) + hasAnyDescendant(withText(getResourceString(SendR.string.common_next))) useUnmergedTree = true } diff --git a/app/src/androidTest/kotlin/com/tangem/tests/send/amountScreen/SendAmountScreenTest.kt b/app/src/androidTest/kotlin/com/tangem/tests/send/amountScreen/SendAmountScreenTest.kt new file mode 100644 index 0000000000..dd6f386748 --- /dev/null +++ b/app/src/androidTest/kotlin/com/tangem/tests/send/amountScreen/SendAmountScreenTest.kt @@ -0,0 +1,145 @@ +package com.tangem.tests.send.amountScreen + +import android.view.KeyEvent +import com.tangem.common.BaseTestCase +import com.tangem.common.utils.setClipboardText +import com.tangem.scenarios.* +import com.tangem.screens.* +import com.tangem.wallet.R +import dagger.hilt.android.testing.HiltAndroidTest +import io.github.kakaocup.kakao.common.utilities.getResourceString +import io.qameta.allure.kotlin.AllureId +import io.qameta.allure.kotlin.junit4.DisplayName +import org.junit.Test + +@HiltAndroidTest +class SendAmountScreenTest : BaseTestCase() { + + @AllureId("4761") + @DisplayName("Send (amount screen): validate different amounts") + @Test + fun validateDifferentAmountsTest() { + val tokenName = "Ethereum" + val manualSendAmount = "1" + val clipboardSendAmount = "0.5" + val invalidAmount = "2" + val errorText = getResourceString(R.string.send_validation_amount_exceeds_balance) + val context = device.context + + setupHooks().run { + step("Open 'Send' screen") { + openSendScreen(tokenName) + } + step("Type '$manualSendAmount' in input text field") { + onSendScreen { + amountInputTextField.performClick() + amountInputTextField.performTextReplacement(manualSendAmount) + } + } + step("Assert send amount = '$manualSendAmount'") { + onSendScreen { amountInputTextField.assertTextContains(manualSendAmount, substring = true) } + } + step("Assert 'Next' button is enabled") { + onSendScreen { nextButton.assertIsEnabled() } + } + step("Press system 'Delete' button") { + waitForIdle() + device.uiDevice.pressDelete() + } + step("Set clipboard text") { + setClipboardText(context, clipboardSendAmount) + } + step("Click on input text field") { + onSendScreen { amountInputTextField.performClick() } + } + step("Paste from clipboard") { + device.uiDevice.pressKeyCode(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON) + } + step("Assert send amount = '$clipboardSendAmount'") { + onSendScreen { amountInputTextField.assertTextContains(clipboardSendAmount, substring = true) } + } + step("Assert 'Next' button is enabled") { + onSendScreen { nextButton.assertIsEnabled() } + } + step("Press system 'Delete' button") { + waitForIdle() + device.uiDevice.pressDelete() + } + step("Type '$invalidAmount' in input text field") { + onSendScreen { + amountInputTextField.performClick() + amountInputTextField.performTextReplacement(invalidAmount) + } + } + step("Assert send amount = '$invalidAmount'") { + onSendScreen { amountInputTextField.assertTextContains(invalidAmount, substring = true) } + } + step("Assert amount error contains text '$errorText'") { + onSendScreen { amountErrorText.assertTextContains(errorText) } + } + step("Assert 'Next' button is disabled") { + onSendScreen { nextButton.assertIsNotEnabled() } + } + step("Click on 'Max' button") { + onSendScreen { maxButton.performClick() } + } + step("Assert send amount = '$manualSendAmount'") { + onSendScreen { amountInputTextField.assertTextContains(manualSendAmount, substring = true) } + } + step("Assert 'Next' button is enabled") { + onSendScreen { nextButton.assertIsEnabled() } + } + step("Click on 'Close' button") { + onSendScreen { closeButton.performClick() } + } + step("Assert 'Token Details' screen is displayed") { + onTokenDetailsScreen { screenContainer.assertIsDisplayed() } + } + } + } + + @AllureId("4762") + @DisplayName("Send (amount screen): switch equivalent") + @Test + fun switchEquivalentTest() { + val tokenName = "Ethereum" + val tokenAmount = "1" + val fiatAmount = "$2,535.63" + + setupHooks().run { + step("Open 'Send' screen") { + openSendScreen(tokenName) + } + step("Type '$tokenAmount' in input text field") { + onSendScreen { + amountInputTextField.performClick() + amountInputTextField.performTextReplacement(tokenAmount) + } + } + step("Assert send amount = '$tokenAmount'") { + onSendScreen { amountInputTextField.assertTextContains(tokenAmount, substring = true) } + } + step("Assert equivalent amount = '$fiatAmount'") { + onSendScreen { equivalentInputAmount.assertTextContains(fiatAmount, substring = true) } + } + step("Click on 'Exchange' button") { + onSendScreen { exchangeIcon.performClick() } + } + step("Assert send amount = '$fiatAmount'") { + onSendScreen { amountInputTextField.assertTextContains(fiatAmount, substring = true) } + } + step("Assert equivalent amount = '$tokenAmount'") { + onSendScreen { equivalentInputAmount.assertTextContains(tokenAmount, substring = true) } + } + step("Click on 'Exchange' button") { + onSendScreen { exchangeIcon.performClick() } + } + step("Assert send amount = '$tokenAmount'") { + onSendScreen { amountInputTextField.assertTextContains(tokenAmount, substring = true) } + } + step("Assert equivalent amount = '$fiatAmount'") { + onSendScreen { equivalentInputAmount.assertTextContains(fiatAmount, substring = true) } + } + } + } +} \ No newline at end of file diff --git a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldV2.kt b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldV2.kt index 0932e007ab..dbc955ab1e 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldV2.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/amountScreen/ui/AmountFieldV2.kt @@ -271,6 +271,7 @@ private fun AmountFieldError( style = TangemTheme.typography.caption2, color = color, textAlign = TextAlign.Center, + modifier = Modifier.testTag(SendScreenTestTags.AMOUNT_ERROR_TEXT), ) } } diff --git a/core/ui/src/main/java/com/tangem/core/ui/test/SendScreenTestTags.kt b/core/ui/src/main/java/com/tangem/core/ui/test/SendScreenTestTags.kt index 49103a185d..928a782a86 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/test/SendScreenTestTags.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/test/SendScreenTestTags.kt @@ -5,6 +5,7 @@ object SendScreenTestTags { const val AMOUNT_CONTAINER_TITLE = "SEND_SCREEN_AMOUNT_CONTAINER_TITLE" const val INPUT_TEXT_FIELD = "SEND_SCREEN_INPUT_TEXT_FIELD" + const val AMOUNT_ERROR_TEXT = "SEND_SCREEN_AMOUNT_ERROR_TEXT" const val EQUIVALENT_INPUT_AMOUNT = "SEND_SCREEN_EQUIVALENT_INPUT_AMOUNT" const val EXCHANGE_ICON = "SEND_SCREEN_EXCHANGE_ICON" const val TOKEN_NAME = "SEND_SCREEN_TOKEN_NAME"