Skip to content

Commit b8ade63

Browse files
committed
test: Add test for Modifier.bringIntoView
1 parent 72fd54e commit b8ade63

1 file changed

Lines changed: 184 additions & 0 deletions

File tree

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package uk.gov.android.ui.patterns.utils
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.fillMaxWidth
5+
import androidx.compose.foundation.layout.height
6+
import androidx.compose.foundation.lazy.LazyColumn
7+
import androidx.compose.foundation.lazy.LazyListState
8+
import androidx.compose.foundation.lazy.rememberLazyListState
9+
import androidx.compose.foundation.rememberScrollState
10+
import androidx.compose.foundation.text.BasicText
11+
import androidx.compose.foundation.verticalScroll
12+
import androidx.compose.runtime.Composable
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.focus.FocusRequester
15+
import androidx.compose.ui.focus.focusRequester
16+
import androidx.compose.ui.input.InputMode
17+
import androidx.compose.ui.input.InputModeManager
18+
import androidx.compose.ui.input.key.Key
19+
import androidx.compose.ui.platform.LocalInputModeManager
20+
import androidx.compose.ui.platform.testTag
21+
import androidx.compose.ui.test.ExperimentalTestApi
22+
import androidx.compose.ui.test.assertIsDisplayed
23+
import androidx.compose.ui.test.assertIsNotDisplayed
24+
import androidx.compose.ui.test.junit4.ComposeTestRule
25+
import androidx.compose.ui.test.junit4.createComposeRule
26+
import androidx.compose.ui.test.onNodeWithTag
27+
import androidx.compose.ui.test.onNodeWithText
28+
import androidx.compose.ui.test.performKeyInput
29+
import androidx.compose.ui.test.pressKey
30+
import androidx.compose.ui.unit.dp
31+
import org.junit.Rule
32+
import org.junit.Test
33+
import org.junit.runner.RunWith
34+
import org.robolectric.RobolectricTestRunner
35+
import uk.gov.android.ui.patterns.utils.BringIntoViewTest.Companion.NUM_ITEMS
36+
import uk.gov.android.ui.patterns.utils.BringIntoViewTest.Companion.containerHeight
37+
import uk.gov.android.ui.patterns.utils.BringIntoViewTest.Companion.itemHeight
38+
import uk.gov.android.ui.patterns.utils.ModifierExtensions.bringIntoView
39+
40+
@OptIn(ExperimentalTestApi::class)
41+
@RunWith(RobolectricTestRunner::class)
42+
class BringIntoViewTest {
43+
@get:Rule
44+
val composeTestRule = createComposeRule()
45+
46+
private val focusRequester = FocusRequester()
47+
48+
@Test
49+
fun `keyboard can scroll down and up for non-lazy list`() {
50+
setUpColumn()
51+
52+
composeTestRule.pressDirectionDown()
53+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsNotDisplayed()
54+
55+
composeTestRule.pressDirectionUp()
56+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsDisplayed()
57+
}
58+
59+
@Test
60+
fun `keyboard can scroll down then up for lazy list`() {
61+
setUpLazyColumn()
62+
63+
composeTestRule.pressDirectionDown()
64+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsNotDisplayed()
65+
66+
composeTestRule.pressDirectionUp()
67+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsDisplayed()
68+
}
69+
70+
@Test
71+
fun `keyboard does not scroll down when content fits`() {
72+
setUpColumn(numItems = 1)
73+
74+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsDisplayed()
75+
76+
composeTestRule.pressDirectionDown()
77+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsDisplayed()
78+
}
79+
80+
@Test
81+
fun `keyboard does not scroll up when already at top`() {
82+
setUpColumn()
83+
84+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsDisplayed()
85+
86+
composeTestRule.pressDirectionUp()
87+
composeTestRule.onNodeWithText(FIRST_ITEM).assertIsDisplayed()
88+
}
89+
90+
private fun setUpColumn(
91+
numItems: Int = NUM_ITEMS,
92+
) {
93+
setContent {
94+
val scrollState = rememberScrollState()
95+
TestColumn(
96+
scrollState = scrollState,
97+
numItems = numItems,
98+
modifier = Modifier
99+
.focusRequester(focusRequester)
100+
.bringIntoView(scrollState),
101+
)
102+
}
103+
}
104+
105+
private fun setUpLazyColumn() {
106+
setContent {
107+
val listState = rememberLazyListState()
108+
TestLazyColumn(
109+
listState = listState,
110+
modifier = Modifier
111+
.focusRequester(focusRequester)
112+
.bringIntoView(listState),
113+
)
114+
}
115+
}
116+
117+
private fun setContent(content: @Composable () -> Unit) {
118+
lateinit var inputModeManager: InputModeManager
119+
composeTestRule.setContent {
120+
inputModeManager = LocalInputModeManager.current
121+
content()
122+
}
123+
composeTestRule.runOnIdle {
124+
inputModeManager.requestInputMode(InputMode.Keyboard)
125+
focusRequester.requestFocus()
126+
}
127+
}
128+
129+
private fun ComposeTestRule.pressDirectionUp() =
130+
onNodeWithTag(TEST_TAG)
131+
.performKeyInput { pressKey(Key.DirectionUp) }
132+
133+
private fun ComposeTestRule.pressDirectionDown() =
134+
onNodeWithTag(TEST_TAG)
135+
.performKeyInput { pressKey(Key.DirectionDown) }
136+
137+
companion object {
138+
const val TEST_TAG = "bringIntoViewTest"
139+
const val NUM_ITEMS = 50
140+
const val FIRST_ITEM = "Item 0"
141+
val containerHeight = 100.dp
142+
val itemHeight = 30.dp
143+
}
144+
}
145+
146+
@Composable
147+
private fun TestColumn(
148+
scrollState: androidx.compose.foundation.ScrollState,
149+
modifier: Modifier = Modifier,
150+
numItems: Int = NUM_ITEMS,
151+
) =
152+
Column(
153+
modifier = modifier
154+
.height(containerHeight)
155+
.verticalScroll(scrollState)
156+
.testTag(BringIntoViewTest.TEST_TAG),
157+
) {
158+
repeat(numItems) { index ->
159+
BasicText(
160+
text = "Item $index",
161+
modifier = Modifier.fillMaxWidth().height(itemHeight),
162+
)
163+
}
164+
}
165+
166+
@Composable
167+
private fun TestLazyColumn(
168+
listState: LazyListState,
169+
modifier: Modifier = Modifier,
170+
numItems: Int = NUM_ITEMS,
171+
) =
172+
LazyColumn(
173+
state = listState,
174+
modifier = modifier
175+
.height(containerHeight)
176+
.testTag(BringIntoViewTest.TEST_TAG),
177+
) {
178+
items(numItems) { index ->
179+
BasicText(
180+
text = "Item $index",
181+
modifier = Modifier.fillMaxWidth().height(itemHeight),
182+
)
183+
}
184+
}

0 commit comments

Comments
 (0)