Updated on 2026-08-14
This commit is contained in:
parent
ba3e7e4044
commit
58ac55c4ae
9 changed files with 26 additions and 20 deletions
|
|
@ -62,6 +62,9 @@ When the user asks to **port** an iOS test to Android:
|
||||||
|
|
||||||
### Test class shape
|
### Test class shape
|
||||||
|
|
||||||
|
- **Test method names are camelCase and always end with `Test`** (e.g. `groupTokensTest()`,
|
||||||
|
`renameWalletTest()`). Never use `snake_case` and never the unit-test `GIVEN … WHEN … THEN …`
|
||||||
|
backtick phrasing — that GWT convention is for JVM unit tests only, not instrumentation tests.
|
||||||
- **Scenario state setup goes in the test body**, not inside the open-the-feature helper. Each test
|
- **Scenario state setup goes in the test body**, not inside the open-the-feature helper. Each test
|
||||||
starts with explicit `step("Set WireMock scenario '$name' to '$state'") { setWireMockScenarioState(name, state) }`
|
starts with explicit `step("Set WireMock scenario '$name' to '$state'") { setWireMockScenarioState(name, state) }`
|
||||||
calls, then calls a thin helper (e.g. `openTangemPay()`) that only opens the screen. Mirror the
|
calls, then calls a thin helper (e.g. `openTangemPay()`) that only opens the screen. Mirror the
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,7 @@ fun BaseTestCase.switchFeeTokenAndApply(currentFeeToken: String, newFeeToken: St
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
step("Click on 'Apply' button") {
|
step("Click on 'Apply' button") {
|
||||||
|
waitForIdle()
|
||||||
onSendFeeSelectorBottomSheet { applyButton.performClick() }
|
onSendFeeSelectorBottomSheet { applyButton.performClick() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ 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.BuyTokenScreenTestTags
|
||||||
import com.tangem.core.ui.test.MarketsTestTags
|
import com.tangem.core.ui.test.MarketsTestTags
|
||||||
|
|
@ -38,7 +37,7 @@ class AddFundsBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractions
|
||||||
}
|
}
|
||||||
|
|
||||||
val closeButton: KNode = child {
|
val closeButton: KNode = child {
|
||||||
hasTestTag(AddFundsBottomSheetTestTags.CLOSE_BUTTON)
|
hasTestTag(BaseBottomSheetTestTags.CLOSE_BUTTON)
|
||||||
useUnmergedTree = true
|
useUnmergedTree = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,7 @@ class SwapTokenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
||||||
|
|
||||||
val swapFiatAmount: KNode = child {
|
val swapFiatAmount: KNode = child {
|
||||||
hasTestTag(SwapTokenScreenTestTags.SWAP_FIAT_AMOUNT)
|
hasTestTag(SwapTokenScreenTestTags.SWAP_FIAT_AMOUNT)
|
||||||
|
useUnmergedTree = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val swapSelectTokenIcon: KNode = child {
|
val swapSelectTokenIcon: KNode = child {
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ import com.tangem.common.constants.TestConstants.TANGEM_PAY_ELIGIBILITY_SCENARIO
|
||||||
import com.tangem.common.extensions.assertTextContainsSafe
|
import com.tangem.common.extensions.assertTextContainsSafe
|
||||||
import com.tangem.common.extensions.clickWithAssertion
|
import com.tangem.common.extensions.clickWithAssertion
|
||||||
import com.tangem.common.extensions.extractText
|
import com.tangem.common.extensions.extractText
|
||||||
import com.tangem.common.extensions.pullToRefresh
|
|
||||||
import com.tangem.common.utils.assertClipboardTextEquals
|
import com.tangem.common.utils.assertClipboardTextEquals
|
||||||
import com.tangem.common.utils.resetWireMockScenarioState
|
import com.tangem.common.utils.resetWireMockScenarioState
|
||||||
|
import com.tangem.common.utils.resetWireMockScenarios
|
||||||
import com.tangem.common.utils.setWireMockScenarioState
|
import com.tangem.common.utils.setWireMockScenarioState
|
||||||
import com.tangem.scenarios.*
|
import com.tangem.scenarios.*
|
||||||
import com.tangem.screens.tangempay.*
|
import com.tangem.screens.tangempay.*
|
||||||
|
|
@ -23,7 +23,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
@AllureId("4549")
|
@AllureId("4549")
|
||||||
@DisplayName("Tangem Pay: change PIN code from card details")
|
@DisplayName("Tangem Pay: change PIN code from card details")
|
||||||
@Test
|
@Test
|
||||||
fun changePin_SetsNewPinCode_FromCardDetails() {
|
fun changePinSetsNewPinCodeFromCardDetailsTest() {
|
||||||
val newPin = "5217"
|
val newPin = "5217"
|
||||||
val pinSetupScenario = "tangem_pay_pin_setup"
|
val pinSetupScenario = "tangem_pay_pin_setup"
|
||||||
val pinNotSetState = "PinNotSet"
|
val pinNotSetState = "PinNotSet"
|
||||||
|
|
@ -31,6 +31,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
additionalBeforeSection = {
|
additionalBeforeSection = {
|
||||||
|
resetWireMockScenarios()
|
||||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
||||||
setWireMockScenarioState(pinSetupScenario, pinNotSetState)
|
setWireMockScenarioState(pinSetupScenario, pinNotSetState)
|
||||||
},
|
},
|
||||||
|
|
@ -67,7 +68,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
@AllureId("4969")
|
@AllureId("4969")
|
||||||
@DisplayName("Tangem Pay: balance updates after transaction on payment account screen")
|
@DisplayName("Tangem Pay: balance updates after transaction on payment account screen")
|
||||||
@Test
|
@Test
|
||||||
fun balanceUpdatesAfterTransaction_OnPaymentAccountScreen() {
|
fun balanceUpdatesAfterTransactionOnPaymentAccountScreenTest() {
|
||||||
val balanceScenario = "tangem_pay_balance_update"
|
val balanceScenario = "tangem_pay_balance_update"
|
||||||
val initialState = "InitialBalance"
|
val initialState = "InitialBalance"
|
||||||
val afterTransactionState = "AfterTransaction"
|
val afterTransactionState = "AfterTransaction"
|
||||||
|
|
@ -75,6 +76,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
additionalBeforeSection = {
|
additionalBeforeSection = {
|
||||||
|
resetWireMockScenarios()
|
||||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
||||||
setWireMockScenarioState(balanceScenario, initialState)
|
setWireMockScenarioState(balanceScenario, initialState)
|
||||||
},
|
},
|
||||||
|
|
@ -90,7 +92,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
step("Switch WireMock scenario '$balanceScenario' to '$afterTransactionState'") {
|
step("Switch WireMock scenario '$balanceScenario' to '$afterTransactionState'") {
|
||||||
setWireMockScenarioState(balanceScenario, afterTransactionState)
|
setWireMockScenarioState(balanceScenario, afterTransactionState)
|
||||||
}
|
}
|
||||||
step("Pull to refresh") { pullToRefresh() }
|
step("Pull to refresh") { pullToRefreshTangemPay() }
|
||||||
step("Assert updated balance contains '9'") {
|
step("Assert updated balance contains '9'") {
|
||||||
onTangemPayMainScreen { balance.assertTextContainsSafe("9", substring = true) }
|
onTangemPayMainScreen { balance.assertTextContainsSafe("9", substring = true) }
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +102,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
@AllureId("4970")
|
@AllureId("4970")
|
||||||
@DisplayName("Tangem Pay: new transaction appears after mocked charge")
|
@DisplayName("Tangem Pay: new transaction appears after mocked charge")
|
||||||
@Test
|
@Test
|
||||||
fun transactionList_NewTransactionAppears_AfterMockedCharge() {
|
fun transactionListNewTransactionAppearsAfterMockedChargeTest() {
|
||||||
val historyScenario = "tangem_pay_transaction_history"
|
val historyScenario = "tangem_pay_transaction_history"
|
||||||
val initialState = "InitialEmpty"
|
val initialState = "InitialEmpty"
|
||||||
val afterTransactionState = "AfterTransaction"
|
val afterTransactionState = "AfterTransaction"
|
||||||
|
|
@ -109,6 +111,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
additionalBeforeSection = {
|
additionalBeforeSection = {
|
||||||
|
resetWireMockScenarios()
|
||||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
||||||
setWireMockScenarioState(historyScenario, initialState)
|
setWireMockScenarioState(historyScenario, initialState)
|
||||||
},
|
},
|
||||||
|
|
@ -126,7 +129,7 @@ class TangemPayTest : BaseTestCase() {
|
||||||
step("Switch WireMock scenario '$historyScenario' to '$afterTransactionState'") {
|
step("Switch WireMock scenario '$historyScenario' to '$afterTransactionState'") {
|
||||||
setWireMockScenarioState(historyScenario, afterTransactionState)
|
setWireMockScenarioState(historyScenario, afterTransactionState)
|
||||||
}
|
}
|
||||||
step("Pull to refresh") { pullToRefresh() }
|
step("Pull to refresh") { pullToRefreshTangemPay() }
|
||||||
step("Assert transaction from '$merchantName' is displayed") {
|
step("Assert transaction from '$merchantName' is displayed") {
|
||||||
onTangemPayMainScreen {
|
onTangemPayMainScreen {
|
||||||
transactionRowWithText(merchantName).assertIsDisplayed()
|
transactionRowWithText(merchantName).assertIsDisplayed()
|
||||||
|
|
@ -138,12 +141,13 @@ class TangemPayTest : BaseTestCase() {
|
||||||
@AllureId("4974")
|
@AllureId("4974")
|
||||||
@DisplayName("Tangem Pay: reveal and copy card number, expiration and CVC")
|
@DisplayName("Tangem Pay: reveal and copy card number, expiration and CVC")
|
||||||
@Test
|
@Test
|
||||||
fun revealAndCopyCardDetails_NumberExpirationCVC() {
|
fun revealAndCopyCardDetailsNumberExpirationCVCTest() {
|
||||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
val eligibilityState = "PaeraCustomer"
|
val eligibilityState = "PaeraCustomer"
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
additionalBeforeSection = {
|
additionalBeforeSection = {
|
||||||
|
resetWireMockScenarios()
|
||||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
||||||
},
|
},
|
||||||
additionalAfterSection = {
|
additionalAfterSection = {
|
||||||
|
|
@ -200,13 +204,14 @@ class TangemPayTest : BaseTestCase() {
|
||||||
@AllureId("4971")
|
@AllureId("4971")
|
||||||
@DisplayName("Tangem Pay: freeze card via confirmation sheet")
|
@DisplayName("Tangem Pay: freeze card via confirmation sheet")
|
||||||
@Test
|
@Test
|
||||||
fun freezeUnfreezeCard_TogglesCardState() {
|
fun freezeUnfreezeCardTogglesCardStateTest() {
|
||||||
val freezeScenario = "tangem_pay_card_freeze"
|
val freezeScenario = "tangem_pay_card_freeze"
|
||||||
val startedState = "Started"
|
val startedState = "Started"
|
||||||
val eligibilityState = "PaeraCustomer"
|
val eligibilityState = "PaeraCustomer"
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
additionalBeforeSection = {
|
additionalBeforeSection = {
|
||||||
|
resetWireMockScenarios()
|
||||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
||||||
setWireMockScenarioState(freezeScenario, startedState)
|
setWireMockScenarioState(freezeScenario, startedState)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_VERY_LONG
|
||||||
import com.tangem.common.extensions.assertTextContainsSafe
|
import com.tangem.common.extensions.assertTextContainsSafe
|
||||||
import com.tangem.common.extensions.clickWithAssertion
|
import com.tangem.common.extensions.clickWithAssertion
|
||||||
import com.tangem.common.utils.resetWireMockScenarioState
|
import com.tangem.common.utils.resetWireMockScenarioState
|
||||||
|
import com.tangem.common.utils.resetWireMockScenarios
|
||||||
import com.tangem.common.utils.setWireMockScenarioState
|
import com.tangem.common.utils.setWireMockScenarioState
|
||||||
import com.tangem.core.res.R as CoreResR
|
import com.tangem.core.res.R as CoreResR
|
||||||
import com.tangem.scenarios.*
|
import com.tangem.scenarios.*
|
||||||
|
|
@ -26,7 +27,7 @@ class TangemPayTopUpTest : BaseTestCase() {
|
||||||
@AllureId("4973")
|
@AllureId("4973")
|
||||||
@DisplayName("Tangem Pay: top up swaps Bitcoin to USDC and appends deposit to history")
|
@DisplayName("Tangem Pay: top up swaps Bitcoin to USDC and appends deposit to history")
|
||||||
@Test
|
@Test
|
||||||
fun topUpFromTangemPay_SwapsBitcoinToUSDC_AppendsDepositToHistory() {
|
fun topUpFromTangemPaySwapsBitcoinToUSDCAppendsDepositToHistoryTest() {
|
||||||
val bitcoinScenario = "bitcoin_utxo"
|
val bitcoinScenario = "bitcoin_utxo"
|
||||||
val expressAssetsScenario = "express_api_assets"
|
val expressAssetsScenario = "express_api_assets"
|
||||||
val balanceScenario = "tangem_pay_balance_update"
|
val balanceScenario = "tangem_pay_balance_update"
|
||||||
|
|
@ -43,6 +44,7 @@ class TangemPayTopUpTest : BaseTestCase() {
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
additionalBeforeSection = {
|
additionalBeforeSection = {
|
||||||
|
resetWireMockScenarios()
|
||||||
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
setWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO, eligibilityState)
|
||||||
setWireMockScenarioState(bitcoinScenario, bitcoinBalanceState)
|
setWireMockScenarioState(bitcoinScenario, bitcoinBalanceState)
|
||||||
setWireMockScenarioState(expressAssetsScenario, expressAssetsState)
|
setWireMockScenarioState(expressAssetsScenario, expressAssetsState)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package com.tangem.core.ui.test
|
|
||||||
|
|
||||||
object AddFundsBottomSheetTestTags {
|
|
||||||
const val CLOSE_BUTTON = "ADD_FUNDS_BOTTOM_SHEET_CLOSE_BUTTON"
|
|
||||||
}
|
|
||||||
|
|
@ -21,7 +21,7 @@ import com.tangem.core.ui.ds.topbar.TangemTopBarType
|
||||||
import com.tangem.core.ui.ds2.button.TangemButton
|
import com.tangem.core.ui.ds2.button.TangemButton
|
||||||
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.core.ui.test.BaseBottomSheetTestTags
|
||||||
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.addfunds.model.AddFundsModel
|
import com.tangem.features.commonfeatures.impl.addfunds.model.AddFundsModel
|
||||||
|
|
@ -201,7 +201,7 @@ internal class DefaultAddFundsComponent @AssistedInject constructor(
|
||||||
},
|
},
|
||||||
endContent = {
|
endContent = {
|
||||||
TangemButton(
|
TangemButton(
|
||||||
modifier = Modifier.testTag(AddFundsBottomSheetTestTags.CLOSE_BUTTON),
|
modifier = Modifier.testTag(BaseBottomSheetTestTags.CLOSE_BUTTON),
|
||||||
iconStart = TangemIconUM.Icon(iconRes = CoreR.drawable.ic_close_24),
|
iconStart = TangemIconUM.Icon(iconRes = CoreR.drawable.ic_close_24),
|
||||||
onClick = onCloseClick,
|
onClick = onCloseClick,
|
||||||
size = TangemButton.Size.X11,
|
size = TangemButton.Size.X11,
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ private fun SimpleTransactionCardEmpty(
|
||||||
style = TangemTheme.typography.body2,
|
style = TangemTheme.typography.body2,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.defaultMinSize(minHeight = TangemTheme.dimens.size20)
|
.defaultMinSize(minHeight = TangemTheme.dimens.size20)
|
||||||
.testTag(SwapTokenScreenTestTags.SWAP_FIAT_AMOUNT),
|
.testTag(SwapTokenScreenTestTags.RECEIVE_FIAT_AMOUNT),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SecondarySmallButton(
|
SecondarySmallButton(
|
||||||
|
|
@ -239,7 +239,7 @@ private fun SimpleTransactionCardLoading(modifier: Modifier = Modifier) {
|
||||||
style = TangemTheme.typography.body2,
|
style = TangemTheme.typography.body2,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.defaultMinSize(minHeight = 20.dp, minWidth = 40.dp)
|
.defaultMinSize(minHeight = 20.dp, minWidth = 40.dp)
|
||||||
.testTag(SwapTokenScreenTestTags.SWAP_FIAT_AMOUNT),
|
.testTag(SwapTokenScreenTestTags.RECEIVE_FIAT_AMOUNT),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SecondarySmallButton(
|
SecondarySmallButton(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue