[go: nahoru, domu]

blob: e4689f40db1cf7320bedfe1b4986a5d54c590dca [file] [log] [blame]
Matvei Malkov2d37cbd2019-07-04 15:15:20 +01001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.ui.material
18
Jelle Fresen11fc7062020-01-13 16:53:55 +000019import android.os.SystemClock.sleep
Louis Pullen-Freiliche46bcf02020-02-12 16:06:21 +000020import androidx.compose.emptyContent
Leland Richardsonfcf76b32020-05-13 16:58:59 -070021import androidx.compose.mutableStateOf
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010022import androidx.test.filters.MediumTest
Adam Powell999a89b2020-03-11 09:08:07 -070023import androidx.ui.core.LayoutCoordinates
24import androidx.ui.core.Modifier
George Mountd02af602020-03-06 16:41:40 -080025import androidx.ui.core.onPositioned
Filip Pavlis1d4d1b832020-05-27 14:45:15 +010026import androidx.ui.core.testTag
Louis Pullen-Freilichddda7be2020-07-17 18:28:12 +010027import androidx.compose.foundation.Box
28import androidx.compose.foundation.background
29import androidx.compose.foundation.clickable
George Mount8f237572020-04-30 12:08:30 -070030import androidx.ui.geometry.Offset
Matvei Malkov11fcc1332020-06-25 18:03:03 +010031import androidx.ui.graphics.Color
Louis Pullen-Freilich623e4052020-07-19 20:24:03 +010032import androidx.compose.foundation.layout.fillMaxSize
33import androidx.compose.foundation.layout.rtl
Calin Tatarudcde3402020-07-08 11:44:22 +010034import androidx.ui.test.GestureScope
Filip Pavlis028c0d52020-06-29 15:07:53 +010035import androidx.ui.test.assertIsEqualTo
36import androidx.ui.test.assertLeftPositionInRootIsEqualTo
37import androidx.ui.test.assertTopPositionInRootIsEqualTo
38import androidx.ui.test.assertWidthIsEqualTo
Calin Tatarudcde3402020-07-08 11:44:22 +010039import androidx.ui.test.center
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010040import androidx.ui.test.createComposeRule
Filip Pavlis659ea722020-07-13 14:14:32 +010041import androidx.ui.test.performGesture
42import androidx.ui.test.onNodeWithTag
Jelle Fresen11fc7062020-01-13 16:53:55 +000043import androidx.ui.test.globalBounds
Filip Pavlisa4d73a52020-07-14 11:30:00 +010044import androidx.ui.test.runOnIdle
Filip Pavlis6fdb2502020-04-02 14:41:32 +010045import androidx.ui.test.runOnUiThread
Filip Pavlis659ea722020-07-13 14:14:32 +010046import androidx.ui.test.click
47import androidx.ui.test.swipe
48import androidx.ui.test.swipeDown
49import androidx.ui.test.swipeLeft
50import androidx.ui.test.swipeRight
51import androidx.ui.test.swipeUp
George Mount842c8c12020-01-08 16:03:42 -080052import androidx.ui.unit.dp
Ryan Mentley7865a632019-08-20 20:10:29 -070053import androidx.ui.unit.height
Ryan Mentley7865a632019-08-20 20:10:29 -070054import androidx.ui.unit.width
Filip Pavlise63b30c2020-01-09 16:21:07 +000055import com.google.common.truth.Truth.assertThat
Matvei Malkov886ec6a2020-02-03 01:45:29 +000056import org.junit.Ignore
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010057import org.junit.Rule
58import org.junit.Test
59import org.junit.runner.RunWith
60import org.junit.runners.JUnit4
Jelle Fresen4c566312020-01-16 10:32:40 +000061import java.util.concurrent.CountDownLatch
62import java.util.concurrent.TimeUnit
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010063import kotlin.math.roundToInt
64
65@MediumTest
66@RunWith(JUnit4::class)
67class DrawerTest {
68
69 @get:Rule
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010070 val composeTestRule = createComposeRule(disableTransitions = true)
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010071
72 @Test
73 fun modalDrawer_testOffset_whenOpened() {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010074 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010075 ModalDrawerLayout(DrawerState.Opened, {}, drawerContent = {
Filip Pavlis028c0d52020-06-29 15:07:53 +010076 Box(Modifier.fillMaxSize().testTag("content"))
Louis Pullen-Freiliche46bcf02020-02-12 16:06:21 +000077 }, bodyContent = emptyContent())
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010078 }
Filip Pavlis028c0d52020-06-29 15:07:53 +010079
Filip Pavlis659ea722020-07-13 14:14:32 +010080 onNodeWithTag("content")
Filip Pavlis028c0d52020-06-29 15:07:53 +010081 .assertLeftPositionInRootIsEqualTo(0.dp)
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010082 }
83
84 @Test
85 fun modalDrawer_testOffset_whenClosed() {
Nader Jawad6df06122020-06-03 15:27:08 -070086 var position: Offset? = null
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010087 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +010088 ModalDrawerLayout(DrawerState.Closed, {}, drawerContent = {
Adam Powell999a89b2020-03-11 09:08:07 -070089 Box(Modifier.fillMaxSize().onPositioned { coords: LayoutCoordinates ->
Filip Pavlis028c0d52020-06-29 15:07:53 +010090 position = coords.localToRoot(Offset.Zero)
Matvei Malkov201726d2020-03-13 14:03:54 +000091 })
Louis Pullen-Freiliche46bcf02020-02-12 16:06:21 +000092 }, bodyContent = emptyContent())
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010093 }
Filip Pavlis028c0d52020-06-29 15:07:53 +010094
95 val width = rootWidth()
Filip Pavlisa4d73a52020-07-14 11:30:00 +010096 composeTestRule.runOnIdleWithDensity {
Filip Pavlis028c0d52020-06-29 15:07:53 +010097 position!!.x.toDp().assertIsEqualTo(-width)
Filip Pavlise63b30c2020-01-09 16:21:07 +000098 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +010099 }
100
101 @Test
102 fun modalDrawer_testEndPadding_whenOpened() {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100103 composeTestRule.setMaterialContent {
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100104 ModalDrawerLayout(DrawerState.Opened, {}, drawerContent = {
Filip Pavlis028c0d52020-06-29 15:07:53 +0100105 Box(Modifier.fillMaxSize().testTag("content"))
Louis Pullen-Freiliche46bcf02020-02-12 16:06:21 +0000106 }, bodyContent = emptyContent())
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100107 }
108
Filip Pavlis659ea722020-07-13 14:14:32 +0100109 onNodeWithTag("content")
Filip Pavlis028c0d52020-06-29 15:07:53 +0100110 .assertWidthIsEqualTo(rootWidth() - 56.dp)
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100111 }
112
113 @Test
114 fun bottomDrawer_testOffset_whenOpened() {
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100115 composeTestRule.setMaterialContent {
Calin Tatarudcde3402020-07-08 11:44:22 +0100116 BottomDrawerLayout(BottomDrawerState.Opened, {}, drawerContent = {
Filip Pavlis028c0d52020-06-29 15:07:53 +0100117 Box(Modifier.fillMaxSize().testTag("content"))
Louis Pullen-Freiliche46bcf02020-02-12 16:06:21 +0000118 }, bodyContent = emptyContent())
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100119 }
Filip Pavlise63b30c2020-01-09 16:21:07 +0000120
Filip Pavlis028c0d52020-06-29 15:07:53 +0100121 val width = rootWidth()
122 val height = rootHeight()
123 val expectedHeight = if (width > height) 0.dp else (height / 2)
Filip Pavlis659ea722020-07-13 14:14:32 +0100124 onNodeWithTag("content")
Filip Pavlis028c0d52020-06-29 15:07:53 +0100125 .assertTopPositionInRootIsEqualTo(expectedHeight)
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100126 }
127
128 @Test
129 fun bottomDrawer_testOffset_whenClosed() {
Nader Jawad6df06122020-06-03 15:27:08 -0700130 var position: Offset? = null
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100131 composeTestRule.setMaterialContent {
Calin Tatarudcde3402020-07-08 11:44:22 +0100132 BottomDrawerLayout(BottomDrawerState.Closed, {}, drawerContent = {
Adam Powell999a89b2020-03-11 09:08:07 -0700133 Box(Modifier.fillMaxSize().onPositioned { coords: LayoutCoordinates ->
Filip Pavlis028c0d52020-06-29 15:07:53 +0100134 position = coords.localToRoot(Offset.Zero)
Matvei Malkov201726d2020-03-13 14:03:54 +0000135 })
Louis Pullen-Freiliche46bcf02020-02-12 16:06:21 +0000136 }, bodyContent = emptyContent())
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100137 }
Filip Pavlis028c0d52020-06-29 15:07:53 +0100138
139 val height = rootHeight()
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100140 composeTestRule.runOnIdleWithDensity {
Filip Pavlis028c0d52020-06-29 15:07:53 +0100141 position!!.y.toDp().assertIsEqualTo(height)
Filip Pavlise63b30c2020-01-09 16:21:07 +0000142 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100143 }
144
145 @Test
Matvei Malkov886ec6a2020-02-03 01:45:29 +0000146 @Ignore("failing in postsubmit, fix in b/148751721")
Jelle Fresen4c566312020-01-16 10:32:40 +0000147 fun modalDrawer_openAndClose() {
George Mount8f237572020-04-30 12:08:30 -0700148 var contentWidth: Int? = null
Jelle Fresen4c566312020-01-16 10:32:40 +0000149 var openedLatch: CountDownLatch? = null
150 var closedLatch: CountDownLatch? = CountDownLatch(1)
Leland Richardsonfcf76b32020-05-13 16:58:59 -0700151 val drawerState = mutableStateOf(DrawerState.Closed)
Jelle Fresen4c566312020-01-16 10:32:40 +0000152 composeTestRule.setMaterialContent {
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100153 ModalDrawerLayout(drawerState.value, { drawerState.value = it },
154 drawerContent = {
155 Box(
156 Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
Nader Jawad6df06122020-06-03 15:27:08 -0700157 val pos = info.localToGlobal(Offset.Zero)
Nader Jawade6a9b332020-05-21 13:49:20 -0700158 if (pos.x == 0.0f) {
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100159 // If fully opened, mark the openedLatch if present
160 openedLatch?.countDown()
George Mount8f237572020-04-30 12:08:30 -0700161 } else if (-pos.x.roundToInt() == contentWidth) {
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100162 // If fully closed, mark the closedLatch if present
163 closedLatch?.countDown()
Matvei Malkov9f27abf2020-05-19 15:15:56 +0100164 }
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100165 }
166 )
167 },
168 bodyContent = {
169 Box(Modifier.fillMaxSize()
170 .onPositioned { contentWidth = it.size.width })
171 })
Jelle Fresen4c566312020-01-16 10:32:40 +0000172 }
173 // Drawer should start in closed state
174 assertThat(closedLatch!!.await(5, TimeUnit.SECONDS)).isTrue()
175
176 // When the drawer state is set to Opened
177 openedLatch = CountDownLatch(1)
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100178 runOnIdle {
Leland Richardsonfcf76b32020-05-13 16:58:59 -0700179 drawerState.value = DrawerState.Opened
Jelle Fresen4c566312020-01-16 10:32:40 +0000180 }
181 // Then the drawer should be opened
182 assertThat(openedLatch.await(5, TimeUnit.SECONDS)).isTrue()
183
184 // When the drawer state is set to Closed
185 closedLatch = CountDownLatch(1)
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100186 runOnIdle {
Leland Richardsonfcf76b32020-05-13 16:58:59 -0700187 drawerState.value = DrawerState.Closed
Jelle Fresen4c566312020-01-16 10:32:40 +0000188 }
189 // Then the drawer should be closed
190 assertThat(closedLatch.await(5, TimeUnit.SECONDS)).isTrue()
191 }
192
193 @Test
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100194 fun modalDrawer_bodyContent_clickable() {
195 var drawerClicks = 0
196 var bodyClicks = 0
Leland Richardsonfcf76b32020-05-13 16:58:59 -0700197 val drawerState = mutableStateOf(DrawerState.Closed)
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100198 composeTestRule.setMaterialContent {
Aurimas Liutikas7a828d32019-10-07 17:16:05 -0700199 // emulate click on the screen
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100200 ModalDrawerLayout(drawerState.value, { drawerState.value = it },
201 drawerContent = {
202 Box(
203 Modifier.fillMaxSize().clickable { drawerClicks += 1 },
204 children = emptyContent()
205 )
206 },
207 bodyContent = {
208 Box(
209 Modifier.testTag("Drawer").fillMaxSize().clickable { bodyClicks += 1 },
210 children = emptyContent()
211 )
212 })
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100213 }
214
Jelle Fresen11fc7062020-01-13 16:53:55 +0000215 // Click in the middle of the drawer (which is the middle of the body)
Filip Pavlis659ea722020-07-13 14:14:32 +0100216 onNodeWithTag("Drawer").performGesture { click() }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100217
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100218 runOnIdle {
Filip Pavlise63b30c2020-01-09 16:21:07 +0000219 assertThat(drawerClicks).isEqualTo(0)
220 assertThat(bodyClicks).isEqualTo(1)
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100221
Leland Richardsonfcf76b32020-05-13 16:58:59 -0700222 drawerState.value = DrawerState.Opened
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100223 }
Jelle Fresen11fc7062020-01-13 16:53:55 +0000224 sleep(100) // TODO(147586311): remove this sleep when opening the drawer triggers a wait
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100225
Jelle Fresen11fc7062020-01-13 16:53:55 +0000226 // Click on the left-center pixel of the drawer
Filip Pavlis659ea722020-07-13 14:14:32 +0100227 onNodeWithTag("Drawer").performGesture {
Nader Jawade6a9b332020-05-21 13:49:20 -0700228 val left = 1.0f
Nader Jawad63153c12020-05-21 14:17:08 -0700229 val centerY = (globalBounds.height / 2)
Filip Pavlis659ea722020-07-13 14:14:32 +0100230 click(Offset(left, centerY))
Jelle Fresen11fc7062020-01-13 16:53:55 +0000231 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100232
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100233 runOnIdle {
Filip Pavlise63b30c2020-01-09 16:21:07 +0000234 assertThat(drawerClicks).isEqualTo(1)
235 assertThat(bodyClicks).isEqualTo(1)
Filip Pavlis2b161e42019-11-22 17:40:08 +0000236 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100237 }
238
239 @Test
Matvei Malkov886ec6a2020-02-03 01:45:29 +0000240 @Ignore("failing in postsubmit, fix in b/148751721")
Jelle Fresen4c566312020-01-16 10:32:40 +0000241 fun bottomDrawer_openAndClose() {
George Mount8f237572020-04-30 12:08:30 -0700242 var contentHeight: Int? = null
243 var openedHeight: Int? = null
Jelle Fresen4c566312020-01-16 10:32:40 +0000244 var openedLatch: CountDownLatch? = null
245 var closedLatch: CountDownLatch? = CountDownLatch(1)
Calin Tatarudcde3402020-07-08 11:44:22 +0100246 val drawerState = mutableStateOf(BottomDrawerState.Closed)
Jelle Fresen4c566312020-01-16 10:32:40 +0000247 composeTestRule.setMaterialContent {
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100248 BottomDrawerLayout(drawerState.value, { drawerState.value = it },
249 drawerContent = {
250 Box(Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
Nader Jawad6df06122020-06-03 15:27:08 -0700251 val pos = info.localToGlobal(Offset.Zero)
George Mount8f237572020-04-30 12:08:30 -0700252 if (pos.y.roundToInt() == openedHeight) {
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100253 // If fully opened, mark the openedLatch if present
254 openedLatch?.countDown()
George Mount8f237572020-04-30 12:08:30 -0700255 } else if (pos.y.roundToInt() == contentHeight) {
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100256 // If fully closed, mark the closedLatch if present
257 closedLatch?.countDown()
258 }
259 })
260 },
261 bodyContent = {
262 Box(Modifier.fillMaxSize().onPositioned {
263 contentHeight = it.size.height
George Mount8f237572020-04-30 12:08:30 -0700264 openedHeight = (it.size.height * BottomDrawerOpenFraction).roundToInt()
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100265 })
266 }
267 )
Jelle Fresen4c566312020-01-16 10:32:40 +0000268 }
269 // Drawer should start in closed state
270 assertThat(closedLatch!!.await(5, TimeUnit.SECONDS)).isTrue()
271
272 // When the drawer state is set to Opened
273 openedLatch = CountDownLatch(1)
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100274 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100275 drawerState.value = BottomDrawerState.Opened
Jelle Fresen4c566312020-01-16 10:32:40 +0000276 }
277 // Then the drawer should be opened
278 assertThat(openedLatch.await(5, TimeUnit.SECONDS)).isTrue()
279
280 // When the drawer state is set to Closed
281 closedLatch = CountDownLatch(1)
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100282 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100283 drawerState.value = BottomDrawerState.Closed
Jelle Fresen4c566312020-01-16 10:32:40 +0000284 }
285 // Then the drawer should be closed
286 assertThat(closedLatch.await(5, TimeUnit.SECONDS)).isTrue()
287 }
288
289 @Test
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100290 fun bottomDrawer_bodyContent_clickable() {
291 var drawerClicks = 0
292 var bodyClicks = 0
Calin Tatarudcde3402020-07-08 11:44:22 +0100293 val drawerState = mutableStateOf(BottomDrawerState.Closed)
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100294 composeTestRule.setMaterialContent {
Aurimas Liutikas7a828d32019-10-07 17:16:05 -0700295 // emulate click on the screen
Filip Pavlis1d4d1b832020-05-27 14:45:15 +0100296 BottomDrawerLayout(drawerState.value, { drawerState.value = it },
297 drawerContent = {
298 Box(
299 Modifier.fillMaxSize().clickable { drawerClicks += 1 },
300 children = emptyContent()
301 )
302 },
303 bodyContent = {
304 Box(
305 Modifier.testTag("Drawer").fillMaxSize().clickable { bodyClicks += 1 },
306 children = emptyContent()
307 )
308 })
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100309 }
310
Jelle Fresen11fc7062020-01-13 16:53:55 +0000311 // Click in the middle of the drawer (which is the middle of the body)
Filip Pavlis659ea722020-07-13 14:14:32 +0100312 onNodeWithTag("Drawer").performGesture { click() }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100313
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100314 runOnIdle {
Filip Pavlise63b30c2020-01-09 16:21:07 +0000315 assertThat(drawerClicks).isEqualTo(0)
316 assertThat(bodyClicks).isEqualTo(1)
317 }
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100318
Filip Pavlis6fdb2502020-04-02 14:41:32 +0100319 runOnUiThread {
Calin Tatarudcde3402020-07-08 11:44:22 +0100320 drawerState.value = BottomDrawerState.Opened
Jelle Fresen11fc7062020-01-13 16:53:55 +0000321 }
322 sleep(100) // TODO(147586311): remove this sleep when opening the drawer triggers a wait
323
324 // Click on the bottom-center pixel of the drawer
Filip Pavlis659ea722020-07-13 14:14:32 +0100325 onNodeWithTag("Drawer").performGesture {
Jelle Fresen11fc7062020-01-13 16:53:55 +0000326 val bounds = globalBounds
Nader Jawad63153c12020-05-21 14:17:08 -0700327 val centerX = bounds.width / 2
328 val bottom = bounds.height - 1.0f
Filip Pavlis659ea722020-07-13 14:14:32 +0100329 click(Offset(centerX, bottom))
Jelle Fresen11fc7062020-01-13 16:53:55 +0000330 }
331
332 assertThat(drawerClicks).isEqualTo(1)
333 assertThat(bodyClicks).isEqualTo(1)
Matvei Malkov7aa7fd22019-08-16 16:52:59 +0100334 }
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100335
336 @Test
337 fun modalDrawer_openBySwipe() {
338 val drawerState = mutableStateOf(DrawerState.Closed)
339 composeTestRule.setMaterialContent {
340 // emulate click on the screen
341 Box(Modifier.testTag("Drawer")) {
342 ModalDrawerLayout(drawerState.value, { drawerState.value = it },
343 drawerContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100344 Box(Modifier.fillMaxSize().background(color = Color.Magenta))
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100345 },
346 bodyContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100347 Box(Modifier.fillMaxSize().background(color = Color.Red))
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100348 })
349 }
350 }
351
Filip Pavlis659ea722020-07-13 14:14:32 +0100352 onNodeWithTag("Drawer")
353 .performGesture { swipeRight() }
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100354
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100355 runOnIdle {
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100356 assertThat(drawerState.value).isEqualTo(DrawerState.Opened)
357 }
358
Filip Pavlis659ea722020-07-13 14:14:32 +0100359 onNodeWithTag("Drawer")
360 .performGesture { swipeLeft() }
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100361
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100362 runOnIdle {
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100363 assertThat(drawerState.value).isEqualTo(DrawerState.Closed)
364 }
365 }
366
367 @Test
368 fun modalDrawer_openBySwipe_rtl() {
369 val drawerState = mutableStateOf(DrawerState.Closed)
370 composeTestRule.setMaterialContent {
371 // emulate click on the screen
372 Box(Modifier.testTag("Drawer").rtl) {
373 ModalDrawerLayout(drawerState.value, { drawerState.value = it },
374 drawerContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100375 Box(Modifier.fillMaxSize().background(color = Color.Magenta))
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100376 },
377 bodyContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100378 Box(Modifier.fillMaxSize().background(color = Color.Red))
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100379 })
380 }
381 }
382
Filip Pavlis659ea722020-07-13 14:14:32 +0100383 onNodeWithTag("Drawer")
384 .performGesture { swipeLeft() }
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100385
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100386 runOnIdle {
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100387 assertThat(drawerState.value).isEqualTo(DrawerState.Opened)
388 }
389
Filip Pavlis659ea722020-07-13 14:14:32 +0100390 onNodeWithTag("Drawer")
391 .performGesture { swipeRight() }
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100392
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100393 runOnIdle {
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100394 assertThat(drawerState.value).isEqualTo(DrawerState.Closed)
395 }
396 }
397
398 @Test
399 fun bottomDrawer_openBySwipe() {
Calin Tatarudcde3402020-07-08 11:44:22 +0100400 val drawerState = mutableStateOf(BottomDrawerState.Closed)
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100401 composeTestRule.setMaterialContent {
402 // emulate click on the screen
403 Box(Modifier.testTag("Drawer")) {
404 BottomDrawerLayout(drawerState.value, { drawerState.value = it },
405 drawerContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100406 Box(Modifier.fillMaxSize().background(color = Color.Magenta))
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100407 },
408 bodyContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100409 Box(Modifier.fillMaxSize().background(color = Color.Red))
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100410 })
411 }
412 }
413
Filip Pavlis659ea722020-07-13 14:14:32 +0100414 onNodeWithTag("Drawer")
415 .performGesture { swipeUp() }
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100416
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100417 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100418 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Expanded)
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100419 }
420
Filip Pavlis659ea722020-07-13 14:14:32 +0100421 onNodeWithTag("Drawer")
422 .performGesture { swipeDown() }
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100423
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100424 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100425 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Closed)
Matvei Malkov11fcc1332020-06-25 18:03:03 +0100426 }
427 }
Calin Tatarudcde3402020-07-08 11:44:22 +0100428
429 @Test
430 fun bottomDrawer_openBySwipe_thresholds() {
431 val drawerState = mutableStateOf(BottomDrawerState.Closed)
432 composeTestRule.setMaterialContent {
433 // emulate click on the screen
434 Box(Modifier.testTag("Drawer")) {
435 BottomDrawerLayout(drawerState.value, { drawerState.value = it },
436 drawerContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100437 Box(Modifier.fillMaxSize().background(Color.Magenta))
Calin Tatarudcde3402020-07-08 11:44:22 +0100438 },
439 bodyContent = {
Matvei Malkovbf014c12020-07-09 17:40:10 +0100440 Box(Modifier.fillMaxSize().background(Color.Red))
Calin Tatarudcde3402020-07-08 11:44:22 +0100441 })
442 }
443 }
444 val threshold = with (composeTestRule.density) { BottomDrawerThreshold.toPx() }
445
Filip Pavlis659ea722020-07-13 14:14:32 +0100446 onNodeWithTag("Drawer")
447 .performGesture { swipeUpBy(threshold / 2) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100448
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100449 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100450 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Closed)
451 }
452
Filip Pavlis659ea722020-07-13 14:14:32 +0100453 onNodeWithTag("Drawer")
454 .performGesture { swipeUpBy(threshold) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100455
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100456 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100457 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Opened)
458 }
459
Filip Pavlis659ea722020-07-13 14:14:32 +0100460 onNodeWithTag("Drawer")
461 .performGesture { swipeUpBy(threshold / 2) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100462
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100463 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100464 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Opened)
465 }
466
Filip Pavlis659ea722020-07-13 14:14:32 +0100467 onNodeWithTag("Drawer")
468 .performGesture { swipeUpBy(threshold) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100469
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100470 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100471 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Expanded)
472 }
473
Filip Pavlis659ea722020-07-13 14:14:32 +0100474 onNodeWithTag("Drawer")
475 .performGesture { swipeDownBy(threshold / 2) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100476
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100477 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100478 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Expanded)
479 }
480
Filip Pavlis659ea722020-07-13 14:14:32 +0100481 onNodeWithTag("Drawer")
482 .performGesture { swipeDownBy(threshold) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100483
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100484 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100485 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Opened)
486 }
487
Filip Pavlis659ea722020-07-13 14:14:32 +0100488 onNodeWithTag("Drawer")
489 .performGesture { swipeDownBy(threshold / 2) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100490
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100491 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100492 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Opened)
493 }
494
Filip Pavlis659ea722020-07-13 14:14:32 +0100495 onNodeWithTag("Drawer")
496 .performGesture { swipeDownBy(threshold) }
Calin Tatarudcde3402020-07-08 11:44:22 +0100497
Filip Pavlisa4d73a52020-07-14 11:30:00 +0100498 runOnIdle {
Calin Tatarudcde3402020-07-08 11:44:22 +0100499 assertThat(drawerState.value).isEqualTo(BottomDrawerState.Closed)
500 }
501 }
502
Filip Pavlis659ea722020-07-13 14:14:32 +0100503 private fun GestureScope.swipeUpBy(offset: Float) {
504 swipe(center, center.copy(y = center.y - offset))
Calin Tatarudcde3402020-07-08 11:44:22 +0100505 }
506
Filip Pavlis659ea722020-07-13 14:14:32 +0100507 private fun GestureScope.swipeDownBy(offset: Float) {
508 swipe(center, center.copy(y = center.y + offset))
Calin Tatarudcde3402020-07-08 11:44:22 +0100509 }
Matvei Malkov2d37cbd2019-07-04 15:15:20 +0100510}