Skip to content

Commit 5488bfd

Browse files
committed
Migrate DatePickerViewFactory to compose
1 parent a7c1b3a commit 5488bfd

File tree

12 files changed

+940
-527
lines changed

12 files changed

+940
-527
lines changed

datacapture/src/androidTest/java/com/google/android/fhir/datacapture/test/QuestionnaireUiEspressoTest.kt

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@ package com.google.android.fhir.datacapture.test
1919
import android.view.View
2020
import android.widget.FrameLayout
2121
import android.widget.TextView
22+
import androidx.compose.ui.semantics.SemanticsProperties
23+
import androidx.compose.ui.test.SemanticsMatcher
24+
import androidx.compose.ui.test.assert
2225
import androidx.compose.ui.test.assertIsDisplayed
2326
import androidx.compose.ui.test.assertTextEquals
27+
import androidx.compose.ui.test.hasAnyAncestor
28+
import androidx.compose.ui.test.hasText
29+
import androidx.compose.ui.test.isDialog
2430
import androidx.compose.ui.test.junit4.createEmptyComposeRule
2531
import androidx.compose.ui.test.onNodeWithContentDescription
2632
import androidx.compose.ui.test.onNodeWithTag
2733
import androidx.compose.ui.test.onNodeWithText
34+
import androidx.compose.ui.test.performClick
2835
import androidx.compose.ui.test.performTextInput
2936
import androidx.fragment.app.commitNow
3037
import androidx.recyclerview.widget.RecyclerView
@@ -35,30 +42,29 @@ import androidx.test.espresso.ViewAction
3542
import androidx.test.espresso.action.ViewActions
3643
import androidx.test.espresso.assertion.ViewAssertions
3744
import androidx.test.espresso.contrib.RecyclerViewActions
38-
import androidx.test.espresso.matcher.RootMatchers
3945
import androidx.test.espresso.matcher.ViewMatchers
4046
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
4147
import androidx.test.espresso.matcher.ViewMatchers.withId
4248
import androidx.test.espresso.matcher.ViewMatchers.withText
4349
import androidx.test.ext.junit.rules.ActivityScenarioRule
4450
import androidx.test.ext.junit.runners.AndroidJUnit4
45-
import androidx.test.filters.SdkSuppress
4651
import androidx.test.platform.app.InstrumentationRegistry
4752
import ca.uhn.fhir.context.FhirContext
4853
import ca.uhn.fhir.context.FhirVersionEnum
4954
import ca.uhn.fhir.parser.IParser
5055
import com.google.android.fhir.datacapture.QuestionnaireFragment
56+
import com.google.android.fhir.datacapture.R
57+
import com.google.android.fhir.datacapture.extensions.localDate
58+
import com.google.android.fhir.datacapture.extensions.localDateTime
5159
import com.google.android.fhir.datacapture.test.utilities.clickIcon
5260
import com.google.android.fhir.datacapture.test.utilities.clickOnText
5361
import com.google.android.fhir.datacapture.validation.Invalid
5462
import com.google.android.fhir.datacapture.validation.QuestionnaireResponseValidator
5563
import com.google.android.fhir.datacapture.validation.Valid
64+
import com.google.android.fhir.datacapture.views.compose.DATE_TEXT_INPUT_FIELD
5665
import com.google.android.fhir.datacapture.views.compose.EDIT_TEXT_FIELD_TEST_TAG
5766
import com.google.android.fhir.datacapture.views.compose.HANDLE_INPUT_DEBOUNCE_TIME
58-
import com.google.android.fhir.datacapture.views.factories.localDate
59-
import com.google.android.fhir.datacapture.views.factories.localDateTime
6067
import com.google.android.material.progressindicator.LinearProgressIndicator
61-
import com.google.android.material.textfield.TextInputEditText
6268
import com.google.android.material.textfield.TextInputLayout
6369
import com.google.common.truth.Truth.assertThat
6470
import java.math.BigDecimal
@@ -284,28 +290,25 @@ class QuestionnaireUiEspressoTest {
284290
buildFragmentFromQuestionnaire("/component_date_picker.json")
285291

286292
// Add month and day. No need to add slashes as they are added automatically
287-
onView(withId(R.id.text_input_edit_text))
288-
.perform(ViewActions.click())
289-
.perform(ViewActions.typeTextIntoFocusedView("0105"))
290-
291-
onView(withId(R.id.text_input_layout)).check { view, _ ->
292-
val actualError = (view as TextInputLayout).error
293-
assertThat(actualError).isEqualTo("Date format needs to be mm/dd/yyyy (e.g. 01/31/2023)")
294-
}
293+
composeTestRule.onNodeWithTag(DATE_TEXT_INPUT_FIELD).performTextInput("0105")
294+
composeTestRule
295+
.onNodeWithTag(DATE_TEXT_INPUT_FIELD)
296+
.assert(
297+
SemanticsMatcher.expectValue(
298+
SemanticsProperties.Error,
299+
"Date format needs to be mm/dd/yyyy (e.g. 01/31/2023)",
300+
),
301+
)
295302
}
296303

297304
@Test
298305
fun datePicker_shouldSaveInQuestionnaireResponseWhenCorrectDateEntered() {
299306
buildFragmentFromQuestionnaire("/component_date_picker.json")
300307

301-
onView(withId(R.id.text_input_edit_text))
302-
.perform(ViewActions.click())
303-
.perform(ViewActions.typeTextIntoFocusedView("01052005"))
304-
305-
onView(withId(R.id.text_input_layout)).check { view, _ ->
306-
val actualError = (view as TextInputLayout).error
307-
assertThat(actualError).isEqualTo(null)
308-
}
308+
composeTestRule.onNodeWithTag(DATE_TEXT_INPUT_FIELD).performTextInput("01052005")
309+
composeTestRule
310+
.onNodeWithTag(DATE_TEXT_INPUT_FIELD)
311+
.assert(SemanticsMatcher.keyNotDefined(SemanticsProperties.Error))
309312

310313
runBlocking {
311314
val answer = getQuestionnaireResponse().item.first().answer.first().valueDateType
@@ -337,11 +340,14 @@ class QuestionnaireUiEspressoTest {
337340
}
338341

339342
buildFragmentFromQuestionnaire(questionnaire)
340-
onView(withId(R.id.text_input_layout)).perform(clickIcon(true))
341-
onView(CoreMatchers.allOf(ViewMatchers.withText("OK")))
342-
.inRoot(RootMatchers.isDialog())
343-
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
344-
.perform(ViewActions.click())
343+
composeTestRule
344+
.onNodeWithContentDescription(context.getString(R.string.select_date))
345+
.performClick()
346+
composeTestRule
347+
.onNode(hasText("OK") and hasAnyAncestor(isDialog()))
348+
.assertIsDisplayed()
349+
.performClick()
350+
composeTestRule.waitForIdle() // Synchronize
345351

346352
val today = DateTimeType.today().valueAsString
347353

@@ -384,11 +390,14 @@ class QuestionnaireUiEspressoTest {
384390
}
385391

386392
buildFragmentFromQuestionnaire(questionnaire)
387-
onView(withId(R.id.text_input_layout)).perform(clickIcon(true))
388-
onView(CoreMatchers.allOf(ViewMatchers.withText("OK")))
389-
.inRoot(RootMatchers.isDialog())
390-
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
391-
.perform(ViewActions.click())
393+
composeTestRule
394+
.onNodeWithContentDescription(context.getString(R.string.select_date))
395+
.performClick()
396+
composeTestRule
397+
.onNode(hasText("OK") and hasAnyAncestor(isDialog()))
398+
.assertIsDisplayed()
399+
.performClick()
400+
composeTestRule.waitForIdle() // Synchronize
392401

393402
val maxDateAllowed = maxDate.valueAsString
394403

@@ -431,11 +440,14 @@ class QuestionnaireUiEspressoTest {
431440
}
432441

433442
buildFragmentFromQuestionnaire(questionnaire)
434-
onView(withId(R.id.text_input_layout)).perform(clickIcon(true))
435-
onView(CoreMatchers.allOf(ViewMatchers.withText("OK")))
436-
.inRoot(RootMatchers.isDialog())
437-
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
438-
.perform(ViewActions.click())
443+
composeTestRule
444+
.onNodeWithContentDescription(context.getString(R.string.select_date))
445+
.performClick()
446+
composeTestRule
447+
.onNode(hasText("OK") and hasAnyAncestor(isDialog()))
448+
.assertIsDisplayed()
449+
.performClick()
450+
composeTestRule.waitForIdle() // Synchronize
439451

440452
val minDateAllowed = minDate.valueAsString
441453

@@ -481,12 +493,14 @@ class QuestionnaireUiEspressoTest {
481493
buildFragmentFromQuestionnaire(questionnaire)
482494
val exception =
483495
Assert.assertThrows(IllegalArgumentException::class.java) {
484-
onView(withId(com.google.android.fhir.datacapture.R.id.text_input_layout))
485-
.perform(clickIcon(true))
486-
onView(CoreMatchers.allOf(ViewMatchers.withText("OK")))
487-
.inRoot(RootMatchers.isDialog())
488-
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
489-
.perform(ViewActions.click())
496+
composeTestRule
497+
.onNodeWithContentDescription(context.getString(R.string.select_date))
498+
.performClick()
499+
composeTestRule
500+
.onNode(hasText("OK") and hasAnyAncestor(isDialog()))
501+
.assertIsDisplayed()
502+
.performClick()
503+
composeTestRule.waitForIdle() // Synchronize
490504
}
491505
assertThat(exception.message).isEqualTo("minValue cannot be greater than maxValue")
492506
}
@@ -550,19 +564,21 @@ class QuestionnaireUiEspressoTest {
550564
}
551565

552566
@Test
553-
@SdkSuppress(minSdkVersion = 33)
554567
fun clearAllAnswers_shouldClearDraftAnswer() {
555568
val questionnaireFragment = buildFragmentFromQuestionnaire("/component_date_picker.json")
556569
// Add month and day. No need to add slashes as they are added automatically
557-
onView(withId(R.id.text_input_edit_text))
558-
.perform(ViewActions.click())
559-
.perform(ViewActions.typeTextIntoFocusedView("0105"))
570+
composeTestRule
571+
.onNodeWithTag(DATE_TEXT_INPUT_FIELD, useUnmergedTree = true)
572+
.performTextInput("0105")
573+
composeTestRule
574+
.onNodeWithTag(DATE_TEXT_INPUT_FIELD, useUnmergedTree = true)
575+
.assertTextEquals("01/05/")
560576

561577
questionnaireFragment.clearAllAnswers()
562578

563-
onView(withId(R.id.text_input_edit_text)).check { view, _ ->
564-
assertThat((view as TextInputEditText).text.toString()).isEmpty()
565-
}
579+
composeTestRule
580+
.onNodeWithTag(DATE_TEXT_INPUT_FIELD, useUnmergedTree = true)
581+
.assertTextEquals("")
566582
}
567583

568584
@Test
@@ -724,7 +740,7 @@ class QuestionnaireUiEspressoTest {
724740
activityScenarioRule.scenario.onActivity { activity ->
725741
activity.supportFragmentManager.commitNow {
726742
setReorderingAllowed(true)
727-
add(R.id.container_holder, fragment)
743+
add(com.google.android.fhir.datacapture.test.R.id.container_holder, fragment)
728744
}
729745
}
730746
}
@@ -742,7 +758,7 @@ class QuestionnaireUiEspressoTest {
742758
activityScenarioRule.scenario.onActivity { activity ->
743759
activity.supportFragmentManager.commitNow {
744760
setReorderingAllowed(true)
745-
add(R.id.container_holder, questionnaireFragment)
761+
add(com.google.android.fhir.datacapture.test.R.id.container_holder, questionnaireFragment)
746762
}
747763
}
748764
}
@@ -754,8 +770,9 @@ class QuestionnaireUiEspressoTest {
754770
var testQuestionnaireFragment: QuestionnaireFragment? = null
755771
activityScenarioRule.scenario.onActivity { activity ->
756772
testQuestionnaireFragment =
757-
activity.supportFragmentManager.findFragmentById(R.id.container_holder)
758-
as QuestionnaireFragment
773+
activity.supportFragmentManager.findFragmentById(
774+
com.google.android.fhir.datacapture.test.R.id.container_holder,
775+
) as QuestionnaireFragment
759776
}
760777
return testQuestionnaireFragment!!.getQuestionnaireResponse()
761778
}

0 commit comments

Comments
 (0)