Updated on 2026-08-14
This commit is contained in:
commit
89170505c5
24 changed files with 399 additions and 57 deletions
|
|
@ -189,10 +189,22 @@ abstract class BaseTestCase : TestCase(
|
|||
"ADD_AND_MANAGE_TOKENS_ENABLED" to true,
|
||||
"ASSETS_DISCOVERY_ENABLED" to true,
|
||||
"VISA_ONBOARDING_ENABLED" to true,
|
||||
"AND_15101_TANGEM_PAY_HOT_WALLET_ONBOARDING" to true,
|
||||
// Toggles released in 5.39+ — forced on so tests run against the actual build even when the
|
||||
// app version resolves to 1.0.0-SNAPSHOT on CI (then 1.0.0 < 5.39 would disable them).
|
||||
"STAKING_ETH_ENABLED" to true,
|
||||
"DYNAMIC_ADDRESSES_ENABLED" to true,
|
||||
"SOLANA_TX_HISTORY_ENABLED" to true,
|
||||
"SOLANA_SCALED_UI_AMOUNT_ENABLED" to true,
|
||||
"SWAP_AB_ENABLED" to true,
|
||||
"AND_15310_ADD_FUNDS_STAGE1" to true,
|
||||
"APP_REDESIGN_ENABLED" to true,
|
||||
"AND_15009_SWAP_PROVIDER_FILTER_ENABLED" to true,
|
||||
"AND_15101_TANGEM_PAY_HOT_WALLET_ONBOARDING" to true,
|
||||
"AND_15402_ADI_MAIN_SCREEN_DEFAULT_ENABLED" to true,
|
||||
"AND_15103_SWAP_RATE_EXPERIENCE_ENABLED" to true,
|
||||
"AND_15122_SWAP_PREDEFINED_BUTTONS_ENABLED" to true,
|
||||
"TWI_1512_HIDE_STORIES_FOR_REFERRAL_ENABLED" to true,
|
||||
// Toggles released in 5.40
|
||||
"APP_REDESIGN_ENABLED" to true,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package com.tangem.scenarios
|
|||
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.waitUntilAtLeastOneExists
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ class MainScreenPageObject(private val semanticsProvider: SemanticsNodeInteracti
|
|||
|
||||
fun assertTokensCount(expectedCount: Int) {
|
||||
semanticsProvider
|
||||
.onAllNodes(withTestTag(TokenElementsTestTags.TOKEN_PRICE))
|
||||
.onAllNodes(withTestTag(MainScreenTestTags.TOKEN_LIST_ITEM), useUnmergedTree = true)
|
||||
.assertCountEquals(expectedCount)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.semantics.SemanticsProperties
|
||||
import androidx.compose.ui.test.SemanticsMatcher
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.BaseActionButtonsBlockTestTags
|
||||
|
|
@ -65,7 +67,8 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
|
|||
}
|
||||
|
||||
val fiatBalance: KNode = child {
|
||||
hasTestTag(TokenDetailsScreenTestTags.BALANCE_FIAT)
|
||||
hasAnyAncestor(withTestTag(TokenDetailsScreenTestTags.BALANCE_FIAT))
|
||||
addSemanticsMatcher(SemanticsMatcher.keyIsDefined(SemanticsProperties.Text))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ 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.BaseButtonTestTags
|
||||
import com.tangem.core.ui.test.WarningBottomSheetTestTags
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
|
||||
|
|
@ -31,27 +30,23 @@ class WarningBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsP
|
|||
}
|
||||
|
||||
val okGotItButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasTestTag(WarningBottomSheetTestTags.BUTTON_SECONDARY)
|
||||
hasText(getResourceString(R.string.warning_button_ok))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val gotItButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasTestTag(WarningBottomSheetTestTags.BUTTON_PRIMARY)
|
||||
hasText(getResourceString(R.string.common_got_it))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val cancelButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasTestTag(WarningBottomSheetTestTags.BUTTON_PRIMARY)
|
||||
hasText(getResourceString(R.string.common_cancel))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val connectAnywayButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasTestTag(WarningBottomSheetTestTags.BUTTON_SECONDARY)
|
||||
hasText(getResourceString(R.string.wc_alert_connect_anyway))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -383,14 +383,14 @@ class MainScreenActionButtonsTest : BaseTestCase() {
|
|||
step("Open 'Main Screen' on '$cardName' card") {
|
||||
openMainScreen(mockContent = cardType, isTwinsCard = true)
|
||||
}
|
||||
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("Click on token: '$tokenTitle'") {
|
||||
onBuyTokenScreen { tokenWithTitleAndFiatAmount(tokenTitle).performClick() }
|
||||
step("Click on 'Buy' button in bottom sheet") {
|
||||
onAddFundsBottomSheet { buyButton.clickWithAssertion() }
|
||||
}
|
||||
step("Click on 'Confirm' button in 'Dialog'") {
|
||||
waitForIdle()
|
||||
|
|
|
|||
|
|
@ -88,14 +88,12 @@ class TotalBalanceUpdateTest : BaseTestCase() {
|
|||
}
|
||||
step("Click on 'Add' button in 'Add token' bottom sheet") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
onAddTokenBottomSheet {
|
||||
addButton.performClick()
|
||||
}
|
||||
onAddTokenBottomSheet { laterButton.assertIsDisplayed() }
|
||||
onAddTokenBottomSheet { addButton.performClick() }
|
||||
}
|
||||
}
|
||||
step("Click on 'Later' button") {
|
||||
onAddTokenBottomSheet { laterButton.performClick() }
|
||||
step("Press 'Back' button") {
|
||||
waitForIdle()
|
||||
device.uiDevice.pressBack()
|
||||
}
|
||||
step("Press 'Back' button") {
|
||||
waitForIdle()
|
||||
|
|
@ -201,8 +199,11 @@ class TotalBalanceUpdateTest : BaseTestCase() {
|
|||
step("Assert 'Token details screen' open") {
|
||||
onTokenDetailsScreen { screenContainer.assertIsDisplayed() }
|
||||
}
|
||||
step("Click 'More' button") {
|
||||
onTokenDetailsTopBar { backButton.clickWithAssertion() }
|
||||
step("Click on 'Back' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT) {
|
||||
onTokenDetailsTopBar { backButton.clickWithAssertion() }
|
||||
onMainScreen { screenContainer.assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Assert $TOTAL_BALANCE is displayed in total balance") {
|
||||
onMainScreen { totalBalanceText.assertTextContains(TOTAL_BALANCE) }
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class AssetsDiscoveryTest : BaseTestCase() {
|
|||
val tetherTitle = "Tether"
|
||||
val ethereumNetworkTitle = "ETHEREUM"
|
||||
val accountName = getResourceString(CoreUiR.string.account_main_account_title)
|
||||
val expectedTokensCount = 4
|
||||
val expectedTokensCount = 2
|
||||
|
||||
setupHooks(
|
||||
additionalBeforeAppLaunchSection = {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ 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.SwipeDirection
|
||||
import com.tangem.common.extensions.swipeVertical
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.extensions.swipeVertical
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.scenarios.openMainScreen
|
||||
|
|
@ -86,10 +86,10 @@ class MainScreenTest : BaseTestCase() {
|
|||
openMainScreen()
|
||||
}
|
||||
step("Assert 'Add & Manage' button is displayed") {
|
||||
onMainScreen { addAndManageButtonNode.assertIsDisplayed() }
|
||||
onMainScreen { addAndManageButton().assertIsDisplayed() }
|
||||
}
|
||||
step("Click 'Add & Manage' button") {
|
||||
onMainScreen { addAndManageButtonNode.clickWithAssertion() }
|
||||
onMainScreen { addAndManageButton().clickWithAssertion() }
|
||||
}
|
||||
step("Assert 'Organize tokens' option is not displayed (nothing to organize)") {
|
||||
onAddAndManageBottomSheet { organizeTokensButton.assertIsNotDisplayed() }
|
||||
|
|
|
|||
|
|
@ -231,7 +231,9 @@ class GaslessSendViaSwapTest : BaseTestCase() {
|
|||
onSendConfirmScreen { secondaryAmount.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert the network fee is paid in '$currencySymbol'") {
|
||||
onSendConfirmScreen { feeBlockCurrency(currencySymbol).assertIsDisplayed() }
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
onSendConfirmScreen { feeBlockCurrency(currencySymbol).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
step("Sign, send and open the 'Transaction sent' screen") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ import com.tangem.common.BaseTestCase
|
|||
import com.tangem.common.constants.TestConstants.DOGECOIN_RECIPIENT_ADDRESS
|
||||
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.resetWireMockScenarioState
|
||||
import com.tangem.scenarios.checkSendWarning
|
||||
import com.tangem.scenarios.openSendConfirmScreenViaNextButton
|
||||
import com.tangem.scenarios.openSendScreen
|
||||
import com.tangem.screens.onSendAddressScreen
|
||||
import com.tangem.screens.onSendScreen
|
||||
|
|
@ -20,8 +22,8 @@ import org.junit.Test
|
|||
@HiltAndroidTest
|
||||
class DogecoinWarningsTest : BaseTestCase() {
|
||||
private val tokenName = "Dogecoin"
|
||||
private val amountToLeaveLessThanDust = "5.78654978"
|
||||
private val amountToLeaveMoreThanDust = "5.7"
|
||||
private val amountToLeaveLessThanDust = "5.7045"
|
||||
private val amountToLeaveMoreThanDust = "5.6"
|
||||
private val amountGreaterThanDust = "0.02"
|
||||
private val amountLessThanDust = "0.005"
|
||||
private val dustAmount = "DOGE 0.01"
|
||||
|
|
@ -56,8 +58,10 @@ class DogecoinWarningsTest : BaseTestCase() {
|
|||
step("Type address in input text field") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(DOGECOIN_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen { nextButton.clickWithAssertion() }
|
||||
step("Open 'Send confirm' screen via 'Next' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
openSendConfirmScreenViaNextButton()
|
||||
}
|
||||
}
|
||||
step("Assert 'Invalid amount warning' is displayed") {
|
||||
checkSendWarning(
|
||||
|
|
@ -93,8 +97,10 @@ class DogecoinWarningsTest : BaseTestCase() {
|
|||
step("Type address in input text field") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(DOGECOIN_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen { nextButton.clickWithAssertion() }
|
||||
step("Open 'Send confirm' screen via 'Next' button") {
|
||||
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||
openSendConfirmScreenViaNextButton()
|
||||
}
|
||||
}
|
||||
step("Assert 'Invalid amount warning' is not displayed") {
|
||||
checkSendWarning(
|
||||
|
|
|
|||
|
|
@ -177,12 +177,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
val splashScreen = installSplashScreen()
|
||||
TangemLogger.i("Splash screen installed")
|
||||
|
||||
enableEdgeToEdge(
|
||||
navigationBarStyle = SystemBarStyle.auto(
|
||||
Color.Transparent.toArgb(),
|
||||
Color.Transparent.toArgb(),
|
||||
),
|
||||
)
|
||||
applyEdgeToEdge()
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
|
@ -200,7 +195,10 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
}
|
||||
|
||||
splashScreen.setKeepOnScreenCondition { viewModel.isSplashScreenShown }
|
||||
splashScreen.setOnExitAnimationListener { provider -> provider.remove() }
|
||||
splashScreen.setOnExitAnimationListener { provider ->
|
||||
provider.remove()
|
||||
applyEdgeToEdge()
|
||||
}
|
||||
|
||||
installActivityDependencies()
|
||||
observeAppThemeModeUpdates()
|
||||
|
|
@ -224,6 +222,15 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
}
|
||||
}
|
||||
|
||||
private fun applyEdgeToEdge() {
|
||||
enableEdgeToEdge(
|
||||
navigationBarStyle = SystemBarStyle.auto(
|
||||
Color.Transparent.toArgb(),
|
||||
Color.Transparent.toArgb(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun setRootContent() {
|
||||
// for now activity is singleTop and after going to ChromeCustomTab it calls onCreate but onDestroy
|
||||
// doesn't calls. It lead to issue that decompose nav stack is not saved in bundle and to restore it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue