Skip to content

Commit 8d31f4b

Browse files
committed
Migrate AutoCompleteTextViewFactory to compose
1 parent 6f0ce2c commit 8d31f4b

File tree

5 files changed

+437
-141
lines changed

5 files changed

+437
-141
lines changed
Lines changed: 50 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 Google LLC
2+
* Copyright 2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,26 +14,30 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.android.fhir.datacapture.views.factories
17+
package com.google.android.fhir.datacapture.test.views
1818

19-
import android.view.View
20-
import android.widget.AutoCompleteTextView
2119
import android.widget.FrameLayout
22-
import android.widget.TextView
23-
import androidx.test.espresso.Espresso.onView
24-
import androidx.test.espresso.action.ViewActions
25-
import androidx.test.espresso.assertion.ViewAssertions
26-
import androidx.test.espresso.matcher.RootMatchers
27-
import androidx.test.espresso.matcher.ViewMatchers
20+
import androidx.compose.ui.test.assertCountEquals
21+
import androidx.compose.ui.test.assertIsDisplayed
22+
import androidx.compose.ui.test.assertTextEquals
23+
import androidx.compose.ui.test.hasAnyAncestor
24+
import androidx.compose.ui.test.hasTestTag
25+
import androidx.compose.ui.test.hasTextExactly
26+
import androidx.compose.ui.test.isPopup
27+
import androidx.compose.ui.test.junit4.createEmptyComposeRule
28+
import androidx.compose.ui.test.onNodeWithTag
29+
import androidx.compose.ui.test.performClick
30+
import androidx.compose.ui.test.performTextReplacement
2831
import androidx.test.ext.junit.rules.ActivityScenarioRule
2932
import androidx.test.platform.app.InstrumentationRegistry
30-
import com.google.android.fhir.datacapture.R
3133
import com.google.android.fhir.datacapture.test.TestActivity
32-
import com.google.android.fhir.datacapture.test.utilities.delayMainThread
3334
import com.google.android.fhir.datacapture.validation.NotValidated
3435
import com.google.android.fhir.datacapture.views.QuestionnaireViewItem
35-
import com.google.android.material.chip.ChipGroup
36-
import com.google.android.material.textfield.MaterialAutoCompleteTextView
36+
import com.google.android.fhir.datacapture.views.compose.DROP_DOWN_ANSWER_MENU_ITEM_TAG
37+
import com.google.android.fhir.datacapture.views.compose.MULTI_AUTO_COMPLETE_INPUT_CHIP_TAG
38+
import com.google.android.fhir.datacapture.views.compose.MULTI_AUTO_COMPLETE_TEXT_FIELD_TAG
39+
import com.google.android.fhir.datacapture.views.factories.AutoCompleteViewHolderFactory
40+
import com.google.android.fhir.datacapture.views.factories.QuestionnaireItemViewHolder
3741
import com.google.common.truth.Truth.assertThat
3842
import org.hl7.fhir.r4.model.Coding
3943
import org.hl7.fhir.r4.model.Questionnaire
@@ -43,19 +47,22 @@ import org.junit.Rule
4347
import org.junit.Test
4448

4549
class AutoCompleteViewHolderFactoryEspressoTest {
46-
@Rule
47-
@JvmField
50+
@get:Rule
4851
var activityScenarioRule: ActivityScenarioRule<TestActivity> =
4952
ActivityScenarioRule(TestActivity::class.java)
5053

51-
private lateinit var parent: FrameLayout
54+
@get:Rule val composeTestRule = createEmptyComposeRule()
55+
5256
private lateinit var viewHolder: QuestionnaireItemViewHolder
5357

5458
@Before
5559
fun setup() {
56-
activityScenarioRule.scenario.onActivity { activity -> parent = FrameLayout(activity) }
57-
viewHolder = AutoCompleteViewHolderFactory.create(parent)
58-
setTestLayout(viewHolder.itemView)
60+
activityScenarioRule.scenario.onActivity { activity ->
61+
viewHolder = AutoCompleteViewHolderFactory.create(FrameLayout(activity))
62+
activity.setContentView(viewHolder.itemView)
63+
}
64+
65+
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
5966
}
6067

6168
@Test
@@ -67,16 +74,11 @@ class AutoCompleteViewHolderFactoryEspressoTest {
6774
validationResult = NotValidated,
6875
answersChangedCallback = { _, _, _, _ -> },
6976
)
70-
runOnUI { viewHolder.bind(questionnaireViewItem) }
71-
72-
onView(ViewMatchers.withId(R.id.autoCompleteTextView)).perform(ViewActions.typeText("Coding 1"))
73-
assertThat(
74-
viewHolder.itemView
75-
.findViewById<MaterialAutoCompleteTextView>(R.id.autoCompleteTextView)
76-
.adapter
77-
.count,
78-
)
79-
.isEqualTo(1)
77+
viewHolder.bind(questionnaireViewItem)
78+
composeTestRule
79+
.onNodeWithTag(MULTI_AUTO_COMPLETE_TEXT_FIELD_TAG)
80+
.performTextReplacement("Coding 1")
81+
composeTestRule.onAllNodes(hasTestTag(DROP_DOWN_ANSWER_MENU_ITEM_TAG)).assertCountEquals(1)
8082
}
8183

