@@ -5,21 +5,15 @@ import android.content.res.Resources
55import androidx.annotation.StringRes
66import androidx.compose.ui.semantics.Role
77import androidx.compose.ui.semantics.SemanticsProperties
8- import androidx.compose.ui.test.SemanticsMatcher
9- import androidx.compose.ui.test.assertIsDisplayed
10- import androidx.compose.ui.test.hasContentDescription
11- import androidx.compose.ui.test.hasSetTextAction
12- import androidx.compose.ui.test.hasTextExactly
8+ import androidx.compose.ui.test.*
9+ import androidx.compose.ui.test.junit4.ComposeContentTestRule
1310import androidx.compose.ui.test.junit4.createAndroidComposeRule
14- import androidx.compose.ui.test.onNodeWithText
15- import androidx.compose.ui.test.performClick
16- import androidx.compose.ui.test.performTextClearance
17- import androidx.compose.ui.test.performTextInput
1811import androidx.test.core.app.ApplicationProvider
1912import androidx.test.rule.GrantPermissionRule
2013import kotlinx.coroutines.test.runTest
2114import org.junit.Rule
2215import org.junit.Test
16+ import kotlin.time.Duration
2317import kotlin.time.Duration.Companion.seconds
2418
2519
@@ -50,74 +44,21 @@ class SmokeTestUiTest {
5044 onNodeWithText(str(R .string.intro_next)).performClick()
5145 onNodeWithText(str(R .string.pin_creation_title)).assertIsDisplayed()
5246
53- onNode(
54- hasSetTextAction() and hasTextExactly(
55- str(R .string.pin_creation_hint),
56- includeEditableText = false
57- )
58- ).performTextInput(" 3133734" )
59-
60- onNode(
61- hasSetTextAction() and hasTextExactly(
62- str(R .string.pin_creation_confirm_hint),
63- includeEditableText = false
64- )
65- ).performTextInput(" 313373" )
66-
47+ setPinFields(" 3133734" , " 313373" )
6748 onNodeWithText(str(R .string.pin_creation_button)).performClick()
49+ waitForText(R .string.pin_creation_error)
6850
69- onNodeWithText(str(R .string.pin_creation_error)).assertIsDisplayed()
70-
71- onNode(
72- hasSetTextAction() and hasTextExactly(
73- str(R .string.pin_creation_hint),
74- includeEditableText = false
75- )
76- ).apply {
77- performTextClearance()
78- performTextInput(" 123456" )
79- }
80-
81- onNode(
82- hasSetTextAction() and hasTextExactly(
83- str(R .string.pin_creation_confirm_hint),
84- includeEditableText = false
85- )
86- ).apply {
87- performTextClearance()
88- performTextInput(" 123456" )
89- }
90-
51+ setPinFields(" 123456" , " 123456" )
9152 onNodeWithText(str(R .string.pin_creation_button)).performClick()
53+ waitForText(R .string.pin_creation_error_weak_pin)
9254
93- onNodeWithText(str(R .string.pin_creation_error_weak_pin)).assertIsDisplayed()
94-
95- onNode(
96- hasSetTextAction() and hasTextExactly(
97- str(R .string.pin_creation_hint),
98- includeEditableText = false
99- )
100- ).apply {
101- performTextClearance()
102- performTextInput(" 313373" )
103- }
104-
105- onNode(
106- hasSetTextAction() and hasTextExactly(
107- str(R .string.pin_creation_confirm_hint),
108- includeEditableText = false
109- )
110- ).apply {
111- performTextClearance()
112- performTextInput(" 313373" )
113- }
114-
55+ setPinFields(" 313373" , " 313373" )
11556 onNodeWithText(str(R .string.pin_creation_button)).performClick()
11657
117- onNodeWithText(str( R .string.pin_creating_vault)).assertIsDisplayed( )
58+ waitForText( R .string.pin_creating_vault)
11859
11960 composeTestRule.waitUntil(
120- timeoutMillis = 10 .seconds.inWholeMilliseconds
61+ timeoutMillis = 30 .seconds.inWholeMilliseconds
12162 ) {
12263 composeTestRule
12364 .onAllNodes(hasRole(Role .Button ) and hasContentDescription(str(R .string.camera_shutter_button_desc)))
@@ -130,13 +71,57 @@ class SmokeTestUiTest {
13071 }
13172 }
13273
74+ private fun ComposeContentTestRule.setPinFields (primary : String , confirm : String ) {
75+ setTextField(
76+ placeholder = R .string.pin_creation_hint,
77+ value = primary,
78+ )
79+
80+ setTextField(
81+ placeholder = R .string.pin_creation_confirm_hint,
82+ value = confirm,
83+ )
84+ }
85+
13386 fun hasRole (role : Role ): SemanticsMatcher =
13487 SemanticsMatcher .expectValue(SemanticsProperties .Role , role)
13588
13689 private fun str (@StringRes id : Int ): String = r.getString(id)
13790 private val r: Resources
13891 get() {
139- val application = ApplicationProvider .getApplicationContext<Application ? >()
92+ val application = ApplicationProvider .getApplicationContext<Application >()
14093 return application.resources
14194 }
95+
96+ private fun ComposeContentTestRule.waitForText (@StringRes text : Int , timeout : Duration = 10.seconds) {
97+ waitForText(str(text), timeout)
98+ }
99+
100+ fun ComposeContentTestRule.waitForText (
101+ text : String ,
102+ timeout : Duration = 10.seconds,
103+ useUnmergedTree : Boolean = true,
104+ substring : Boolean = true
105+ ) {
106+ waitUntil(timeout.inWholeMilliseconds) {
107+ onAllNodes(
108+ hasText(text, substring = substring),
109+ useUnmergedTree = useUnmergedTree
110+ ).fetchSemanticsNodes().isNotEmpty()
111+ }
112+ onNodeWithText(text, substring = substring)
113+ .assertIsDisplayed()
114+ }
115+
116+ private fun ComposeContentTestRule.setTextField (value : String , placeholder : Int ) {
117+ onNode(
118+ hasSetTextAction() and hasTextExactly(
119+ str(placeholder),
120+ includeEditableText = false
121+ )
122+ ).apply {
123+ performTextClearance()
124+ performTextInput(value)
125+ }
126+ }
142127}
0 commit comments