Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 1 | /* |
| 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 | */ |
Louis Pullen-Freilich | ddda7be | 2020-07-17 18:28:12 +0100 | [diff] [blame] | 16 | package androidx.compose.foundation |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 17 | |
Mihai Popa | b300d2c | 2020-06-23 16:25:50 +0100 | [diff] [blame] | 18 | import androidx.compose.Providers |
| 19 | import androidx.compose.ambientOf |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 20 | import androidx.compose.state |
Matvei Malkov | 28d8d5d | 2020-07-14 20:04:44 +0100 | [diff] [blame] | 21 | import androidx.test.filters.FlakyTest |
Ryan Mentley | 7865a63 | 2019-08-20 20:10:29 -0700 | [diff] [blame] | 22 | import androidx.test.filters.MediumTest |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 23 | import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation |
| 24 | import androidx.test.uiautomator.UiDevice |
Matvei Malkov | 323b745 | 2020-05-01 16:57:52 +0100 | [diff] [blame] | 25 | import androidx.ui.core.Modifier |
Filip Pavlis | 8b8a862 | 2020-02-13 16:32:04 +0000 | [diff] [blame] | 26 | import androidx.ui.test.assertIsDisplayed |
Ryan Mentley | 7865a63 | 2019-08-20 20:10:29 -0700 | [diff] [blame] | 27 | import androidx.ui.test.createComposeRule |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 28 | import androidx.ui.test.performClick |
| 29 | import androidx.ui.test.onNodeWithText |
Filip Pavlis | a4d73a5 | 2020-07-14 11:30:00 +0100 | [diff] [blame] | 30 | import androidx.ui.test.runOnIdle |
Mihai Popa | b300d2c | 2020-06-23 16:25:50 +0100 | [diff] [blame] | 31 | import org.junit.Assert.assertEquals |
Filip Pavlis | 2b161e4 | 2019-11-22 17:40:08 +0000 | [diff] [blame] | 32 | import org.junit.Ignore |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 33 | import org.junit.Rule |
| 34 | import org.junit.Test |
| 35 | import org.junit.runner.RunWith |
| 36 | import org.junit.runners.JUnit4 |
| 37 | |
| 38 | @MediumTest |
| 39 | @RunWith(JUnit4::class) |
| 40 | class DialogUiTest { |
| 41 | @get:Rule |
| 42 | val composeTestRule = createComposeRule(disableTransitions = true) |
| 43 | |
| 44 | private val defaultText = "dialogText" |
| 45 | |
| 46 | @Test |
| 47 | fun dialogTest_isShowingContent() { |
| 48 | composeTestRule.setContent { |
Leland Richardson | 7f848ab | 2019-12-12 13:43:41 -0800 | [diff] [blame] | 49 | val showDialog = state { true } |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 50 | |
| 51 | if (showDialog.value) { |
| 52 | Dialog(onCloseRequest = {}) { |
| 53 | Text(defaultText) |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 58 | onNodeWithText(defaultText).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | @Test |
Matvei Malkov | 28d8d5d | 2020-07-14 20:04:44 +0100 | [diff] [blame] | 62 | @FlakyTest(bugId = 159364185) |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 63 | fun dialogTest_isNotDismissed_whenClicked() { |
| 64 | val textBeforeClick = "textBeforeClick" |
| 65 | val textAfterClick = "textAfterClick" |
| 66 | |
| 67 | composeTestRule.setContent { |
Leland Richardson | 7f848ab | 2019-12-12 13:43:41 -0800 | [diff] [blame] | 68 | val showDialog = state { true } |
| 69 | val text = state { textBeforeClick } |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 70 | |
| 71 | if (showDialog.value) { |
| 72 | Dialog(onCloseRequest = { |
| 73 | showDialog.value = false |
| 74 | }) { |
Matvei Malkov | 323b745 | 2020-05-01 16:57:52 +0100 | [diff] [blame] | 75 | Text( |
| 76 | text = text.value, |
| 77 | modifier = Modifier.clickable { |
| 78 | text.value = textAfterClick |
| 79 | } |
| 80 | ) |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 81 | } |
| 82 | } |
| 83 | } |
| 84 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 85 | onNodeWithText(textBeforeClick) |
Filip Pavlis | 8b8a862 | 2020-02-13 16:32:04 +0000 | [diff] [blame] | 86 | .assertIsDisplayed() |
Ryan Mentley | 7865a63 | 2019-08-20 20:10:29 -0700 | [diff] [blame] | 87 | // Click inside the dialog |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 88 | .performClick() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 89 | |
Ryan Mentley | 7865a63 | 2019-08-20 20:10:29 -0700 | [diff] [blame] | 90 | // Check that the Clickable was pressed and that the Dialog is still visible, but with |
| 91 | // the new text |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 92 | onNodeWithText(textBeforeClick).assertDoesNotExist() |
| 93 | onNodeWithText(textAfterClick).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | @Test |
| 97 | fun dialogTest_isDismissed_whenSpecified() { |
| 98 | composeTestRule.setContent { |
Leland Richardson | 7f848ab | 2019-12-12 13:43:41 -0800 | [diff] [blame] | 99 | val showDialog = state { true } |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 100 | |
| 101 | if (showDialog.value) { |
| 102 | Dialog(onCloseRequest = { showDialog.value = false }) { |
| 103 | Text(defaultText) |
| 104 | } |
| 105 | } |
| 106 | } |
| 107 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 108 | onNodeWithText(defaultText).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 109 | |
| 110 | // Click outside the dialog to dismiss it |
| 111 | val outsideX = 0 |
| 112 | val outsideY = composeTestRule.displayMetrics.heightPixels / 2 |
| 113 | UiDevice.getInstance(getInstrumentation()).click(outsideX, outsideY) |
| 114 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 115 | onNodeWithText(defaultText).assertDoesNotExist() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 116 | } |
| 117 | |
| 118 | @Test |
| 119 | fun dialogTest_isNotDismissed_whenNotSpecified() { |
| 120 | composeTestRule.setContent { |
Leland Richardson | 7f848ab | 2019-12-12 13:43:41 -0800 | [diff] [blame] | 121 | val showDialog = state { true } |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 122 | |
| 123 | if (showDialog.value) { |
| 124 | Dialog(onCloseRequest = {}) { |
| 125 | Text(defaultText) |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 130 | onNodeWithText(defaultText).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 131 | |
| 132 | // Click outside the dialog to try to dismiss it |
| 133 | val outsideX = 0 |
| 134 | val outsideY = composeTestRule.displayMetrics.heightPixels / 2 |
| 135 | UiDevice.getInstance(getInstrumentation()).click(outsideX, outsideY) |
| 136 | |
| 137 | // The Dialog should still be visible |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 138 | onNodeWithText(defaultText).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 139 | } |
| 140 | |
| 141 | @Test |
| 142 | fun dialogTest_isDismissed_whenSpecified_backButtonPressed() { |
| 143 | composeTestRule.setContent { |
Leland Richardson | 7f848ab | 2019-12-12 13:43:41 -0800 | [diff] [blame] | 144 | val showDialog = state { true } |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 145 | |
| 146 | if (showDialog.value) { |
| 147 | Dialog(onCloseRequest = { showDialog.value = false }) { |
| 148 | Text(defaultText) |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 153 | onNodeWithText(defaultText).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 154 | |
| 155 | // Click the back button to dismiss the Dialog |
| 156 | UiDevice.getInstance(getInstrumentation()).pressBack() |
| 157 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 158 | onNodeWithText(defaultText).assertDoesNotExist() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 159 | } |
| 160 | |
Filip Pavlis | 2b161e4 | 2019-11-22 17:40:08 +0000 | [diff] [blame] | 161 | // TODO(pavlis): Espresso loses focus on the dialog after back press. That makes the |
| 162 | // subsequent query to fails. |
| 163 | @Ignore |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 164 | @Test |
| 165 | fun dialogTest_isNotDismissed_whenNotSpecified_backButtonPressed() { |
| 166 | composeTestRule.setContent { |
Leland Richardson | 7f848ab | 2019-12-12 13:43:41 -0800 | [diff] [blame] | 167 | val showDialog = state { true } |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 168 | |
| 169 | if (showDialog.value) { |
| 170 | Dialog(onCloseRequest = {}) { |
| 171 | Text(defaultText) |
| 172 | } |
| 173 | } |
| 174 | } |
| 175 | |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 176 | onNodeWithText(defaultText).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 177 | |
| 178 | // Click the back button to try to dismiss the dialog |
| 179 | UiDevice.getInstance(getInstrumentation()).pressBack() |
| 180 | |
| 181 | // The Dialog should still be visible |
Filip Pavlis | 659ea72 | 2020-07-13 14:14:32 +0100 | [diff] [blame] | 182 | onNodeWithText(defaultText).assertIsDisplayed() |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 183 | } |
Mihai Popa | b300d2c | 2020-06-23 16:25:50 +0100 | [diff] [blame] | 184 | |
| 185 | @Test |
| 186 | fun dialog_preservesAmbients() { |
| 187 | val ambient = ambientOf<Float>() |
| 188 | var value = 0f |
| 189 | composeTestRule.setContent { |
| 190 | Providers(ambient provides 1f) { |
| 191 | Dialog(onCloseRequest = {}) { |
| 192 | value = ambient.current |
| 193 | } |
| 194 | } |
| 195 | } |
Filip Pavlis | a4d73a5 | 2020-07-14 11:30:00 +0100 | [diff] [blame] | 196 | runOnIdle { |
Mihai Popa | b300d2c | 2020-06-23 16:25:50 +0100 | [diff] [blame] | 197 | assertEquals(1f, value) |
| 198 | } |
| 199 | } |
Mihai Burlaciuc | e882b3c | 2019-07-16 18:58:04 +0100 | [diff] [blame] | 200 | } |