8284
@Test
@@ -89,23 +91,24 @@ class AutoCompleteViewHolderFactoryEspressoTest {
8991
validationResult = NotValidated,
9092
answersChangedCallback = { _, _, answers, _ -> answerHolder = answers },
9193
)
92-
runOnUI { viewHolder.bind(questionnaireViewItem) }
94+
viewHolder.bind(questionnaireViewItem)
9395

94-
onView(ViewMatchers.withId(R.id.autoCompleteTextView)).perform(ViewActions.typeText("Coding 3"))
95-
runOnUI {
96-
viewHolder.itemView
97-
.findViewById<AutoCompleteTextView>(R.id.autoCompleteTextView)
98-
.showDropDown()
99-
}
100-
onView(ViewMatchers.withId(R.id.autoCompleteTextView)).perform(delayMainThread())
101-
onView(ViewMatchers.withText("Coding 3"))
102-
.inRoot(RootMatchers.isPlatformPopup())
103-
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
104-
.perform(ViewActions.click())
105-
assertThat(
106-
viewHolder.itemView.findViewById<TextView>(R.id.autoCompleteTextView).text.toString(),
96+
composeTestRule
97+
.onNodeWithTag(MULTI_AUTO_COMPLETE_TEXT_FIELD_TAG)
98+
.performTextReplacement("Coding 3")
99+
100+
composeTestRule
101+
.onNode(
102+
hasTestTag(DROP_DOWN_ANSWER_MENU_ITEM_TAG) and
103+
hasTextExactly("Coding 3") and
104+
hasAnyAncestor(isPopup()),
107105
)
108-
.isEmpty()
106+
.assertIsDisplayed()
107+
.performClick()
108+
109+
composeTestRule.onNodeWithTag(MULTI_AUTO_COMPLETE_TEXT_FIELD_TAG).assertTextEquals("")
110+
111+
composeTestRule.waitUntil { answerHolder != null }
109112
assertThat(answerHolder!!.map { it.valueCoding.display })
110113
.containsExactly("Coding 1", "Coding 5", "Coding 3")
111114
}
@@ -119,21 +122,8 @@ class AutoCompleteViewHolderFactoryEspressoTest {
119122
validationResult = NotValidated,
120123
answersChangedCallback = { _, _, _, _ -> },
121124
)
122-
runOnUI { viewHolder.bind(questionnaireViewItem) }
123-
124-
assertThat(viewHolder.itemView.findViewById<ChipGroup>(R.id.chipContainer).childCount)
125-
.isEqualTo(2)
126-
}
127-
128-
/** Method to run code snippet on UI/main thread */
129-
private fun runOnUI(action: () -> Unit) {
130-
activityScenarioRule.scenario.onActivity { action() }
131-
}
132-
133-
/** Method to set content view for test activity */
134-
private fun setTestLayout(view: View) {
135-
activityScenarioRule.scenario.onActivity { activity -> activity.setContentView(view) }
136-
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
125+
viewHolder.bind(questionnaireViewItem)
126+
composeTestRule.onAllNodes(hasTestTag(MULTI_AUTO_COMPLETE_INPUT_CHIP_TAG)).assertCountEquals(2)
137127
}
138128

139129
private fun answerOptions(repeats: Boolean, vararg options: String) =

0 commit comments

Comments
 (0)