Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-22 17:23:08 +04:00
commit bac330628f
29 changed files with 756 additions and 150 deletions

View file

@ -4,9 +4,10 @@ import android.os.SystemClock
import androidx.compose.ui.test.ComposeTimeoutException
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.ComposeTestRule
import io.github.kakaocup.compose.node.core.BaseNode
import io.github.kakaocup.compose.node.element.KNode
fun KNode.clickWithAssertion() {
fun BaseNode<*>.clickWithAssertion() {
assertIsDisplayed()
performClick()
}

View file

@ -1,16 +1,21 @@
package com.tangem.screens
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.common.utils.LazyListItemNode
import com.tangem.core.ui.R
import com.tangem.core.ui.test.BaseBottomSheetTestTags
import com.tangem.core.ui.test.BuyTokenScreenTestTags
import com.tangem.core.ui.test.MarketsTestTags
import com.tangem.core.ui.test.TokenActionsTestTags
import com.tangem.core.ui.test.TokenElementsTestTags
import com.tangem.core.ui.utils.LazyListItemPositionSemantics
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.compose.node.element.lazylist.KLazyListNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
import androidx.compose.ui.test.hasTestTag as withTestTag
import androidx.compose.ui.test.hasText as withText
@ -53,11 +58,22 @@ class AddFundsBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractions
useUnmergedTree = true
}
fun trendingTokenWithTitle(tokenTitle: String): KNode = child {
hasTestTag(MarketsTestTags.TOKENS_LIST_ITEM)
hasAnyDescendant(withText(tokenTitle))
useUnmergedTree = true
}
private val trendingTokensList = KLazyListNode(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(BuyTokenScreenTestTags.LAZY_LIST) },
itemTypeBuilder = { itemType(::LazyListItemNode) },
positionMatcher = { position ->
SemanticsMatcher.expectValue(LazyListItemPositionSemantics, position)
},
)
@OptIn(ExperimentalTestApi::class)
fun trendingTokenWithTitle(tokenTitle: String): LazyListItemNode =
trendingTokensList.childWith<LazyListItemNode> {
hasTestTag(MarketsTestTags.TOKENS_LIST_ITEM)
hasText(tokenTitle)
useUnmergedTree = true
}
}
internal fun BaseTestCase.onAddFundsBottomSheet(function: AddFundsBottomSheetPageObject.() -> Unit) =

View file

@ -54,13 +54,22 @@ class AppCurrencyTest : BaseTestCase() {
step("Click on currency '$targetCurrency'") {
onAppCurrencySelectorScreen { currencyItem(targetCurrency).performClick() }
}
step("Press 'Back' button to return to 'Details' screen") {
step("Assert 'App settings' screen is open after currency selection") {
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
onAppSettingsScreen { currencyButton.assertIsDisplayed() }
}
}
step("Return to 'Details' screen") {
waitForIdle()
device.uiDevice.pressBack()
}
step("Press 'Back' button to return to 'Main' screen") {
waitForIdle()
device.uiDevice.pressBack()
step("Return to 'Main' screen via 'Back' button") {
onDetailsScreen { topAppBarBackButton.clickWithAssertion() }
}
step("Assert 'Main' screen is opened") {
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
onMainScreen { screenContainer.assertIsDisplayed() }
}
}
step("Assert total balance contains '$targetSymbol' on 'Main' screen") {
// Balance re-loads in the new currency async after the switch — wait for the € equivalent.

View file

@ -501,7 +501,9 @@ class MainScreenActionButtonsTest : BaseTestCase() {
onMainScreen { swapButton.performClick() }
}
step("Check 'Action is unavailable' dialog") {
checkActionIsUnavailableDialog()
flakySafely(WAIT_UNTIL_TIMEOUT) {
checkActionIsUnavailableDialog()
}
}
step("Click on 'Ok' button") {
onDialog { okButton.performClick() }

View file

@ -3,11 +3,13 @@ package com.tangem.tests.send.warnings
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.constants.TestConstants.XLM_ACTIVATED_RECIPIENT_ADDRESS
import com.tangem.common.constants.TestConstants.XLM_NON_ACTIVATED_RECIPIENT_ADDRESS
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.onSendConfirmScreen
@ -110,8 +112,10 @@ class StellarWarningsTest : BaseTestCase() {
step("Type non activated address in input text field") {
onSendAddressScreen { addressTextField.performTextReplacement(XLM_NON_ACTIVATED_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 reserve amount warning' is not displayed") {
checkSendWarning(