157 lines
No EOL
6.2 KiB
Kotlin
157 lines
No EOL
6.2 KiB
Kotlin
package com.tangem.scenarios
|
|
|
|
import com.tangem.common.BaseTestCase
|
|
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.setWireMockScenarioState
|
|
import com.tangem.screens.*
|
|
import io.qameta.allure.kotlin.Allure.step
|
|
|
|
/**
|
|
* From the recipient step: fill the address and advance to the 'Send confirm' screen.
|
|
* Uses `composeTestRule.waitUntil` because `flakySafely` is unavailable in extensions on [BaseTestCase].
|
|
*/
|
|
fun BaseTestCase.enterRecipientAndOpenSendConfirm(recipientAddress: String) {
|
|
step("Type recipient address") {
|
|
onSendAddressScreen { addressTextField.performTextReplacement(recipientAddress) }
|
|
}
|
|
step("Click on 'Next' button until 'Send confirm' screen opens") {
|
|
composeTestRule.waitUntil(timeoutMillis = WAIT_UNTIL_TIMEOUT_LONG) {
|
|
runCatching { openSendConfirmScreenViaNextButton() }.isSuccess
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Enter the send amount, then fill the recipient and open the 'Send confirm' screen. */
|
|
fun BaseTestCase.enterAmountAndOpenSendConfirm(amount: String, recipientAddress: String) {
|
|
step("Type '$amount' in input text field") {
|
|
onSendScreen {
|
|
amountInputTextField.performClick()
|
|
amountInputTextField.performTextReplacement(amount)
|
|
}
|
|
}
|
|
step("Click on 'Next' button") {
|
|
onSendScreen { nextButton.clickWithAssertion() }
|
|
}
|
|
enterRecipientAndOpenSendConfirm(recipientAddress)
|
|
}
|
|
|
|
/**
|
|
* On the 'Send confirm' screen, open the network-fee selector and switch the fee token from the
|
|
* native coin to the given (stablecoin) token — the core gasless action repeated across the suite.
|
|
*/
|
|
fun BaseTestCase.selectStablecoinAsFeeToken(
|
|
coinName: String,
|
|
tokenName: String,
|
|
// Positive flows wait until 'Apply' is enabled (fee is computed & payable). Negative flows
|
|
// (insufficient balance) must NOT wait for that — 'Apply' stays disabled — so pass false and let
|
|
// the caller assert the disabled/error state itself.
|
|
expectApplyEnabled: Boolean = true,
|
|
) {
|
|
step("Click on 'Network fee' block") {
|
|
onSendConfirmScreen {
|
|
feeSelectorBlock.assertIsDisplayed()
|
|
feeSelectorBlock.performClick()
|
|
}
|
|
}
|
|
step("Click on '$coinName' fee token to open 'Choose token'") {
|
|
composeTestRule.waitUntil(timeoutMillis = WAIT_UNTIL_TIMEOUT_LONG) {
|
|
runCatching { onSendFeeSelectorBottomSheet { feeTokenItem(coinName).performClick() } }.isSuccess
|
|
}
|
|
}
|
|
step("Select '$tokenName' as the fee-paying token") {
|
|
onSendFeeSelectorBottomSheet { feeTokenItem(tokenName).performClick() }
|
|
}
|
|
step("Wait until the '$tokenName' fee is loaded") {
|
|
composeTestRule.waitUntil(timeoutMillis = WAIT_UNTIL_TIMEOUT_LONG) {
|
|
runCatching {
|
|
onSendFeeSelectorBottomSheet {
|
|
networkFeeTitle.assertIsDisplayed()
|
|
feeTokenItem(tokenName).assertIsDisplayed()
|
|
if (expectApplyEnabled) applyButton.assertIsEnabled()
|
|
}
|
|
}.isSuccess
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Open an existing hot wallet (gasless signing needs a hot wallet, not the mock card), set the
|
|
* portfolio and quotes mocks, and reach the send amount input for the given token.
|
|
*/
|
|
fun BaseTestCase.openGaslessSendScreenWithHotWallet(
|
|
seedPhrase: String,
|
|
tokenName: String,
|
|
userTokensState: String,
|
|
quotesState: String,
|
|
) {
|
|
step("Set WireMock scenario '$USER_TOKENS_API_SCENARIO' to '$userTokensState'") {
|
|
setWireMockScenarioState(scenarioName = USER_TOKENS_API_SCENARIO, state = userTokensState)
|
|
}
|
|
step("Set WireMock scenario '$QUOTES_API_SCENARIO' to '$quotesState'") {
|
|
setWireMockScenarioState(scenarioName = QUOTES_API_SCENARIO, state = quotesState)
|
|
}
|
|
step("Open 'Main' screen with existing hot wallet") {
|
|
openMainScreenWithExistingHotWallet(seedPhrase)
|
|
}
|
|
step("Click on token with name: '$tokenName'") {
|
|
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
|
}
|
|
step("Click on 'Transfer' button") {
|
|
onTokenDetailsScreen { transferButton.clickWithAssertion() }
|
|
}
|
|
step("Click on 'Send' button in bottom sheet") {
|
|
onTransferBottomSheet { sendButton.clickWithAssertion() }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Open an existing hot wallet, select the token to send and choose the swap target token/network —
|
|
* the shared entry into the gasless send-via-swap flow. Scenario states stay in the test body.
|
|
*/
|
|
fun BaseTestCase.openSendViaSwapScreenWithHotWallet(
|
|
seedPhrase: String,
|
|
tokenName: String,
|
|
swapTokenName: String,
|
|
networkName: String,
|
|
networkType: String? = null,
|
|
) {
|
|
step("Open 'Main' screen with existing hot wallet") {
|
|
openMainScreenWithExistingHotWallet(seedPhrase)
|
|
}
|
|
step("Click on token with name: '$tokenName'") {
|
|
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
|
|
}
|
|
step("Select '$swapTokenName' as the token to receive via swap") {
|
|
selectTokenToSendViaSwap(
|
|
swapTokenName = swapTokenName,
|
|
networkName = networkName,
|
|
networkType = networkType,
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send-via-swap amount entry: type the amount, advance past the quote-gated 'Next' button (waiting
|
|
* until it becomes enabled once the swap quote loads), then fill the recipient and open the
|
|
* 'Send confirm' screen. Uses `composeTestRule.waitUntil` because `flakySafely` is unavailable in
|
|
* extensions on [BaseTestCase].
|
|
*/
|
|
fun BaseTestCase.enterSwapAmountAndOpenSendConfirm(amount: String, recipientAddress: String) {
|
|
step("Type amount '$amount' in input field") {
|
|
onSendScreen { amountInputTextField.performTextReplacement(amount) }
|
|
}
|
|
step("Click on 'Next' button") {
|
|
composeTestRule.waitUntil(timeoutMillis = WAIT_UNTIL_TIMEOUT_LONG) {
|
|
runCatching {
|
|
onSendScreen {
|
|
nextButton.assertIsEnabled()
|
|
nextButton.performClick()
|
|
}
|
|
}.isSuccess
|
|
}
|
|
}
|
|
enterRecipientAndOpenSendConfirm(recipientAddress)
|
|
} |