Updated on 2026-08-14
This commit is contained in:
parent
a65b0ab877
commit
846f6301d9
3 changed files with 37 additions and 3 deletions
|
|
@ -41,6 +41,36 @@ so the hold gesture is silently swallowed: the button looks fine, the user holds
|
||||||
3. Snapshot again — byte-identical trees mean `onConfirm` didn't run.
|
3. Snapshot again — byte-identical trees mean `onConfirm` didn't run.
|
||||||
4. Or check WireMock request stats for the downstream API call expected after `onConfirm`.
|
4. Or check WireMock request stats for the downstream API call expected after `onConfirm`.
|
||||||
|
|
||||||
|
## `assertTextContains(x)` defaults to exact-segment match, not substring
|
||||||
|
|
||||||
|
`SemanticsNodeInteraction.assertTextContains(value, substring = false, ignoreCase = false)` defaults to
|
||||||
|
`substring = false` — it asserts that some text **segment of the node equals `value` exactly**. Matching
|
||||||
|
a symbol or fragment inside a larger string (e.g. `"€"` against a balance `"€108,474.21"`) silently
|
||||||
|
never matches and times out inside a `waitUntil`. Pass `substring = true`:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
totalBalanceText.assertTextContains("€", substring = true)
|
||||||
|
```
|
||||||
|
|
||||||
|
Reference tests that pass the *full* string (`assertTextContains("€108,474.21")`) work with the default,
|
||||||
|
which is why a copy-pasted matcher can mislead.
|
||||||
|
|
||||||
|
## Kakao-Compose `child { }`: use DSL matchers, not raw Compose matcher aliases
|
||||||
|
|
||||||
|
Inside a `child { … }` / `ComposeScreen` element builder, call the DSL methods (`hasText(...)`,
|
||||||
|
`hasTestTag(...)`, `hasAnyDescendant(...)`). A common alias is `import androidx.compose.ui.test.hasText
|
||||||
|
as withText` — but `withText(x)` as a **bare statement** inside the builder just creates a
|
||||||
|
`SemanticsMatcher` and discards it, registering nothing → `ViewBuilderException: Please set matchers for
|
||||||
|
your Element!` at run time. `withText`/raw matchers are only valid as *arguments* to a DSL method
|
||||||
|
(`hasAnyDescendant(withText(name))`), never as a standalone line.
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// WRONG — no matcher registered
|
||||||
|
fun walletNameValue(name: String) = child { withText(name); useUnmergedTree = true }
|
||||||
|
// RIGHT
|
||||||
|
fun walletNameValue(name: String) = child { hasText(name); useUnmergedTree = true }
|
||||||
|
```
|
||||||
|
|
||||||
## Decompose model lifecycle vs. data refresh
|
## Decompose model lifecycle vs. data refresh
|
||||||
|
|
||||||
Models (e.g. `TangemPayDetailsModel`) call data fetches from `init {}`, NOT on `ON_RESUME`. Returning
|
Models (e.g. `TangemPayDetailsModel`) call data fetches from `init {}`, NOT on `ON_RESUME`. Returning
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ class WalletSettingsPageObject(semanticsProvider: SemanticsNodeInteractionsProvi
|
||||||
}
|
}
|
||||||
|
|
||||||
fun walletNameValue(name: String): KNode = walletSettingsItem.child {
|
fun walletNameValue(name: String): KNode = walletSettingsItem.child {
|
||||||
withText(name)
|
hasText(name)
|
||||||
useUnmergedTree = true
|
useUnmergedTree = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,9 @@ class AppCurrencyTest : BaseTestCase() {
|
||||||
step("Assert total balance contains '$targetSymbol' on 'Main' screen") {
|
step("Assert total balance contains '$targetSymbol' on 'Main' screen") {
|
||||||
// Balance re-loads in the new currency async after the switch — wait for the € equivalent.
|
// Balance re-loads in the new currency async after the switch — wait for the € equivalent.
|
||||||
composeTestRule.waitUntil(WAIT_UNTIL_TIMEOUT_LONG) {
|
composeTestRule.waitUntil(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||||
runCatching { onMainScreen { totalBalanceText.assertTextContains(targetSymbol) } }.isSuccess
|
runCatching {
|
||||||
|
onMainScreen { totalBalanceText.assertTextContains(targetSymbol, substring = true) }
|
||||||
|
}.isSuccess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
step("Click on token '$token'") {
|
step("Click on token '$token'") {
|
||||||
|
|
@ -78,7 +80,9 @@ class AppCurrencyTest : BaseTestCase() {
|
||||||
}
|
}
|
||||||
step("Assert token fiat balance contains '$targetSymbol'") {
|
step("Assert token fiat balance contains '$targetSymbol'") {
|
||||||
composeTestRule.waitUntil(WAIT_UNTIL_TIMEOUT_LONG) {
|
composeTestRule.waitUntil(WAIT_UNTIL_TIMEOUT_LONG) {
|
||||||
runCatching { onTokenDetailsScreen { fiatBalance.assertTextContains(targetSymbol) } }.isSuccess
|
runCatching {
|
||||||
|
onTokenDetailsScreen { fiatBalance.assertTextContains(targetSymbol, substring = true) }
|
||||||
|
}.isSuccess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue