Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-06 11:54:03 +03:00
parent 1abd6b9b2e
commit 9d73e02d69
9 changed files with 588 additions and 43 deletions

View file

@ -84,6 +84,7 @@ abstract class BaseTestCase : TestCase(
* and only after that the activity should be launched.
*/
protected fun setupHooks(
additionalBeforeAppLaunchSection: () -> Unit = {},
additionalBeforeSection: () -> Unit = {},
additionalAfterSection: () -> Unit = {},
) = before {
@ -91,6 +92,7 @@ abstract class BaseTestCase : TestCase(
// Setup WireMock redirect for CI with local WireMock instances
val wiremockUrl = InstrumentationRegistry.getArguments().getString(WIREMOCK_BASE_URL_ARG)
WireMockRedirectInterceptor.overriddenBaseUrl = wiremockUrl
additionalBeforeAppLaunchSection()
hiltRule.inject()
runBlocking {
appPreferencesStore.editData { mutablePreferences ->

View file

@ -2,6 +2,7 @@ package com.tangem.common.extensions
import androidx.test.uiautomator.By
import com.tangem.common.BaseTestCase
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
import com.tangem.wallet.R
import io.github.kakaocup.kakao.common.utilities.getResourceString
@ -74,8 +75,17 @@ fun BaseTestCase.stopApp(packageName: String) {
}
fun BaseTestCase.launchApp(packageName: String) {
device.apps.waitForAppLaunchAndReady(packageName = packageName)
device.apps.launch(packageName)
device.apps.waitForAppLaunchAndReady(packageName = packageName)
}
fun BaseTestCase.restartApp(packageName: String) {
device.uiDevice.pressHome()
device.apps.kill(packageName)
waitForIdle()
device.apps.launch(packageName)
device.apps.waitForAppLaunchAndReady(timeout = WAIT_UNTIL_TIMEOUT_LONG, packageName = packageName)
waitForIdle()
}
enum class SwipeDirection {

View file

@ -0,0 +1,26 @@
package com.tangem.scenarios
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.screens.onMainScreen
import com.tangem.screens.onMarketsScreen
import com.tangem.screens.onMarketsTokenDetailsScreen
import io.qameta.allure.kotlin.Allure.step
fun BaseTestCase.openMarketTokenDetailsScreen(blockchainName: String, tokenName: String) {
step("Open 'Markets' screen") {
onMainScreen { searchThroughMarketPlaceholder.performClick() }
waitForIdle()
}
step("Click on 'Search' placeholder") {
onMarketsScreen { searchThroughMarketPlaceholder.performClick() }
}
step("Click on $blockchainName blockchain") {
waitForIdle()
onMarketsScreen { tokenWithTitle(blockchainName).clickWithAssertion() }
}
step("Click on $tokenName token") {
waitForIdle()
onMarketsTokenDetailsScreen { tokenWithTitle(tokenName).clickWithAssertion() }
}
}

View file

@ -0,0 +1,180 @@
package com.tangem.scenarios
import androidx.compose.ui.test.click
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.screens.*
import io.github.kakaocup.kakao.common.utilities.getResourceString
import io.qameta.allure.kotlin.Allure.step
import com.tangem.common.ui.R as CommonUiR
private val firstStoryIndex = 0
private val firstStoryTitle = getResourceString(CommonUiR.string.swap_story_first_title)
private val firstStorySubtitle = getResourceString(CommonUiR.string.swap_story_first_subtitle)
private val secondStoryIndex = 1
private val secondStoryTitle = getResourceString(CommonUiR.string.swap_story_second_title)
private val secondStorySubtitle = getResourceString(CommonUiR.string.swap_story_second_subtitle)
private val thirdStoryIndex = 2
private val thirdStoryTitle = getResourceString(CommonUiR.string.swap_story_third_title)
private val thirdStorySubtitle = getResourceString(CommonUiR.string.swap_story_third_subtitle)
private val forthStoryIndex = 3
private val forthStoryTitle = getResourceString(CommonUiR.string.swap_story_forth_title)
private val forthStorySubtitle = getResourceString(CommonUiR.string.swap_story_forth_subtitle)
private val fifthStoryIndex = 4
private val fifthStoryTitle = getResourceString(CommonUiR.string.swap_story_fifth_title)
private val fifthStorySubtitle = getResourceString(CommonUiR.string.swap_story_fifth_subtitle)
fun BaseTestCase.openSwapScreen(
from: SwapEntryPoint,
storiesExist: Boolean = true,
) {
when (from) {
SwapEntryPoint.MainScreen -> step("Click on 'Swap' button on 'Main' screen") {
onMainScreen { swapButton.performClick() }
}
SwapEntryPoint.TokenDetails -> step("Click on 'Swap' button on 'Token details' screen") {
onTokenDetailsScreen { swapButton().performClick() }
}
SwapEntryPoint.MarketsTokenDetails -> step("Click on 'Swap' button on 'Markets' token details screen") {
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.performClick() }
}
SwapEntryPoint.TokenActionsBottomSheet -> step("Click on 'Swap' button on token actions bottom sheet") {
onTokenActionsBottomSheet { swapButton.performClick() }
}
}
if (storiesExist) {
step("Close 'Stories' screen") {
onSwapStoriesScreen { closeButton.clickWithAssertion() }
}
} else {
step("Assert 'Stories' screen is not displayed") {
onSwapStoriesScreen { container.assertDoesNotExist() }
}
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
}
}
fun BaseTestCase.checkStoriesContent(
storyIndex: Int,
storyTitle: String,
storySubtitle: String,
) {
step("Assert 'Close' button is displayed") {
onSwapStoriesScreen { closeButton.assertIsDisplayed() }
}
step("Assert progress bar item №${storyIndex + 1} is displayed") {
onSwapStoriesScreen { progressBarItem(storyIndex).assertIsDisplayed() }
}
step("Assert story title is $storyTitle") {
onSwapStoriesScreen { title.assertTextContains(storyTitle) }
}
step("Assert story subtitle is $storySubtitle") {
onSwapStoriesScreen { subtitle.assertTextContains(storySubtitle) }
}
}
fun BaseTestCase.checkStoriesChanges() {
step("Check title and subtitle for story №${firstStoryIndex + 1}") {
checkStoriesContent(
storyIndex = firstStoryIndex,
storyTitle = firstStoryTitle,
storySubtitle = firstStorySubtitle
)
}
step("Click on right side") {
onSwapStoriesScreen { container.performTouchInput { click(centerRight) } }
}
step("Check title and subtitle for story №${secondStoryIndex + 1}") {
checkStoriesContent(
storyIndex = secondStoryIndex,
storyTitle = secondStoryTitle,
storySubtitle = secondStorySubtitle
)
}
step("Click on right side") {
onSwapStoriesScreen { container.performTouchInput { click(centerRight) } }
}
step("Check title and subtitle for story №${thirdStoryIndex + 1}") {
checkStoriesContent(
storyIndex = thirdStoryIndex,
storyTitle = thirdStoryTitle,
storySubtitle = thirdStorySubtitle
)
}
step("Click on right side") {
onSwapStoriesScreen { container.performTouchInput { click(centerRight) } }
}
step("Check title and subtitle for story №${forthStoryIndex + 1}") {
checkStoriesContent(
storyIndex = forthStoryIndex,
storyTitle = forthStoryTitle,
storySubtitle = forthStorySubtitle
)
}
step("Click on right side") {
onSwapStoriesScreen { container.performTouchInput { click(centerRight) } }
}
step("Check title and subtitle for story №${fifthStoryIndex + 1}") {
checkStoriesContent(
storyIndex = fifthStoryIndex,
storyTitle = fifthStoryTitle,
storySubtitle = fifthStorySubtitle
)
}
step("Click on left side") {
onSwapStoriesScreen { container.performTouchInput { click(centerLeft) } }
}
step("Check title and subtitle for story №${forthStoryIndex + 1}") {
checkStoriesContent(
storyIndex = forthStoryIndex,
storyTitle = forthStoryTitle,
storySubtitle = forthStorySubtitle
)
}
step("Click on left side") {
onSwapStoriesScreen { container.performTouchInput { click(centerLeft) } }
}
step("Check title and subtitle for story №${thirdStoryIndex + 1}") {
checkStoriesContent(
storyIndex = thirdStoryIndex,
storyTitle = thirdStoryTitle,
storySubtitle = thirdStorySubtitle
)
}
step("Click on left side") {
onSwapStoriesScreen { container.performTouchInput { click(centerLeft) } }
}
step("Check title and subtitle for story №${secondStoryIndex + 1}") {
checkStoriesContent(
storyIndex = secondStoryIndex,
storyTitle = secondStoryTitle,
storySubtitle = secondStorySubtitle
)
}
step("Click on left side") {
onSwapStoriesScreen { container.performTouchInput { click(centerLeft) } }
}
step("Check title and subtitle for story №${firstStoryIndex + 1}") {
checkStoriesContent(
storyIndex = firstStoryIndex,
storyTitle = firstStoryTitle,
storySubtitle = firstStorySubtitle
)
}
}
sealed class SwapEntryPoint {
object MainScreen : SwapEntryPoint()
object TokenDetails : SwapEntryPoint()
object MarketsTokenDetails : SwapEntryPoint()
object TokenActionsBottomSheet : SwapEntryPoint()
}

View file

@ -10,10 +10,31 @@ import io.github.kakaocup.compose.node.element.KNode
class SwapStoriesPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<SwapStoriesPageObject>(semanticsProvider = semanticsProvider) {
val container: KNode = child {
hasTestTag(SwapStoriesScreenTestTags.SCREEN_CONTAINER)
useUnmergedTree = true
}
val closeButton: KNode = child {
hasTestTag(SwapStoriesScreenTestTags.CLOSE_BUTTON)
useUnmergedTree = true
}
fun progressBarItem(index: Int): KNode = child {
hasTestTag(SwapStoriesScreenTestTags.PROGRESS_BAR_ITEM)
hasPosition(index)
useUnmergedTree = true
}
val title: KNode = child {
hasTestTag(SwapStoriesScreenTestTags.TITLE)
useUnmergedTree = true
}
val subtitle: KNode = child {
hasTestTag(SwapStoriesScreenTestTags.SUBTITLE)
useUnmergedTree = true
}
}
internal fun BaseTestCase.onSwapStoriesScreen(function: SwapStoriesPageObject.() -> Unit) =

View file

@ -1,10 +1,13 @@
package com.tangem.tests.swap
import androidx.compose.ui.test.longClick
import androidx.test.InstrumentationRegistry.getTargetContext
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.assertHasBadge
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.scenarios.openMainScreen
import com.tangem.scenarios.synchronizeAddresses
import com.tangem.common.extensions.restartApp
import com.tangem.common.utils.resetWireMockScenarioState
import com.tangem.common.utils.setWireMockScenarioState
import com.tangem.scenarios.*
import com.tangem.screens.*
import dagger.hilt.android.testing.HiltAndroidTest
import io.qameta.allure.kotlin.AllureId
@ -30,14 +33,8 @@ class SwapStoriesTest : BaseTestCase() {
step("Assert 'Swap' button has badge") {
onMainScreen { swapButton.assertHasBadge() }
}
step("Click on 'Swap' button") {
onMainScreen { swapButton.performClick() }
}
step("Close 'Stories' screen") {
onSwapStoriesScreen { closeButton.clickWithAssertion() }
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.MainScreen)
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
@ -68,14 +65,8 @@ class SwapStoriesTest : BaseTestCase() {
step("Assert 'Swap' button has badge") {
onTokenDetailsScreen { swapButton().assertHasBadge() }
}
step("Click on 'Swap' button") {
onTokenDetailsScreen { swapButton().performClick() }
}
step("Close 'Stories' screen") {
onSwapStoriesScreen { closeButton.clickWithAssertion() }
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.TokenDetails)
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
@ -102,33 +93,15 @@ class SwapStoriesTest : BaseTestCase() {
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Open 'Markets' screen") {
onMainScreen { searchThroughMarketPlaceholder.performClick() }
waitForIdle()
}
step("") {
onMarketsScreen { searchThroughMarketPlaceholder.performClick() }
}
step("Click on $tokenName token") {
waitForIdle()
onMarketsScreen { tokenWithTitle(tokenName).clickWithAssertion() }
}
step("Click on $tokenName token") {
waitForIdle()
onMarketsTokenDetailsScreen { tokenWithTitle(tokenName).performClick() }
step("Open 'Markets' token details screen for token '$tokenName'") {
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
}
step("Assert 'Swap' button has badge") {
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertIsDisplayed() }
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertContentDescriptionEquals(badgeShown) }
}
step("Click on 'Swap' button") {
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.performClick() }
}
step("Close 'Stories' screen") {
onSwapStoriesScreen { closeButton.clickWithAssertion() }
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails)
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
@ -138,4 +111,327 @@ class SwapStoriesTest : BaseTestCase() {
}
}
}
@AllureId("5469")
@DisplayName("Check unavailable swap stories on 'Main' screen")
@Test
fun checkUnavailableSwapStoriesOnMainScreen() {
val scenarioName = "stories_first_time_swap"
val scenarioErrorState = "Error"
val packageName = getTargetContext().packageName
setupHooks(
additionalBeforeAppLaunchSection = {
setWireMockScenarioState(scenarioName = scenarioName, state = scenarioErrorState)
},
additionalAfterSection = {
resetWireMockScenarioState(scenarioName)
}
).run {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Assert 'Swap' button has badge") {
onMainScreen { swapButton.assertHasBadge(false) }
}
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.MainScreen, storiesExist = false)
}
step("Reset WireMock scenario state") {
resetWireMockScenarioState(scenarioName)
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
}
step("Restart app") {
restartApp(packageName)
}
step("Assert 'Swap' button is displayed") {
waitForIdle()
onMainScreen { swapButton.assertIsDisplayed() }
}
step("Assert 'Swap' button has badge") {
onMainScreen { swapButton.assertHasBadge() }
}
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.MainScreen, storiesExist = true)
}
}
}
@AllureId("5471")
@DisplayName("Check unavailable swap stories on 'Token details' screen")
@Test
fun checkUnavailableSwapStoriesOnTokenDetailsScreen() {
val scenarioName = "stories_first_time_swap"
val scenarioErrorState = "Error"
val packageName = getTargetContext().packageName
val tokenName = "Ethereum"
setupHooks(
additionalBeforeAppLaunchSection = {
setWireMockScenarioState(scenarioName = scenarioName, state = scenarioErrorState)
},
additionalAfterSection = {
resetWireMockScenarioState(scenarioName)
}
).run {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Click on token with name: '$tokenName'") {
onMainScreen { tokenWithTitleAndAddress(tokenName).performClick() }
}
step("Assert 'Swap' button has badge") {
onTokenDetailsScreen { swapButton().assertHasBadge(false) }
}
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = false)
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
}
step("Reset WireMock scenario state") {
resetWireMockScenarioState(scenarioName)
}
step("Restart app") {
restartApp(packageName)
}
step("Assert 'Swap' button has badge") {
waitForIdle()
onMainScreen { swapButton.assertHasBadge() }
}
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = true)
}
}
}
@AllureId("5471")
@DisplayName("Check unavailable swap stories on 'Markets' token details screen")
@Test
fun checkUnavailableSwapStoriesOnMarketsTokenDetailsScreen() {
val scenarioName = "stories_first_time_swap"
val scenarioErrorState = "Error"
val packageName = getTargetContext().packageName
val tokenName = "Ethereum"
val badgeShown = "Badge shown"
val badgeHidden = "Badge hidden"
setupHooks(
additionalBeforeAppLaunchSection = {
setWireMockScenarioState(scenarioName = scenarioName, state = scenarioErrorState)
},
additionalAfterSection = {
resetWireMockScenarioState(scenarioName)
}
).run {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Open 'Markets' token details screen for token '$tokenName'") {
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
}
step("Assert 'Swap' button has badge") {
waitForIdle()
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertIsDisplayed() }
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertContentDescriptionEquals(badgeHidden) }
}
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails, storiesExist = false)
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
}
step("Reset WireMock scenario state") {
resetWireMockScenarioState(scenarioName)
}
step("Restart app") {
restartApp(packageName)
}
step("Open 'Markets' token details screen for token '$tokenName'") {
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
}
step("Assert 'Swap' button has badge") {
waitForIdle()
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertIsDisplayed() }
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.assertContentDescriptionEquals(badgeShown) }
}
step("Open 'Swap' screen") {
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails, storiesExist = true)
}
}
}
@AllureId("5474")
@DisplayName("Check 'Swap' stories on 'Main' screen")
@Test
fun checkSwapStoriesOnMainScreenTest() {
setupHooks().run {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Click on 'Swap' button on 'Main' screen") {
onMainScreen { swapButton.performClick() }
}
step("Check stories changes") {
checkStoriesChanges()
}
step("Click on 'Close' button") {
onSwapStoriesScreen { closeButton.performClick() }
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
}
step("Open 'Swap' screen without stories") {
openSwapScreen(from = SwapEntryPoint.MainScreen, storiesExist = false)
}
}
}
@AllureId("5475")
@DisplayName("Check 'Swap' stories on 'Token details' screen")
@Test
fun checkSwapStoriesOnTokenDetailsScreenTest() {
val tokenName = "Ethereum"
setupHooks().run {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Click on token with name: '$tokenName'") {
onMainScreen { tokenWithTitleAndAddress(tokenName).performClick() }
}
step("Assert 'Swap' button has badge") {
onTokenDetailsScreen { swapButton().assertHasBadge() }
}
step("Click on 'Swap' button on 'Token details' screen") {
onTokenDetailsScreen { swapButton().performClick() }
}
step("Check stories changes") {
checkStoriesChanges()
}
step("Click on 'Close' button") {
onSwapStoriesScreen { closeButton.performClick() }
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
}
step("Open 'Swap' screen without stories") {
openSwapScreen(from = SwapEntryPoint.TokenDetails, storiesExist = false)
}
}
}
@AllureId("5476")
@DisplayName("Check 'Swap' stories on 'Markets' screen")
@Test
fun checkSwapStoriesOnMarketTokenDetailsScreenTest() {
val tokenName = "Ethereum"
setupHooks().run {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Open 'Markets' token details screen for token '$tokenName'") {
openMarketTokenDetailsScreen(blockchainName = tokenName, tokenName = tokenName)
}
step("Click on 'Swap' button on 'Markets' token details screen") {
onMarketsTokenDetailsScreen { swapPortfolioQuickActionButton.performClick() }
}
step("Check stories changes") {
checkStoriesChanges()
}
step("Click on 'Close' button") {
onSwapStoriesScreen { closeButton.performClick() }
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
}
step("Open 'Swap' screen without stories") {
openSwapScreen(from = SwapEntryPoint.MarketsTokenDetails, storiesExist = false)
}
}
}
@AllureId("5477")
@DisplayName("Check 'Swap' stories on token actions bottom sheet")
@Test
fun checkSwapStoriesOnTokenActionsBottomSheetTest() {
val tokenName = "Ethereum"
setupHooks().run {
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses()
}
step("Long click on token with name: '$tokenName'") {
waitForIdle()
onMainScreen {
tokenWithTitleAndAddress(tokenName).performTouchInput {
longClick(
position = center,
durationMillis = 1000L
)
}
}
}
step("Click on 'Swap' button") {
onTokenActionsBottomSheet { swapButton.performClick() }
}
step("Check stories changes") {
checkStoriesChanges()
}
step("Click on 'Close' button") {
onSwapStoriesScreen { closeButton.performClick() }
}
step("Assert 'Swap' screen title is displayed") {
onSwapTokenScreen { title.assertIsDisplayed() }
}
step("Click on 'Close' button") {
onSwapTokenScreen { closeButton.performClick() }
}
step("Open 'Swap' screen without stories") {
openSwapScreen(from = SwapEntryPoint.TokenActionsBottomSheet, storiesExist = false)
}
}
}
}

View file

@ -94,6 +94,7 @@ private fun SwapStoriesText(current: SwapStoriesUM.Content.Config) {
),
color = TangemTheme.colors.text.constantWhite,
textAlign = TextAlign.Center,
modifier = Modifier.testTag(SwapStoriesScreenTestTags.TITLE),
)
Text(
text = current.subtitle.resolveReference(),
@ -105,6 +106,7 @@ private fun SwapStoriesText(current: SwapStoriesUM.Content.Config) {
),
color = SubtitleColor,
textAlign = TextAlign.Center,
modifier = Modifier.testTag(SwapStoriesScreenTestTags.SUBTITLE),
)
}
}

View file

@ -8,16 +8,20 @@ import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.SpacerW4
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.SwapStoriesScreenTestTags
import kotlinx.coroutines.delay
private const val STORIES_ANIMATION_SPEED_ZERO_DURATION = 3000L
@ -99,6 +103,7 @@ fun StoriesProgressBar(
.clip(RoundedCornerShape(2.dp))
.background(TangemColorPalette.White)
.fillMaxHeight()
.testTag(SwapStoriesScreenTestTags.PROGRESS_BAR_ITEM)
.let { modifier ->
when (index) {
currentStep -> modifier.fillMaxWidth(progress.value)

View file

@ -3,4 +3,7 @@ package com.tangem.core.ui.test
object SwapStoriesScreenTestTags {
const val SCREEN_CONTAINER = "SWAP_STORIES_SCREEN_CONTAINER"
const val CLOSE_BUTTON = "SWAP_STORIES_SCREEN_CLOSE_BUTTON"
const val PROGRESS_BAR_ITEM = "SWAP_STORIES_SCREEN_PROGRESS_BAR_ITEM"
const val TITLE = "SWAP_STORIES_SCREEN_TITLE"
const val SUBTITLE = "SWAP_STORIES_SCREEN_SUBTITLE"
}