Updated on 2026-08-14
This commit is contained in:
parent
2110b5f541
commit
53c0546b5c
8 changed files with 9 additions and 96 deletions
|
|
@ -93,6 +93,13 @@ Scenario files orchestrate flows; they must not define page objects or duplicate
|
||||||
`com.tangem.core.res.R` or `com.tangem.core.ui.R`. The Detekt rule `UnsafeStringResourceUsage`
|
`com.tangem.core.res.R` or `com.tangem.core.ui.R`. The Detekt rule `UnsafeStringResourceUsage`
|
||||||
enforces this for production code; reviewers extend it to test code informally.
|
enforces this for production code; reviewers extend it to test code informally.
|
||||||
|
|
||||||
|
### Allure IDs
|
||||||
|
|
||||||
|
- **Every test method gets its own unique `@AllureId`.** Never reuse the same id across two test methods —
|
||||||
|
not even for two variants of one manual case. If a manual case is split into multiple automated tests
|
||||||
|
(e.g. a positive and a negative variant), each test must be linked to its own distinct Allure case/id.
|
||||||
|
(Note: iOS sometimes shares one id across methods — do NOT mirror that here.)
|
||||||
|
|
||||||
### Assertions
|
### Assertions
|
||||||
|
|
||||||
- **Never** use Kotlin's built-in `assert(...)` — Android instrumentation runs don't enable JVM
|
- **Never** use Kotlin's built-in `assert(...)` — Android instrumentation runs don't enable JVM
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,6 @@ class DeviceSettingsPageObject(semanticsProvider: SemanticsNodeInteractionsProvi
|
||||||
useUnmergedTree = true
|
useUnmergedTree = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val securityModeRow: KNode = child {
|
|
||||||
hasTestTag(DeviceSettingsScreenTestTags.SECURITY_MODE_ROW)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun resetToFactorySettingsButtonSubtitle(withBackup: Boolean = false): KNode = child {
|
fun resetToFactorySettingsButtonSubtitle(withBackup: Boolean = false): KNode = child {
|
||||||
hasTestTag(DeviceSettingsScreenTestTags.ITEM_SUBTITLE)
|
hasTestTag(DeviceSettingsScreenTestTags.ITEM_SUBTITLE)
|
||||||
useUnmergedTree = true
|
useUnmergedTree = true
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package com.tangem.screens
|
|
||||||
|
|
||||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
|
||||||
import com.tangem.common.BaseTestCase
|
|
||||||
import com.tangem.core.ui.test.SecurityModeScreenTestTags
|
|
||||||
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
|
|
||||||
|
|
||||||
class SecurityModePageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
|
||||||
ComposeScreen<SecurityModePageObject>(semanticsProvider = semanticsProvider) {
|
|
||||||
|
|
||||||
val screenContainer: KNode = child {
|
|
||||||
hasTestTag(SecurityModeScreenTestTags.SCREEN_CONTAINER)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun BaseTestCase.onSecurityModeScreen(function: SecurityModePageObject.() -> Unit) =
|
|
||||||
onComposeScreen(composeTestRule, function)
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
package com.tangem.tests
|
|
||||||
|
|
||||||
import com.tangem.common.BaseTestCase
|
|
||||||
import com.tangem.common.extensions.clickWithAssertion
|
|
||||||
import com.tangem.domain.models.scan.ProductType
|
|
||||||
import com.tangem.scenarios.openDeviceSettingsScreen
|
|
||||||
import com.tangem.scenarios.openMainScreen
|
|
||||||
import com.tangem.screens.*
|
|
||||||
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 SecurityModeTest : BaseTestCase() {
|
|
||||||
|
|
||||||
@AllureId("2267")
|
|
||||||
@DisplayName("Security Mode: Twin card opens the section")
|
|
||||||
@Test
|
|
||||||
fun twinSecurityModeOpensTest() =
|
|
||||||
setupHooks().run {
|
|
||||||
step("Open 'Main Screen'") {
|
|
||||||
openMainScreen(productType = ProductType.Twins, isTwinsCard = true)
|
|
||||||
}
|
|
||||||
openDeviceSettingsScreen()
|
|
||||||
step("Click on 'Scan card or ring' button") {
|
|
||||||
onDeviceSettingsScreen { scanCardOrRingButton.clickWithAssertion() }
|
|
||||||
}
|
|
||||||
step("Assert 'Security Mode' row is enabled") {
|
|
||||||
onDeviceSettingsScreen { securityModeRow.assertIsEnabled() }
|
|
||||||
}
|
|
||||||
step("Click on 'Security Mode' row") {
|
|
||||||
onDeviceSettingsScreen { securityModeRow.clickWithAssertion() }
|
|
||||||
}
|
|
||||||
step("Assert 'Security Mode' screen is displayed") {
|
|
||||||
onSecurityModeScreen { screenContainer.assertIsDisplayed() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@DisplayName("Security Mode: other cards cannot open the section")
|
|
||||||
@Test
|
|
||||||
fun walletSecurityModeDisabledTest() =
|
|
||||||
setupHooks().run {
|
|
||||||
step("Open 'Main Screen'") {
|
|
||||||
openMainScreen()
|
|
||||||
}
|
|
||||||
openDeviceSettingsScreen()
|
|
||||||
step("Click on 'Scan card or ring' button") {
|
|
||||||
onDeviceSettingsScreen { scanCardOrRingButton.clickWithAssertion() }
|
|
||||||
}
|
|
||||||
step("Assert 'Security Mode' row is not clickable") {
|
|
||||||
onDeviceSettingsScreen { securityModeRow.assertIsNotEnabled() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -125,7 +125,7 @@ private fun ScanCardContent(onScanCardClick: () -> Unit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("ComplexMethod", "LongMethod")
|
@Suppress("ComplexMethod")
|
||||||
@Composable
|
@Composable
|
||||||
private fun CardSettings(state: CardSettingsScreenState) {
|
private fun CardSettings(state: CardSettingsScreenState) {
|
||||||
if (state.cardDetails == null) return
|
if (state.cardDetails == null) return
|
||||||
|
|
@ -156,13 +156,6 @@ private fun CardSettings(state: CardSettingsScreenState) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.then(
|
|
||||||
if (cardInfo is CardInfo.SecurityMode) {
|
|
||||||
Modifier.testTag(DeviceSettingsScreenTestTags.SECURITY_MODE_ROW)
|
|
||||||
} else {
|
|
||||||
Modifier
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.clickable(
|
.clickable(
|
||||||
enabled = cardInfo.isClickable,
|
enabled = cardInfo.isClickable,
|
||||||
onClick = { state.onElementClick(cardInfo) },
|
onClick = { state.onElementClick(cardInfo) },
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,9 @@ import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.testTag
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||||
import com.tangem.core.ui.test.SecurityModeScreenTestTags
|
|
||||||
import com.tangem.tap.features.details.redux.SecurityOption
|
import com.tangem.tap.features.details.redux.SecurityOption
|
||||||
import com.tangem.tap.features.details.ui.common.DetailsMainButton
|
import com.tangem.tap.features.details.ui.common.DetailsMainButton
|
||||||
import com.tangem.tap.features.details.ui.common.DetailsRadioButtonElement
|
import com.tangem.tap.features.details.ui.common.DetailsRadioButtonElement
|
||||||
|
|
@ -37,8 +35,7 @@ private fun SecurityModeOptions(state: SecurityModeScreenState) {
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
.padding(bottom = 28.dp)
|
.padding(bottom = 28.dp),
|
||||||
.testTag(SecurityModeScreenTestTags.SCREEN_CONTAINER),
|
|
||||||
verticalArrangement = Arrangement.SpaceBetween,
|
verticalArrangement = Arrangement.SpaceBetween,
|
||||||
) {
|
) {
|
||||||
ScreenTitle(titleRes = R.string.card_settings_security_mode, Modifier.padding(bottom = 36.dp))
|
ScreenTitle(titleRes = R.string.card_settings_security_mode, Modifier.padding(bottom = 36.dp))
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,4 @@ object DeviceSettingsScreenTestTags {
|
||||||
const val IMAGE_BLOCK = "DEVICE_SETTINGS_SCREEN_IMAGE_BLOCK"
|
const val IMAGE_BLOCK = "DEVICE_SETTINGS_SCREEN_IMAGE_BLOCK"
|
||||||
const val ITEM_TITLE = "DEVICE_SETTINGS_SCREEN_ITEM_TITLE"
|
const val ITEM_TITLE = "DEVICE_SETTINGS_SCREEN_ITEM_TITLE"
|
||||||
const val ITEM_SUBTITLE = "DEVICE_SETTINGS_SCREEN_ITEM_SUBTITLE"
|
const val ITEM_SUBTITLE = "DEVICE_SETTINGS_SCREEN_ITEM_SUBTITLE"
|
||||||
const val SECURITY_MODE_ROW = "DEVICE_SETTINGS_SCREEN_SECURITY_MODE_ROW"
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package com.tangem.core.ui.test
|
|
||||||
|
|
||||||
object SecurityModeScreenTestTags {
|
|
||||||
const val SCREEN_CONTAINER = "SECURITY_MODE_SCREEN_CONTAINER"
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue