Updated on 2026-08-14
This commit is contained in:
parent
d9d8e9b500
commit
61145f7cc5
5 changed files with 326 additions and 9 deletions
|
|
@ -27,3 +27,10 @@ fun KNode.isDisplayedSafely(): Boolean {
|
|||
}
|
||||
}
|
||||
|
||||
fun KNode.assertVisibility(shouldBeDisplayed: Boolean) {
|
||||
if (shouldBeDisplayed) {
|
||||
assertIsDisplayed()
|
||||
} else {
|
||||
assertIsNotDisplayed()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.scenarios
|
||||
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.extensions.assertVisibility
|
||||
import com.tangem.screens.onSendConfirmScreen
|
||||
import io.github.kakaocup.compose.node.element.KNode
|
||||
import io.qameta.allure.kotlin.Allure.step
|
||||
|
||||
fun BaseTestCase.checkSendWarning(
|
||||
|
|
@ -45,12 +45,4 @@ fun BaseTestCase.checkSendWarning(
|
|||
sendButton.assertIsEnabled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun KNode.assertVisibility(shouldBeDisplayed: Boolean) {
|
||||
if (shouldBeDisplayed) {
|
||||
assertIsDisplayed()
|
||||
} else {
|
||||
assertIsNotDisplayed()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.scenarios
|
|||
|
||||
import androidx.compose.ui.test.click
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.extensions.assertVisibility
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.extensions.isDisplayedSafely
|
||||
import com.tangem.screens.*
|
||||
|
|
@ -258,6 +259,44 @@ fun BaseTestCase.chackUnableToCoverFeeNotification(networkName: String, currency
|
|||
}
|
||||
}
|
||||
|
||||
fun BaseTestCase.checkSwapWarning(
|
||||
title: String,
|
||||
message: String,
|
||||
isDisplayed: Boolean = true,
|
||||
swapButtonIsDisabled: Boolean = isDisplayed,
|
||||
) {
|
||||
val assertDisplay = if (isDisplayed) "displayed" else "not displayed"
|
||||
|
||||
step("Assert warning title is $assertDisplay") {
|
||||
onSwapTokenScreen {
|
||||
warningTitle(title).assertVisibility(isDisplayed)
|
||||
}
|
||||
}
|
||||
step("Assert warning icon is $assertDisplay") {
|
||||
onSwapTokenScreen {
|
||||
warningIcon(message).assertVisibility(isDisplayed)
|
||||
}
|
||||
}
|
||||
step("Assert warning message is $assertDisplay") {
|
||||
onSwapTokenScreen {
|
||||
warningMessage(message).assertVisibility(isDisplayed)
|
||||
}
|
||||
}
|
||||
|
||||
if (swapButtonIsDisabled)
|
||||
step("Assert 'Swap' button is disabled") {
|
||||
onSwapTokenScreen {
|
||||
swapButton.assertIsNotEnabled()
|
||||
}
|
||||
}
|
||||
else
|
||||
step("Assert 'Swap' button is enabled") {
|
||||
onSwapTokenScreen {
|
||||
swapButton.assertIsEnabled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SwapEntryPoint {
|
||||
object MainScreen : SwapEntryPoint()
|
||||
object TokenDetails : SwapEntryPoint()
|
||||
|
|
|
|||
|
|
@ -113,6 +113,24 @@ class SwapTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun warningTitle(title: String): KNode = child {
|
||||
hasTestTag(NotificationTestTags.TITLE)
|
||||
hasText(title)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun warningMessage(message: String): KNode = child {
|
||||
hasTestTag(NotificationTestTags.MESSAGE)
|
||||
hasText(message)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun warningIcon(message: String): KNode = child {
|
||||
hasTestTag(NotificationTestTags.ICON)
|
||||
hasAnySibling(withText(message))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val refreshButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.BUTTON)
|
||||
hasText(getResourceString(R.string.warning_button_refresh))
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.datasource.api.common.config.ApiConfig
|
|||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
import com.tangem.scenarios.SwapEntryPoint
|
||||
import com.tangem.scenarios.chackUnableToCoverFeeNotification
|
||||
import com.tangem.scenarios.checkSwapWarning
|
||||
import com.tangem.scenarios.openMainScreen
|
||||
import com.tangem.scenarios.openSwapScreen
|
||||
import com.tangem.scenarios.synchronizeAddresses
|
||||
|
|
@ -316,4 +317,264 @@ class SwapTokenScreenWarningsTest : BaseTestCase() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("2831")
|
||||
@DisplayName("Swap: warning is not displayed, if remaining balance is equal to 0")
|
||||
@Test
|
||||
fun solanaRemainingBalanceEqualToZeroWarningTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val inputAmount = "0.00168933"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
val notificationTitle = getResourceString(R.string.send_notification_invalid_amount_title)
|
||||
val notificationMessage = getResourceString(
|
||||
R.string.send_notification_invalid_amount_rent_fee,
|
||||
rentAmount
|
||||
)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$tokensScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$QUOTES_API_SCENARIO' to state: $tokensScenarioState") {
|
||||
setWireMockScenarioState(scenarioName = QUOTES_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Click on token with name: '$tokenTitle'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).clickWithAssertion() }
|
||||
}
|
||||
step("Assert title: '$tokenTitle' is displayed") {
|
||||
onTokenDetailsScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails)
|
||||
}
|
||||
step("Assert 'You swap' block is displayed") {
|
||||
onSwapTokenScreen { youSwapBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Input swap amount = '$inputAmount'") {
|
||||
waitForIdle()
|
||||
onSwapTokenScreen {
|
||||
textInput.clickWithAssertion()
|
||||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is not displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
title = notificationTitle,
|
||||
message = notificationMessage,
|
||||
isDisplayed = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("2832")
|
||||
@DisplayName("Swap: warning is not displayed, if remaining balance is equal to rent amount")
|
||||
@Test
|
||||
fun solanaRemainingBalanceEqualToRentAmountTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val inputAmount = "0.001689338"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
val notificationTitle = getResourceString(R.string.send_notification_invalid_amount_title)
|
||||
val notificationMessage = getResourceString(
|
||||
R.string.send_notification_invalid_amount_rent_fee,
|
||||
rentAmount
|
||||
)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$tokensScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$QUOTES_API_SCENARIO' to state: $tokensScenarioState") {
|
||||
setWireMockScenarioState(scenarioName = QUOTES_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Click on token with name: '$tokenTitle'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).clickWithAssertion() }
|
||||
}
|
||||
step("Assert title: '$tokenTitle' is displayed") {
|
||||
onTokenDetailsScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails)
|
||||
}
|
||||
step("Assert 'You swap' block is displayed") {
|
||||
onSwapTokenScreen { youSwapBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Input swap amount = '$inputAmount'") {
|
||||
waitForIdle()
|
||||
onSwapTokenScreen {
|
||||
textInput.clickWithAssertion()
|
||||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is not displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
title = notificationTitle,
|
||||
message = notificationMessage,
|
||||
isDisplayed = false
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("2833")
|
||||
@DisplayName("Swap: warning is not displayed, if remaining balance more than rent amount")
|
||||
@Test
|
||||
fun solanaRemainingBalanceMoreThanRentAmountTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val inputAmount = "0.0000941"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
val notificationTitle = getResourceString(R.string.send_notification_invalid_amount_title)
|
||||
val notificationMessage = getResourceString(
|
||||
R.string.send_notification_invalid_amount_rent_fee,
|
||||
rentAmount
|
||||
)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$tokensScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$QUOTES_API_SCENARIO' to state: $tokensScenarioState") {
|
||||
setWireMockScenarioState(scenarioName = QUOTES_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Click on token with name: '$tokenTitle'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).clickWithAssertion() }
|
||||
}
|
||||
step("Assert title: '$tokenTitle' is displayed") {
|
||||
onTokenDetailsScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails)
|
||||
}
|
||||
step("Assert 'You swap' block is displayed") {
|
||||
onSwapTokenScreen { youSwapBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Input swap amount = '$inputAmount'") {
|
||||
waitForIdle()
|
||||
onSwapTokenScreen {
|
||||
textInput.clickWithAssertion()
|
||||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is not displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
title = notificationTitle,
|
||||
message = notificationMessage,
|
||||
isDisplayed = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("2830")
|
||||
@DisplayName("Swap: warning is displayed, if remaining balance less than rent amount")
|
||||
@Test
|
||||
fun solanaRemainingBalanceLessThanRentAmountTest() {
|
||||
val tokenTitle = "Solana"
|
||||
val inputAmount = "0.0016941"
|
||||
val tokensScenarioState = "SolanaUSDC"
|
||||
val rentAmount = "SOL 0.00089088"
|
||||
val notificationTitle = getResourceString(R.string.send_notification_invalid_amount_title)
|
||||
val notificationMessage = getResourceString(
|
||||
R.string.send_notification_invalid_amount_rent_fee,
|
||||
rentAmount
|
||||
)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
|
||||
step("Set WireMock scenario: '$USER_TOKENS_API_SCENARIO' to state: '$tokensScenarioState'") {
|
||||
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$QUOTES_API_SCENARIO' to state: $tokensScenarioState") {
|
||||
setWireMockScenarioState(scenarioName = QUOTES_API_SCENARIO, state = tokensScenarioState)
|
||||
}
|
||||
|
||||
step("Open 'Main Screen'") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Click on token with name: '$tokenTitle'") {
|
||||
onMainScreen { tokenWithTitleAndAddress(tokenTitle).clickWithAssertion() }
|
||||
}
|
||||
step("Assert title: '$tokenTitle' is displayed") {
|
||||
onTokenDetailsScreen { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Open 'Swap' screen") {
|
||||
openSwapScreen(from = SwapEntryPoint.TokenDetails)
|
||||
}
|
||||
step("Assert 'You swap' block is displayed") {
|
||||
onSwapTokenScreen { youSwapBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Input swap amount = '$inputAmount'") {
|
||||
waitForIdle()
|
||||
onSwapTokenScreen {
|
||||
textInput.clickWithAssertion()
|
||||
textInput.performTextReplacement(inputAmount)
|
||||
}
|
||||
}
|
||||
step("Assert 'Invalid amount' warning is displayed") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
checkSwapWarning(
|
||||
title = notificationTitle,
|
||||
message = notificationMessage
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue