@@ -5,21 +5,14 @@ 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
20- import kotlinx.coroutines.test.runTest
2113import org.junit.Rule
2214import org.junit.Test
15+ import kotlin.time.Duration
2316import kotlin.time.Duration.Companion.seconds
2417
2518
@@ -36,7 +29,7 @@ class SmokeTestUiTest {
3629 val composeTestRule = createAndroidComposeRule<MainActivity >()
3730
3831 @Test
39- fun smokeTest () = runTest {
32+ fun smokeTest () {
4033 composeTestRule.apply {
4134 onNodeWithText(str(R .string.intro_next)).performClick()
4235 onNodeWithText(str(R .string.intro_slide1_title)).assertIsDisplayed()
@@ -50,74 +43,21 @@ class SmokeTestUiTest {
5043 onNodeWithText(str(R .string.intro_next)).performClick()
5144 onNodeWithText(str(R .string.pin_creation_title)).assertIsDisplayed()
5245
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-
46+ setPinFields(" 3133734" , " 313373" )
6747 onNodeWithText(str(R .string.pin_creation_button)).performClick()
48+ waitForText(R .string.pin_creation_error)
6849
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-
50+ setPinFields(" 123456" , " 123456" )
9151 onNodeWithText(str(R .string.pin_creation_button)).performClick()
52+ waitForText(R .string.pin_creation_error_weak_pin)
9253
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-
54+ setPinFields(" 313373" , " 313373" )
11555 onNodeWithText(str(R .string.pin_creation_button)).performClick()
11656
117- onNodeWithText(str( R .string.pin_creating_vault)).assertIsDisplayed( )
57+ waitForText( R .string.pin_creating_vault)
11858
11959 composeTestRule.waitUntil(
120- timeoutMillis = 10 .seconds.inWholeMilliseconds
60+ timeoutMillis = 30 .seconds.inWholeMilliseconds
12161 ) {
12262 composeTestRule
12363 .onAllNodes(hasRole(Role .Button ) and hasContentDescription(str(R .string.camera_shutter_button_desc)))
@@ -130,13 +70,57 @@ class SmokeTestUiTest {
13070 }
13171 }
13272
73+ private fun ComposeContentTestRule.setPinFields (primary : String , confirm : String ) {
74+ setTextField(
75+ placeholder = R .string.pin_creation_hint,
76+ value = primary,
77+ )
78+
79+ setTextField(
80+ placeholder = R .string.pin_creation_confirm_hint,
81+ value = confirm,
82+ )
83+ }
84+
13385 fun hasRole (role : Role ): SemanticsMatcher =
13486 SemanticsMatcher .expectValue(SemanticsProperties .Role , role)
13587
13688 private fun str (@StringRes id : Int ): String = r.getString(id)
13789 private val r: Resources
13890 get() {
139- val application = ApplicationProvider .getApplicationContext<Application ? >()
91+ val application = ApplicationProvider .getApplicationContext<Application >()
14092 return application.resources
14193 }
94+
95+ private fun ComposeContentTestRule.waitForText (@StringRes text : Int , timeout : Duration = 10.seconds) {
96+ waitForText(str(text), timeout)
97+ }
98+
99+ fun ComposeContentTestRule.waitForText (
100+ text : String ,
101+ timeout : Duration = 10.seconds,
102+ useUnmergedTree : Boolean = true,
103+ substring : Boolean = true
104+ ) {
105+ waitUntil(timeout.inWholeMilliseconds) {
106+ onAllNodes(
107+ hasText(text, substring = substring),
108+ useUnmergedTree = useUnmergedTree
109+ ).fetchSemanticsNodes().isNotEmpty()
110+ }
111+ onNodeWithText(text, substring = substring)
112+ .assertIsDisplayed()
113+ }
114+
115+ private fun ComposeContentTestRule.setTextField (value : String , placeholder : Int ) {
116+ onNode(
117+ hasSetTextAction() and hasTextExactly(
118+ str(placeholder),
119+ includeEditableText = false
120+ )
121+ ).apply {
122+ performTextClearance()
123+ performTextInput(value)
124+ }
125+ }
142126}
0 commit comments