Updated on 2026-08-14
This commit is contained in:
parent
2a5a05fe83
commit
5618f44c8b
8 changed files with 151 additions and 4 deletions
|
|
@ -3,11 +3,17 @@ package com.tangem.screens
|
||||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||||
import com.tangem.common.BaseTestCase
|
import com.tangem.common.BaseTestCase
|
||||||
import com.tangem.core.ui.R
|
import com.tangem.core.ui.R
|
||||||
|
import com.tangem.core.ui.test.AddFundsBottomSheetTestTags
|
||||||
import com.tangem.core.ui.test.BaseBottomSheetTestTags
|
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 io.github.kakaocup.compose.node.element.ComposeScreen
|
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.ComposeScreen.Companion.onComposeScreen
|
||||||
import io.github.kakaocup.compose.node.element.KNode
|
import io.github.kakaocup.compose.node.element.KNode
|
||||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||||
|
import androidx.compose.ui.test.hasTestTag as withTestTag
|
||||||
import androidx.compose.ui.test.hasText as withText
|
import androidx.compose.ui.test.hasText as withText
|
||||||
|
|
||||||
class AddFundsBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
class AddFundsBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||||
|
|
@ -32,7 +38,25 @@ class AddFundsBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractions
|
||||||
}
|
}
|
||||||
|
|
||||||
val closeButton: KNode = child {
|
val closeButton: KNode = child {
|
||||||
hasAnyChild(withText(getResourceString(R.string.common_close)))
|
hasTestTag(AddFundsBottomSheetTestTags.CLOSE_BUTTON)
|
||||||
|
useUnmergedTree = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val buyTokenButton: KNode = child {
|
||||||
|
hasTestTag(TokenActionsTestTags.BUY_ACTION)
|
||||||
|
useUnmergedTree = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun userTokenWithTitle(tokenTitle: String): KNode = child {
|
||||||
|
hasTestTag(BuyTokenScreenTestTags.LAZY_LIST_ITEM)
|
||||||
|
hasAnyDescendant(withTestTag(TokenElementsTestTags.TOKEN_TITLE))
|
||||||
|
hasAnyDescendant(withText(tokenTitle))
|
||||||
|
useUnmergedTree = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun trendingTokenWithTitle(tokenTitle: String): KNode = child {
|
||||||
|
hasTestTag(MarketsTestTags.TOKENS_LIST_ITEM)
|
||||||
|
hasAnyDescendant(withText(tokenTitle))
|
||||||
useUnmergedTree = true
|
useUnmergedTree = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,11 @@ class AddTokenBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractions
|
||||||
hasText(getResourceString(R.string.common_add_token))
|
hasText(getResourceString(R.string.common_add_token))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val closeButton: KNode = child {
|
||||||
|
hasTestTag(BaseBottomSheetTestTags.CLOSE_BUTTON)
|
||||||
|
useUnmergedTree = true
|
||||||
|
}
|
||||||
|
|
||||||
val addButton: KNode = child {
|
val addButton: KNode = child {
|
||||||
hasTestTag(BaseButtonTestTags.TEXT)
|
hasTestTag(BaseButtonTestTags.TEXT)
|
||||||
hasText(getResourceString(R.string.common_add))
|
hasText(getResourceString(R.string.common_add))
|
||||||
|
|
|
||||||
|
|
@ -439,6 +439,14 @@ class MainScreenPageObject(private val semanticsProvider: SemanticsNodeInteracti
|
||||||
.onAllNodes(withTestTag(MainScreenTestTags.TOKEN_LIST_ITEM), useUnmergedTree = true)
|
.onAllNodes(withTestTag(MainScreenTestTags.TOKEN_LIST_ITEM), useUnmergedTree = true)
|
||||||
.assertCountEquals(expectedCount)
|
.assertCountEquals(expectedCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun assertTokenExists(tokenTitle: String) {
|
||||||
|
lazyList.child<KNode> {
|
||||||
|
hasTestTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
||||||
|
hasAnyDescendant(withText(tokenTitle))
|
||||||
|
useUnmergedTree = true
|
||||||
|
}.assertIsDisplayed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun BaseTestCase.onMainScreen(function: MainScreenPageObject.() -> Unit) =
|
internal fun BaseTestCase.onMainScreen(function: MainScreenPageObject.() -> Unit) =
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.tangem.tests.addFunds
|
||||||
|
|
||||||
|
import com.tangem.common.BaseTestCase
|
||||||
|
import com.tangem.common.extensions.assertTextContainsSafe
|
||||||
|
import com.tangem.common.extensions.clickWithAssertion
|
||||||
|
import com.tangem.scenarios.openMainScreen
|
||||||
|
import com.tangem.scenarios.synchronizeAddresses
|
||||||
|
import com.tangem.screens.onAddTokenBottomSheet
|
||||||
|
import com.tangem.screens.onAddFundsBottomSheet
|
||||||
|
import com.tangem.screens.onBuyTokenDetailsScreen
|
||||||
|
import com.tangem.screens.onMainScreen
|
||||||
|
import dagger.hilt.android.testing.HiltAndroidTest
|
||||||
|
import io.qameta.allure.kotlin.AllureId
|
||||||
|
import io.qameta.allure.kotlin.junit4.DisplayName
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
@HiltAndroidTest
|
||||||
|
class BuyTest : BaseTestCase() {
|
||||||
|
|
||||||
|
@AllureId("587")
|
||||||
|
@DisplayName("Buy. Display tokens available for purchase")
|
||||||
|
@Test
|
||||||
|
fun buyDisplayTokensAvailableForPurchaseTest() {
|
||||||
|
val token = "Bitcoin"
|
||||||
|
|
||||||
|
setupHooks().run {
|
||||||
|
step("Open 'Main' screen") {
|
||||||
|
openMainScreen()
|
||||||
|
}
|
||||||
|
step("Synchronize addresses") {
|
||||||
|
synchronizeAddresses()
|
||||||
|
}
|
||||||
|
step("Click on 'Add Funds' button") {
|
||||||
|
onMainScreen { addFundsButton.clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Click on $token in Wallet list") {
|
||||||
|
onAddFundsBottomSheet { userTokenWithTitle(token).clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Click on 'Buy' button") {
|
||||||
|
onAddFundsBottomSheet { buyTokenButton.clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Verify 'Buy $token' title is displayed") {
|
||||||
|
onBuyTokenDetailsScreen {
|
||||||
|
topBarTitle.assertTextContainsSafe("Buy $token", substring = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllureId("590")
|
||||||
|
@DisplayName("Buy. Adding trending token to the main screen")
|
||||||
|
@Test
|
||||||
|
fun buyAddingTrendingTokenToMainScreenTest() {
|
||||||
|
val token = "Solana"
|
||||||
|
|
||||||
|
setupHooks().run {
|
||||||
|
step("Open 'Main' screen") {
|
||||||
|
openMainScreen()
|
||||||
|
}
|
||||||
|
step("Synchronize addresses") {
|
||||||
|
synchronizeAddresses()
|
||||||
|
}
|
||||||
|
step("Click on 'Add Funds' button") {
|
||||||
|
onMainScreen { addFundsButton.clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Click on $token in Trending list") {
|
||||||
|
onAddFundsBottomSheet { trendingTokenWithTitle(token).clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Click on 'Add' button") {
|
||||||
|
onAddTokenBottomSheet { addButton.clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Close 'Get token' screen") {
|
||||||
|
onAddFundsBottomSheet { closeButton.clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Verify token $token exists on main screen") {
|
||||||
|
onMainScreen { assertTokenExists(token) }
|
||||||
|
}
|
||||||
|
step("Click on 'Add Funds' button") {
|
||||||
|
onMainScreen { addFundsButton.clickWithAssertion() }
|
||||||
|
}
|
||||||
|
step("Verify token $token in Wallet list") {
|
||||||
|
onAddFundsBottomSheet { userTokenWithTitle(token).assertIsDisplayed() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.tangem.core.ui.test
|
||||||
|
|
||||||
|
object AddFundsBottomSheetTestTags {
|
||||||
|
const val CLOSE_BUTTON = "ADD_FUNDS_BOTTOM_SHEET_CLOSE_BUTTON"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.tangem.core.ui.test
|
||||||
|
|
||||||
|
object TokenActionsTestTags {
|
||||||
|
const val BUY_ACTION = "TOKEN_ACTIONS_BUY_ACTION"
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
|
|
@ -26,6 +27,7 @@ import com.tangem.core.ui.ds.topbar.TangemTopBarType
|
||||||
import com.tangem.core.ui.extensions.clickableSingle
|
import com.tangem.core.ui.extensions.clickableSingle
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemeRedesign
|
import com.tangem.core.ui.res.TangemThemeRedesign
|
||||||
|
import com.tangem.core.ui.test.AddFundsBottomSheetTestTags
|
||||||
import com.tangem.features.commonfeatures.api.addfunds.AddFundsComponent
|
import com.tangem.features.commonfeatures.api.addfunds.AddFundsComponent
|
||||||
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenComponent
|
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenComponent
|
||||||
import com.tangem.features.commonfeatures.impl.R
|
import com.tangem.features.commonfeatures.impl.R
|
||||||
|
|
@ -198,7 +200,11 @@ internal class DefaultAddFundsComponent @AssistedInject constructor(
|
||||||
null
|
null
|
||||||
},
|
},
|
||||||
endContent = {
|
endContent = {
|
||||||
CircleIconButton(iconRes = R.drawable.ic_close_24, onClick = onCloseClick)
|
CircleIconButton(
|
||||||
|
iconRes = R.drawable.ic_close_24,
|
||||||
|
onClick = onCloseClick,
|
||||||
|
modifier = Modifier.testTag(AddFundsBottomSheetTestTags.CLOSE_BUTTON),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -213,12 +219,12 @@ internal class DefaultAddFundsComponent @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CircleIconButton(iconRes: Int, onClick: () -> Unit) {
|
private fun CircleIconButton(iconRes: Int, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = ImageVector.vectorResource(id = iconRes),
|
imageVector = ImageVector.vectorResource(id = iconRes),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = TangemTheme.colors2.graphic.neutral.primary,
|
tint = TangemTheme.colors2.graphic.neutral.primary,
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.size(TangemTheme.dimens2.x11)
|
.size(TangemTheme.dimens2.x11)
|
||||||
.background(
|
.background(
|
||||||
color = TangemTheme.colors2.button.backgroundSecondary,
|
color = TangemTheme.colors2.button.backgroundSecondary,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
|
|
@ -42,6 +43,7 @@ import com.tangem.core.ui.format.bigdecimal.fiat
|
||||||
import com.tangem.core.ui.format.bigdecimal.formatStyled
|
import com.tangem.core.ui.format.bigdecimal.formatStyled
|
||||||
import com.tangem.core.ui.format.bigdecimal.price
|
import com.tangem.core.ui.format.bigdecimal.price
|
||||||
import com.tangem.core.ui.res.*
|
import com.tangem.core.ui.res.*
|
||||||
|
import com.tangem.core.ui.test.TokenActionsTestTags
|
||||||
import com.tangem.features.commonfeatures.impl.R
|
import com.tangem.features.commonfeatures.impl.R
|
||||||
import com.tangem.features.commonfeatures.impl.tokenactions.ui.state.PortfolioBadgeUM
|
import com.tangem.features.commonfeatures.impl.tokenactions.ui.state.PortfolioBadgeUM
|
||||||
import com.tangem.features.commonfeatures.impl.tokenactions.ui.state.TokenActionsUM
|
import com.tangem.features.commonfeatures.impl.tokenactions.ui.state.TokenActionsUM
|
||||||
|
|
@ -120,7 +122,13 @@ private fun QuickActionsList(state: TokenActionsUM, modifier: Modifier = Modifie
|
||||||
enter = fadeIn() + expandVertically(),
|
enter = fadeIn() + expandVertically(),
|
||||||
exit = fadeOut() + shrinkVertically(),
|
exit = fadeOut() + shrinkVertically(),
|
||||||
) {
|
) {
|
||||||
|
val actionModifier = when (actionUM) {
|
||||||
|
is QuickActionUM.V1.Buy, is QuickActionUM.V2.Buy ->
|
||||||
|
Modifier.testTag(TokenActionsTestTags.BUY_ACTION)
|
||||||
|
else -> Modifier
|
||||||
|
}
|
||||||
TokenActionRow(
|
TokenActionRow(
|
||||||
|
modifier = actionModifier,
|
||||||
iconRes = actionUM.icon,
|
iconRes = actionUM.icon,
|
||||||
title = actionUM.title,
|
title = actionUM.title,
|
||||||
description = actionUM.description,
|
description = actionUM.description,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue