Skip to content

Commit 1d95400

Browse files
committed
Stop the instrumented tests depending on screen width
filteringByCategoryHidesTheOtherCategories matched the Medicine chip by text and clicked it. The filters are a LazyRow, so a chip that does not fit on screen is never composed and cannot be found. It passed on a 1080x2400 emulator and failed on CI's narrower one. The row now carries a test tag and the test scrolls to the chip, and takes the label from resources rather than hardcoding English. Also raises the waitUntil timeout from 5s to 15s. Three tests timed out on CI purely because a cold emulator is slower than a warm local one, which reports as a behaviour failure rather than as the machine being busy.
1 parent 36445e0 commit 1d95400

3 files changed

Lines changed: 23 additions & 3 deletions

File tree

composeApp/src/androidTest/kotlin/com/anish/expirydatereminder/ui/ItemJourneyTest.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule
77
import androidx.compose.ui.test.onAllNodesWithContentDescription
88
import androidx.compose.ui.test.onAllNodesWithText
99
import androidx.compose.ui.test.onNodeWithContentDescription
10+
import androidx.compose.ui.test.onNodeWithTag
1011
import androidx.compose.ui.test.onNodeWithText
1112
import androidx.compose.ui.test.performClick
13+
import androidx.compose.ui.test.performScrollToNode
1214
import androidx.compose.ui.test.performTextClearance
1315
import androidx.compose.ui.test.performTextInput
1416
import androidx.compose.ui.test.performTouchInput
@@ -21,6 +23,7 @@ import com.anish.expirydatereminder.domain.model.ItemDraft
2123
import com.anish.expirydatereminder.domain.model.plusDays
2224
import com.anish.expirydatereminder.domain.repository.CategoryRepository
2325
import com.anish.expirydatereminder.domain.repository.ItemRepository
26+
import com.anish.expirydatereminder.ui.items.CATEGORY_FILTERS_TAG
2427
import kotlin.time.Clock
2528
import kotlinx.coroutines.runBlocking
2629
import kotlinx.datetime.TimeZone
@@ -136,7 +139,12 @@ class ItemJourneyTest {
136139

137140
@Test
138141
fun filteringByCategoryHidesTheOtherCategories() {
139-
rule.onNodeWithText("Medicine").performClick()
142+
// Scroll the row rather than matching the chip directly. The filters are a LazyRow,
143+
// so a chip that does not fit on screen is never composed and cannot be found: this
144+
// passed on a wide emulator and failed on a narrower one.
145+
val medicine = string(R.string.category_medicine)
146+
rule.onNodeWithTag(CATEGORY_FILTERS_TAG).performScrollToNode(hasText(medicine))
147+
rule.onNodeWithText(medicine).performClick()
140148

141149
waitUntilRowShown(TABLETS)
142150
waitUntilRowGone(SOUP)
@@ -194,6 +202,8 @@ class ItemJourneyTest {
194202
const val SOUP = "EdrJourneySoup"
195203
const val TABLETS = "EdrJourneyTablets"
196204
const val RENAMED = "EdrJourneyRenamed"
197-
const val TIMEOUT_MS = 5_000L
205+
// Generous because a cold CI emulator is far slower than a warm local one, and a
206+
// timeout here reports as a behaviour failure rather than as the machine being busy.
207+
const val TIMEOUT_MS = 15_000L
198208
}
199209
}

composeApp/src/androidTest/kotlin/com/anish/expirydatereminder/ui/items/AddItemFlowTest.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ class AddItemFlowTest {
138138
private companion object {
139139
const val FIRST = "EdrTestItemOne"
140140
const val SECOND = "EdrTestItemTwo"
141-
const val TIMEOUT_MS = 5_000L
141+
// Generous because a cold CI emulator is far slower than a warm local one, and a
142+
// timeout here reports as a behaviour failure rather than as the machine being busy.
143+
const val TIMEOUT_MS = 15_000L
142144

143145
/** What [BigDateField] draws in place of an empty four-digit value. */
144146
const val YEAR_PLACEHOLDER = "----"

composeApp/src/main/kotlin/com/anish/expirydatereminder/ui/items/ItemListScreen.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import androidx.compose.ui.focus.FocusRequester
6868
import androidx.compose.ui.focus.focusRequester
6969
import androidx.compose.ui.graphics.Color
7070
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
71+
import androidx.compose.ui.platform.testTag
7172
import androidx.compose.ui.res.stringResource
7273
import androidx.compose.ui.semantics.clearAndSetSemantics
7374
import androidx.compose.ui.semantics.contentDescription
@@ -372,6 +373,10 @@ private fun InlineSearch(value: String, onValueChange: (String) -> Unit, modifie
372373
@Composable
373374
private fun CategoryFilters(categories: List<Category>, selectedId: Long?, onSelect: (Long?) -> Unit) {
374375
LazyRow(
376+
// Tagged so a test can scroll the row to a chip. A LazyRow does not compose what is
377+
// off screen, and how many chips fit depends on the device, so matching one by text
378+
// alone only works on a screen wide enough to show it.
379+
modifier = Modifier.testTag(CATEGORY_FILTERS_TAG),
375380
contentPadding = PaddingValues(horizontal = Space.md),
376381
horizontalArrangement = Arrangement.spacedBy(Space.sm),
377382
) {
@@ -588,3 +593,6 @@ private fun ItemRow(item: Item, state: ItemListUiState, status: ExpiryStatus, on
588593
}
589594

590595
private val HERO_TEXT_HEIGHT = 104.dp
596+
597+
/** Identifies the category filter row so a test can scroll it to a chip. */
598+
const val CATEGORY_FILTERS_TAG = "category_filters"

0 commit comments

Comments
 (0)