From e5cd69de281ea9bb403d11935d82439c05046b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Miguel=20Rubio?= Date: Sun, 10 Mar 2024 18:36:58 +0100 Subject: [PATCH] Update SearchTETest (#3525) * Update SearchTETest with lazyActivityScenario and composeTestRule * fix shouldShowErrorWhenSyncEventFails * revert Jenkinsfile changes * shouldShowErrorWhenSyncEventFails click on event item --- .../org/dhis2/usescases/event/EventTest.kt | 22 +- .../org/dhis2/usescases/filters/FilterTest.kt | 50 ++-- .../flow/searchFlow/SearchFlowTest.kt | 11 +- .../usescases/flow/syncFlow/SyncFlowTest.kt | 68 +++-- .../usescases/flow/syncFlow/SyncIntents.kt | 29 +- .../robot/EventWithoutRegistrationRobot.kt | 44 +--- .../flow/syncFlow/robot/SyncFlowRobot.kt | 28 +- .../usescases/flow/teiFlow/TeiFlowRobot.kt | 55 ++-- .../usescases/flow/teiFlow/TeiFlowTest.kt | 18 +- .../programevent/ProgramEventTest.kt | 18 +- .../usescases/searchte/SearchTEIntents.kt | 24 +- .../dhis2/usescases/searchte/SearchTETest.kt | 67 +++-- .../searchte/robot/SearchTeiRobot.kt | 68 +---- .../teidashboard/TeiDashboardIntents.kt | 127 ++++++--- .../TeiDashboardMobileActivityTest.kt | 9 +- .../teidashboard/TeiDashboardTest.kt | 87 +++--- .../TeiDashboardTestNoComposable.kt | 10 +- .../teidashboard/robot/EventRobot.kt | 53 ++-- .../teidashboard/robot/TeiDashboardRobot.kt | 249 ++++++++++-------- .../ProgramEventDetailLiveAdapter.kt | 6 +- 20 files changed, 533 insertions(+), 510 deletions(-) diff --git a/app/src/androidTest/java/org/dhis2/usescases/event/EventTest.kt b/app/src/androidTest/java/org/dhis2/usescases/event/EventTest.kt index 999613820e..e67454ee8b 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/event/EventTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/event/EventTest.kt @@ -48,8 +48,8 @@ class EventTest : BaseTest() { prepareEventToDeleteIntentAndLaunchActivity(ruleTeiDashboard) - teiDashboardRobot { - clickOnEventGroupByStageUsingDate(composeTestRule, tbVisitDate) + teiDashboardRobot(composeTestRule) { + clickOnEventGroupByStageUsingDate(tbVisitDate) } eventRegistrationRobot { @@ -58,7 +58,7 @@ class EventTest : BaseTest() { clickOnDeleteDialog() } - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { checkEventWasDeletedStageGroup(tbProgramStages) } } @@ -98,19 +98,19 @@ class EventTest : BaseTest() { prepareEventToUpdateIntentAndLaunchActivity(ruleTeiDashboard) - teiDashboardRobot { - clickOnStageGroup(composeTestRule, labMonitoring) + teiDashboardRobot(composeTestRule) { + clickOnStageGroup(labMonitoring) clickOnEventGroupByStage(eventDate) } - eventRobot { + eventRobot(composeTestRule) { fillRadioButtonForm(radioFormLength) clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() } - teiDashboardRobot { - clickOnStageGroup(composeTestRule, labMonitoring) + teiDashboardRobot(composeTestRule) { + clickOnStageGroup(labMonitoring) checkEventStateStageGroup(labMonitoringStatus) } } @@ -129,10 +129,10 @@ class EventTest : BaseTest() { eventRegistrationRobot { clickNextButton() } - eventRobot { + eventRobot(composeTestRule) { typeOnRequiredEventForm("125", 1) clickOnFormFabButton() - checkSecondaryButtonNotVisible(composeTestRule) + checkSecondaryButtonNotVisible() } } diff --git a/app/src/androidTest/java/org/dhis2/usescases/filters/FilterTest.kt b/app/src/androidTest/java/org/dhis2/usescases/filters/FilterTest.kt index 6826737ec6..2e39037ab7 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/filters/FilterTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/filters/FilterTest.kt @@ -16,7 +16,7 @@ import org.junit.Ignore import org.junit.Rule import org.junit.Test -class FilterTest: BaseTest() { +class FilterTest : BaseTest() { @get:Rule val rule = ActivityTestRule(MainActivity::class.java, false, false) @@ -37,16 +37,16 @@ class FilterTest: BaseTest() { filterRobotCommon { openFilterAtPosition(0) clickOnFromToDateOption() - selectDate(2020,6,15) + selectDate(2020, 6, 15) acceptDateSelected() - selectDate(2020,11,7) + selectDate(2020, 11, 7) acceptDateSelected() } homeRobot { openFilters() - checkItemsInProgram(composeTestRule,3,"Child Programme", "3") - checkItemsInProgram(composeTestRule,5, "Contraceptives Voucher Program", "5") - checkItemsInProgram(composeTestRule,26, "Mortality < 5 years", "4") + checkItemsInProgram(composeTestRule, 3, "Child Programme", "3") + checkItemsInProgram(composeTestRule, 5, "Contraceptives Voucher Program", "5") + checkItemsInProgram(composeTestRule, 26, "Mortality < 5 years", "4") } cleanLocalDatabase() } @@ -68,15 +68,15 @@ class FilterTest: BaseTest() { } homeRobot { openFilters() - checkItemsInProgram(composeTestRule,3,"Child Programme", "0") - checkItemsInProgram(composeTestRule,41, "XX TEST EVENT FULL", "2") - checkItemsInProgram(composeTestRule,43, "XX TEST TRACKER PROGRAM", "4") + checkItemsInProgram(composeTestRule, 3, "Child Programme", "0") + checkItemsInProgram(composeTestRule, 41, "XX TEST EVENT FULL", "2") + checkItemsInProgram(composeTestRule, 43, "XX TEST TRACKER PROGRAM", "4") } cleanLocalDatabase() } @Test - fun checkTreeOrgUnitFilter(){ + fun checkTreeOrgUnitFilter() { startActivity() setupCredentials() @@ -87,15 +87,15 @@ class FilterTest: BaseTest() { filterRobotCommon { openFilterAtPosition(1) clickOnOrgUnitTree() - orgUnitSelectorRobot(composeTestRule){ + orgUnitSelectorRobot(composeTestRule) { selectTreeOrgUnit("OU TEST PARENT") } } homeRobot { openFilters() - checkItemsInProgram(composeTestRule,3,"Child Programme", "0") - checkItemsInProgram(composeTestRule,41, "XX TEST EVENT FULL", "2") - checkItemsInProgram(composeTestRule,43, "XX TEST TRACKER PROGRAM", "4") + checkItemsInProgram(composeTestRule, 3, "Child Programme", "0") + checkItemsInProgram(composeTestRule, 41, "XX TEST EVENT FULL", "2") + checkItemsInProgram(composeTestRule, 43, "XX TEST TRACKER PROGRAM", "4") } cleanLocalDatabase() } @@ -106,15 +106,15 @@ class FilterTest: BaseTest() { startActivity() homeRobot { - openProgramByPosition(composeTestRule,0) + openProgramByPosition(composeTestRule, 0) waitToDebounce(700) } - eventWithoutRegistrationRobot { + eventWithoutRegistrationRobot(composeTestRule) { clickOnEventAtPosition(0) } - eventRobot { + eventRobot(composeTestRule) { clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() pressBack() } homeRobot { @@ -126,8 +126,8 @@ class FilterTest: BaseTest() { } homeRobot { openFilters() - checkItemsInProgram(composeTestRule,0,"Antenatal care visit", "1") - checkItemsInProgram(composeTestRule,3,"Child Programme", "0") + checkItemsInProgram(composeTestRule, 0, "Antenatal care visit", "1") + checkItemsInProgram(composeTestRule, 3, "Child Programme", "0") } cleanLocalDatabase() } @@ -139,13 +139,13 @@ class FilterTest: BaseTest() { startActivity() homeRobot { - openProgramByPosition(composeTestRule,41) + openProgramByPosition(composeTestRule, 41) } - eventWithoutRegistrationRobot { + eventWithoutRegistrationRobot(composeTestRule) { clickOnEventAtPosition(0) } formRobot { - clickOnSelectOption("ZZ TEST RULE ACTIONS A", 1,"Hide Field", 1) + clickOnSelectOption("ZZ TEST RULE ACTIONS A", 1, "Hide Field", 1) pressBack() pressBack() pressBack() @@ -164,9 +164,9 @@ class FilterTest: BaseTest() { } homeRobot { openFilters() - checkItemsInProgram(composeTestRule,37,"TB program", "0") + checkItemsInProgram(composeTestRule, 37, "TB program", "0") waitToDebounce(700) - checkItemsInProgram(composeTestRule,41, "XX TEST EVENT FULL", "1") + checkItemsInProgram(composeTestRule, 41, "XX TEST EVENT FULL", "1") waitToDebounce(700) } cleanLocalDatabase() diff --git a/app/src/androidTest/java/org/dhis2/usescases/flow/searchFlow/SearchFlowTest.kt b/app/src/androidTest/java/org/dhis2/usescases/flow/searchFlow/SearchFlowTest.kt index 5e82eddb97..2807eded53 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/flow/searchFlow/SearchFlowTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/flow/searchFlow/SearchFlowTest.kt @@ -1,9 +1,9 @@ package org.dhis2.usescases.flow.searchFlow import android.content.Intent +import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.intl.Locale -import androidx.compose.ui.test.junit4.createComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.ActivityTestRule import org.dhis2.R @@ -33,13 +33,16 @@ class SearchFlowTest : BaseTest() { setDatePicker() val registerTEIDetails = createRegisterTEI() val enrollmentStatus = context.getString(R.string.filters_title_enrollment_status) - .format(context.resources.getQuantityString(R.plurals.enrollment, 1).capitalize(Locale.current)) + .format( + context.resources.getQuantityString(R.plurals.enrollment, 1) + .capitalize(Locale.current) + ) val filterCounter = "1" val filterTotalCount = "2" prepareWomanProgrammeIntentAndLaunchActivity(rule) - teiFlowRobot { - registerTEI(registerTEIDetails, composeTestRule) + teiFlowRobot(composeTestRule) { + registerTEI(registerTEIDetails) pressBack() } diff --git a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncFlowTest.kt b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncFlowTest.kt index ab6a619359..f21aae06a0 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncFlowTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncFlowTest.kt @@ -6,10 +6,10 @@ import androidx.compose.ui.test.performClick import androidx.lifecycle.MutableLiveData import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.rule.ActivityTestRule import androidx.work.Data import androidx.work.WorkInfo import org.dhis2.AppTest +import org.dhis2.lazyActivityScenarioRule import org.dhis2.usescases.BaseTest import org.dhis2.usescases.datasets.dataSetTableRobot import org.dhis2.usescases.datasets.datasetDetail.DataSetDetailActivity @@ -31,14 +31,14 @@ import java.util.UUID class SyncFlowTest : BaseTest() { @get:Rule - val ruleDataSet = ActivityTestRule(DataSetDetailActivity::class.java, false, false) + val ruleDataSet = lazyActivityScenarioRule(launchActivity = false) @get:Rule - val ruleSearch = ActivityTestRule(SearchTEActivity::class.java, false, false) + val ruleSearch = lazyActivityScenarioRule(launchActivity = false) @get:Rule val ruleEventWithoutRegistration = - ActivityTestRule(ProgramEventDetailActivity::class.java, false, false) + lazyActivityScenarioRule(launchActivity = false) @get:Rule val composeTestRule = createComposeRule() @@ -68,26 +68,26 @@ class SyncFlowTest : BaseTest() { clickOnTEI(teiName, teiLastName) } - teiDashboardRobot { - clickOnEventWith(composeTestRule, LAB_MONITORING_EVENT_DATE) + teiDashboardRobot(composeTestRule) { + clickOnEventWith(LAB_MONITORING_EVENT_DATE) } - eventRobot { + eventRobot(composeTestRule) { fillRadioButtonForm(4) clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() } - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { composeTestRule.onNodeWithText("Sync").performClick() } - syncFlowRobot { + syncFlowRobot(composeTestRule) { waitToDebounce(500) - clickOnSyncButton(composeTestRule) + clickOnSyncButton() workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.RUNNING))) workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.FAILED))) - checkSyncFailed(composeTestRule) + checkSyncFailed() } cleanLocalDatabase() } @@ -97,21 +97,21 @@ class SyncFlowTest : BaseTest() { fun shouldSuccessfullySyncSavedEvent() { prepareMalariaEventIntentAndLaunchActivity(ruleEventWithoutRegistration) - eventWithoutRegistrationRobot { + eventWithoutRegistrationRobot(composeTestRule) { clickOnEventAtPosition(0) } - eventRobot { + eventRobot(composeTestRule) { clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() } - syncFlowRobot { - clickOnEventToSync(0) - clickOnSyncButton(composeTestRule) + syncFlowRobot(composeTestRule) { + clickOnEventToSync() + clickOnSyncButton() workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.RUNNING))) workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.SUCCEEDED))) - checkSyncWasSuccessfully(composeTestRule) + checkSyncWasSuccessfully() } cleanLocalDatabase() } @@ -120,21 +120,21 @@ class SyncFlowTest : BaseTest() { fun shouldShowErrorWhenSyncEventFails() { prepareMalariaEventIntentAndLaunchActivity(ruleEventWithoutRegistration) - eventWithoutRegistrationRobot { + eventWithoutRegistrationRobot(composeTestRule) { clickOnEventAtPosition(1) } - eventRobot { + eventRobot(composeTestRule) { clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() } - syncFlowRobot { - clickOnEventToSync(1) - clickOnSyncButton(composeTestRule) + syncFlowRobot(composeTestRule) { + clickOnEventToSync() + clickOnSyncButton() workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.RUNNING))) workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.FAILED))) - checkSyncFailed(composeTestRule) + checkSyncFailed() } cleanLocalDatabase() } @@ -162,12 +162,12 @@ class SyncFlowTest : BaseTest() { clickOnNegativeButton() } - syncFlowRobot { + syncFlowRobot(composeTestRule) { clickOnDataSetToSync(0) - clickOnSyncButton(composeTestRule) + clickOnSyncButton() workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.RUNNING))) workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.SUCCEEDED))) - checkSyncWasSuccessfully(composeTestRule) //sync failed + checkSyncWasSuccessfully() //sync failed } cleanLocalDatabase() } @@ -195,12 +195,12 @@ class SyncFlowTest : BaseTest() { clickOnNegativeButton() } - syncFlowRobot { + syncFlowRobot(composeTestRule) { clickOnDataSetToSync(1) - clickOnSyncButton(composeTestRule) + clickOnSyncButton() workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.RUNNING))) workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.FAILED))) - checkSyncFailed(composeTestRule) + checkSyncFailed() } cleanLocalDatabase() } @@ -218,10 +218,6 @@ class SyncFlowTest : BaseTest() { } companion object { - const val ORG_UNIT = "Ngelehun CHC" - const val TB_VISIT = "TB visit" - const val TB_VISIT_EVENT_DATE = "3/7/2019" - const val LAB_MONITORING = "Lab monitoring" const val LAB_MONITORING_EVENT_DATE = "28/6/2020" } } \ No newline at end of file diff --git a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncIntents.kt b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncIntents.kt index b0f3019c14..83b391ceb4 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncIntents.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/SyncIntents.kt @@ -1,31 +1,40 @@ package org.dhis2.usescases.flow.syncFlow import android.content.Intent -import androidx.test.rule.ActivityTestRule +import androidx.test.core.app.ApplicationProvider +import org.dhis2.LazyActivityScenarioRule import org.dhis2.usescases.datasets.datasetDetail.DataSetDetailActivity import org.dhis2.usescases.programEventDetail.ProgramEventDetailActivity import org.dhis2.usescases.searchTrackEntity.SearchTEActivity import org.dhis2.usescases.searchte.SearchTETest -fun prepareTBProgrammeIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { - Intent().apply { +fun prepareTBProgrammeIntentAndLaunchActivity(ruleSearch: LazyActivityScenarioRule) { + Intent( + ApplicationProvider.getApplicationContext(), + SearchTEActivity::class.java, + ).apply { putExtra(PROGRAM_UID, TB_PROGRAM_UID_VALUE) putExtra(SearchTETest.CHILD_TE_TYPE, SearchTETest.CHILD_TE_TYPE_VALUE) - }.also { ruleSearch.launchActivity(it) } + }.also { ruleSearch.launch(it) } } -fun prepareMalariaEventIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { - Intent().apply { putExtra(PROGRAM_UID, ANTENATAL_PROGRAM_UID_VALUE) }.also { ruleSearch.launchActivity(it) } +fun prepareMalariaEventIntentAndLaunchActivity(ruleSearch: LazyActivityScenarioRule) { + Intent( + ApplicationProvider.getApplicationContext(), + ProgramEventDetailActivity::class.java, + ).apply { putExtra(PROGRAM_UID, ANTENATAL_PROGRAM_UID_VALUE) }.also { ruleSearch.launch(it) } } -fun prepareFacilityDataSetIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { - Intent().apply { putExtra(DATASET_UID, MNCH_DATASET_UID_VALUE) }.also { ruleSearch.launchActivity(it) } +fun prepareFacilityDataSetIntentAndLaunchActivity(ruleSearch: LazyActivityScenarioRule) { + Intent( + ApplicationProvider.getApplicationContext(), + DataSetDetailActivity::class.java, + ).apply { putExtra(DATASET_UID, MNCH_DATASET_UID_VALUE) } + .also { ruleSearch.launch(it) } } const val PROGRAM_UID = "PROGRAM_UID" -const val MALARIA_PROGRAM_UID_VALUE = "VBqh0ynB2wv" const val ANTENATAL_PROGRAM_UID_VALUE = "lxAQ7Zs9VYR" const val DATASET_UID = "DATASET_UID" -const val FACILITY_DATASET_UID_VALUE = "V8MHeZHIrcP" const val MNCH_DATASET_UID_VALUE = "EKWVBc5C0ms" const val TB_PROGRAM_UID_VALUE = "ur1Edk5Oe2n" \ No newline at end of file diff --git a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/EventWithoutRegistrationRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/EventWithoutRegistrationRobot.kt index 78b18c3914..5d3eb23df9 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/EventWithoutRegistrationRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/EventWithoutRegistrationRobot.kt @@ -1,44 +1,24 @@ package org.dhis2.usescases.flow.syncFlow.robot -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItem -import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition -import androidx.test.espresso.contrib.RecyclerViewActions.scrollTo -import androidx.test.espresso.matcher.ViewMatchers.hasDescendant -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText -import org.dhis2.R +import androidx.compose.ui.test.junit4.ComposeTestRule +import androidx.compose.ui.test.onAllNodesWithTag +import androidx.compose.ui.test.performClick import org.dhis2.common.BaseRobot -import org.dhis2.common.viewactions.clickChildViewWithId -import org.dhis2.usescases.teiDashboard.dashboardfragments.teidata.teievents.EventViewHolder -import org.hamcrest.CoreMatchers.allOf -fun eventWithoutRegistrationRobot(eventWithoutRegistrationRobot: EventWithoutRegistrationRobot.() -> Unit) { - EventWithoutRegistrationRobot().apply { +fun eventWithoutRegistrationRobot( + composeTestRule: ComposeTestRule, + eventWithoutRegistrationRobot: EventWithoutRegistrationRobot.() -> Unit +) { + EventWithoutRegistrationRobot(composeTestRule).apply { eventWithoutRegistrationRobot() } } -class EventWithoutRegistrationRobot : BaseRobot() { - - fun clickOnEvent() { - onView(withId(R.id.recycler)).perform( - scrollTo( - allOf(hasDescendant(withText("teiName")), hasDescendant(withText("teiLastName"))) - ), - actionOnItem( - allOf(hasDescendant(withText("teiName")), hasDescendant(withText("teiLastName"))), clickChildViewWithId(R.id.status_icon) - ) - ) - } +class EventWithoutRegistrationRobot(val composeTestRule: ComposeTestRule) : BaseRobot() { fun clickOnEventAtPosition(position: Int) { - onView(withId(R.id.recycler)) - .perform(actionOnItemAtPosition(position, click())) - } - - fun clickOnSaveFab() { - onView(withId(R.id.action_button)).perform(click()) + composeTestRule + .onAllNodesWithTag("EVENT_ITEM")[position] + .performClick() } } \ No newline at end of file diff --git a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/SyncFlowRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/SyncFlowRobot.kt index 4072ae657d..befed7dff1 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/SyncFlowRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/flow/syncFlow/robot/SyncFlowRobot.kt @@ -1,7 +1,8 @@ import androidx.compose.ui.test.assert import androidx.compose.ui.test.hasText -import androidx.compose.ui.test.junit4.ComposeContentTestRule +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.test.espresso.Espresso.onView import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition @@ -13,40 +14,35 @@ import org.dhis2.common.viewactions.clickChildViewWithId import org.dhis2.ui.dialogs.bottomsheet.MAIN_BUTTON_TAG import org.dhis2.ui.dialogs.bottomsheet.TITLE import org.dhis2.usescases.datasets.datasetDetail.datasetList.DataSetListViewHolder -import org.dhis2.usescases.teiDashboard.dashboardfragments.teidata.teievents.EventViewHolder -fun syncFlowRobot(syncFlowRobot: SyncFlowRobot.() -> Unit) { - SyncFlowRobot().apply { +fun syncFlowRobot( + composeTestRule: ComposeTestRule, + syncFlowRobot: SyncFlowRobot.() -> Unit) { + SyncFlowRobot(composeTestRule).apply { syncFlowRobot() } } -class SyncFlowRobot : BaseRobot() { +class SyncFlowRobot(val composeTestRule: ComposeTestRule) : BaseRobot() { - fun clickOnSyncButton(composeTestRule: ComposeContentTestRule) { + fun clickOnSyncButton() { composeTestRule.onNodeWithTag(MAIN_BUTTON_TAG).performClick() } - fun checkSyncWasSuccessfully(composeTestRule: ComposeContentTestRule) { + fun checkSyncWasSuccessfully() { val expectedTitle = InstrumentationRegistry.getInstrumentation() .targetContext.getString(R.string.sync_dialog_title_not_synced) composeTestRule.onNodeWithTag(TITLE).assert(hasText(expectedTitle)) } - fun checkSyncFailed(composeTestRule: ComposeContentTestRule) { + fun checkSyncFailed() { val expectedTitle = InstrumentationRegistry.getInstrumentation() .targetContext.getString(R.string.sync_dialog_title_not_synced) composeTestRule.onNodeWithTag(TITLE).assert(hasText(expectedTitle)) } - fun clickOnEventToSync(position: Int) { - onView(withId(R.id.recycler)) - .perform( - actionOnItemAtPosition( - position, - clickChildViewWithId(R.id.sync_icon) - ) - ) + fun clickOnEventToSync() { + composeTestRule.onNodeWithText("Sync").performClick() } fun clickOnDataSetToSync(position: Int) { diff --git a/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowRobot.kt index 64778b99ab..6cba386321 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowRobot.kt @@ -1,26 +1,27 @@ package org.dhis2.usescases.flow.teiFlow -import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.junit4.ComposeTestRule import org.dhis2.common.BaseRobot -import org.dhis2.usescases.searchte.robot.searchTeiRobot import org.dhis2.usescases.flow.teiFlow.entity.EnrollmentListUIModel import org.dhis2.usescases.flow.teiFlow.entity.RegisterTEIUIModel +import org.dhis2.usescases.searchte.robot.searchTeiRobot import org.dhis2.usescases.teidashboard.robot.enrollmentRobot import org.dhis2.usescases.teidashboard.robot.eventRobot import org.dhis2.usescases.teidashboard.robot.teiDashboardRobot -fun teiFlowRobot(teiFlowRobot: TeiFlowRobot.() -> Unit) { - TeiFlowRobot().apply { +fun teiFlowRobot( + composeTestRule: ComposeTestRule, + teiFlowRobot: TeiFlowRobot.() -> Unit +) { + TeiFlowRobot(composeTestRule).apply { teiFlowRobot() } } -class TeiFlowRobot : BaseRobot() { +class TeiFlowRobot(val composeTestRule: ComposeTestRule) : BaseRobot() { fun registerTEI( - registrationModel: RegisterTEIUIModel, - composeTestRule: ComposeContentTestRule + registrationModel: RegisterTEIUIModel ) { val registrationDate = registrationModel.firstSpecificDate val enrollmentDate = registrationModel.enrollmentDate @@ -43,8 +44,8 @@ class TeiFlowRobot : BaseRobot() { } } - fun enrollToProgram(composeTestRule: ComposeTestRule, program: String) { - teiDashboardRobot { + fun enrollToProgram(program: String) { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnMenuProgramEnrollments() } @@ -58,7 +59,7 @@ class TeiFlowRobot : BaseRobot() { } fun checkActiveAndPastEnrollmentDetails(enrollmentDetails: EnrollmentListUIModel) { - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnMenuProgramEnrollments() } @@ -70,41 +71,41 @@ class TeiFlowRobot : BaseRobot() { } fun checkPastEventsAreClosed( - composeTestRule: ComposeContentTestRule, programPosition: Int ) { enrollmentRobot { clickOnEnrolledProgram(programPosition) } - teiDashboardRobot { - checkCanNotAddEvent(composeTestRule) - checkAllEventsAreClosed(composeTestRule) + teiDashboardRobot(composeTestRule) { + checkCanNotAddEvent() + checkAllEventsAreClosed() } } - fun closeEnrollmentAndCheckEvents( - composeTestRule: ComposeContentTestRule, - ) { - teiDashboardRobot { + fun closeEnrollmentAndCheckEvents() { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() clickOnMenuMoreOptions() clickOnMenuComplete() - checkCanNotAddEvent(composeTestRule) - checkAllEventsAreClosed(composeTestRule) + checkCanNotAddEvent() + checkAllEventsAreClosed() } } - fun changeDueDate(date: String, composeTestRule: ComposeTestRule) { - teiDashboardRobot { - clickOnEventGroupByStageUsingDate(composeTestRule, date) + fun changeDueDate( + cardTitle: String, + date: String, + ) { + teiDashboardRobot(composeTestRule) { + clickOnEventGroupByStageUsingDate(cardTitle) } - eventRobot { - clickOnEventReportDate(composeTestRule) - selectSpecificDate(composeTestRule, date) - acceptUpdateEventDate(composeTestRule) + eventRobot(composeTestRule) { + clickOnEventReportDate() + selectSpecificDate(date) + acceptUpdateEventDate() } } } diff --git a/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowTest.kt b/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowTest.kt index 34b8b12f7b..35e09a7add 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/flow/teiFlow/TeiFlowTest.kt @@ -5,11 +5,11 @@ import androidx.compose.ui.test.junit4.createComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.ActivityTestRule import org.dhis2.usescases.BaseTest -import org.dhis2.usescases.searchTrackEntity.SearchTEActivity -import org.dhis2.usescases.teiDashboard.TeiDashboardMobileActivity import org.dhis2.usescases.flow.teiFlow.entity.DateRegistrationUIModel import org.dhis2.usescases.flow.teiFlow.entity.EnrollmentListUIModel import org.dhis2.usescases.flow.teiFlow.entity.RegisterTEIUIModel +import org.dhis2.usescases.searchTrackEntity.SearchTEActivity +import org.dhis2.usescases.teiDashboard.TeiDashboardMobileActivity import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -18,7 +18,7 @@ import java.util.Date @RunWith(AndroidJUnit4::class) -class TeiFlowTest: BaseTest() { +class TeiFlowTest : BaseTest() { @get:Rule val rule = ActivityTestRule(TeiDashboardMobileActivity::class.java, false, false) @@ -43,12 +43,12 @@ class TeiFlowTest: BaseTest() { setDatePicker() prepareWomanProgrammeIntentAndLaunchActivity(ruleSearch) - teiFlowRobot { - registerTEI(registerTeiDetails, composeTestRule) - closeEnrollmentAndCheckEvents(composeTestRule) - enrollToProgram(composeTestRule, ADULT_WOMAN_PROGRAM) + teiFlowRobot(composeTestRule) { + registerTEI(registerTeiDetails) + closeEnrollmentAndCheckEvents() + enrollToProgram(ADULT_WOMAN_PROGRAM) checkActiveAndPastEnrollmentDetails(enrollmentListDetails) - checkPastEventsAreClosed(composeTestRule, totalEventsPerEnrollment) + checkPastEventsAreClosed(totalEventsPerEnrollment) } } @@ -79,7 +79,7 @@ class TeiFlowTest: BaseTest() { 30 ) - private fun getCurrentDate() :String { + private fun getCurrentDate(): String { val sdf = SimpleDateFormat(DATE_FORMAT) val dateFormat = sdf.format(Date()) return dateFormat.removePrefix("0") diff --git a/app/src/androidTest/java/org/dhis2/usescases/programevent/ProgramEventTest.kt b/app/src/androidTest/java/org/dhis2/usescases/programevent/ProgramEventTest.kt index b3a8cf117c..7bf563882a 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/programevent/ProgramEventTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/programevent/ProgramEventTest.kt @@ -40,9 +40,9 @@ class ProgramEventTest : BaseTest() { eventRegistrationRobot { clickNextButton() } - eventRobot { + eventRobot(composeTestRule) { clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() } programEventsRobot(composeTestRule) { checkEventWasCreatedAndClosed(eventOrgUnit) @@ -61,7 +61,7 @@ class ProgramEventTest : BaseTest() { clickOnEvent(eventDate) } - eventRobot { + eventRobot(composeTestRule) { checkDetails(eventDate, eventOrgUnit) } } @@ -78,9 +78,9 @@ class ProgramEventTest : BaseTest() { clickOnEvent(eventDate) } - eventRobot { + eventRobot(composeTestRule) { clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() waitToDebounce(400) } @@ -89,7 +89,7 @@ class ProgramEventTest : BaseTest() { clickOnEvent(eventDate) } - eventRobot { + eventRobot(composeTestRule) { clickOnDetails() clickOnReopen() pressBack() @@ -112,9 +112,9 @@ class ProgramEventTest : BaseTest() { waitToDebounce(400) clickOnEvent(eventDate) } - eventRobot { + eventRobot(composeTestRule) { clickOnDetails() - checkEventDetails(eventDate, eventOrgUnit, composeTestRule) + checkEventDetails(eventDate, eventOrgUnit) } } @@ -129,7 +129,7 @@ class ProgramEventTest : BaseTest() { waitToDebounce(400) clickOnEvent(eventDate) } - eventRobot { + eventRobot(composeTestRule) { openMenuMoreOptions() clickOnDelete() clickOnDeleteDialog() diff --git a/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTEIntents.kt b/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTEIntents.kt index ab7517fa2a..e13224bf4d 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTEIntents.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTEIntents.kt @@ -1,7 +1,8 @@ package org.dhis2.usescases.searchte import android.content.Intent -import androidx.test.rule.ActivityTestRule +import androidx.test.core.app.ApplicationProvider +import org.dhis2.LazyActivityScenarioRule import org.dhis2.usescases.searchTrackEntity.SearchTEActivity private const val PROGRAM_UID = "PROGRAM_UID" @@ -16,25 +17,32 @@ private const val ADULT_WOMAN_TE_TYPE_VALUE = "nEenWmSyUEp" private const val TB_TE_TYPE_VALUE = "nEenWmSyUEp" private const val CHILD_TE_TYPE = "TRACKED_ENTITY_UID" -fun prepareChildProgrammeIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { +fun prepareChildProgrammeIntentAndLaunchActivity(ruleSearch: LazyActivityScenarioRule) { startSearchActivity(CHILD_PROGRAM_UID_VALUE, CHILD_TE_TYPE_VALUE, ruleSearch) } -fun prepareTestProgramRulesProgrammeIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { +fun prepareTestProgramRulesProgrammeIntentAndLaunchActivity(ruleSearch: LazyActivityScenarioRule) { startSearchActivity(XX_TEST_PROGRAM_RULES_UID_VALUE, PROGRAM_RULES_TE_TYPE_VALUE, ruleSearch) } -fun prepareTestAdultWomanProgrammeIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { +fun prepareTestAdultWomanProgrammeIntentAndLaunchActivity(ruleSearch: LazyActivityScenarioRule) { startSearchActivity(ADULT_WOMAN_PROGRAM_UID_VALUE, ADULT_WOMAN_TE_TYPE_VALUE, ruleSearch) } -fun prepareTBIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { +fun prepareTBIntentAndLaunchActivity(ruleSearch: LazyActivityScenarioRule) { startSearchActivity(TB_PROGRAM_UID_VALUE, TB_TE_TYPE_VALUE, ruleSearch) } -fun startSearchActivity(programUID: String?, teType: String, ruleSearch: ActivityTestRule) { - Intent().apply { +fun startSearchActivity( + programUID: String?, + teType: String, + ruleSearch: LazyActivityScenarioRule +) { + Intent( + ApplicationProvider.getApplicationContext(), + SearchTEActivity::class.java, + ).apply { putExtra(PROGRAM_UID, programUID) putExtra(CHILD_TE_TYPE, teType) - }.also { ruleSearch.launchActivity(it) } + }.also { ruleSearch.launch(it) } } \ No newline at end of file diff --git a/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTETest.kt b/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTETest.kt index 422916ba72..b05c63ed10 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTETest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/searchte/SearchTETest.kt @@ -9,7 +9,6 @@ import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.IdlingResourceTimeoutException import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation -import androidx.test.rule.ActivityTestRule import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.Until @@ -18,6 +17,8 @@ import dispatch.android.espresso.IdlingDispatcherProviderRule import org.dhis2.R import org.dhis2.bindings.app import org.dhis2.common.idlingresources.MapIdlingResource +import org.dhis2.data.dhislogic.SIMPLE_DATE_FORMAT +import org.dhis2.lazyActivityScenarioRule import org.dhis2.ui.dialogs.bottomsheet.SECONDARY_BUTTON_TAG import org.dhis2.usescases.BaseTest import org.dhis2.usescases.flow.teiFlow.TeiFlowTest @@ -42,7 +43,7 @@ import java.util.Date class SearchTETest : BaseTest() { @get:Rule - val rule = ActivityTestRule(SearchTEActivity::class.java, false, false) + val rule = lazyActivityScenarioRule(launchActivity = false) private var mapIdlingResource: MapIdlingResource? = null @@ -61,7 +62,7 @@ class SearchTETest : BaseTest() { @Test fun shouldSuccessfullySearchByName() { val firstName = "Tim" - val orgUnit = "Ngelehun CHC" + val lastName = "Johnson" prepareChildProgrammeIntentAndLaunchActivity(rule) @@ -70,7 +71,10 @@ class SearchTETest : BaseTest() { openNextSearchParameter("First name") typeOnNextSearchTextParameter(firstName) clickOnSearch() - checkListOfSearchTEI(firstName, orgUnit) + checkListOfSearchTEI( + title = "First name: $firstName", + attributes = mapOf("Last name:" to lastName) + ) } } @@ -103,7 +107,10 @@ class SearchTETest : BaseTest() { openNextSearchParameter("Last name") typeOnNextSearchTextParameter(lastName) clickOnSearch() - checkListOfSearchTEI(firstName, lastName) + checkListOfSearchTEI( + title = "First name: $firstName", + attributes = mapOf("Last name:" to lastName) + ) } } @@ -125,7 +132,6 @@ class SearchTETest : BaseTest() { fun shouldCheckDisplayInList() { val displayInListData = createDisplayListFields() - setDatePicker() prepareTestAdultWomanProgrammeIntentAndLaunchActivity(rule) searchTeiRobot(composeTestRule) { @@ -145,7 +151,10 @@ class SearchTETest : BaseTest() { @Test fun shouldSuccessfullyFilterByEnrollmentStatusActive() { val enrollmentStatusFilter = context.getString(R.string.filters_title_enrollment_status) - .format(context.resources.getQuantityString(R.plurals.enrollment, 1).capitalize(Locale.current)) + .format( + context.resources.getQuantityString(R.plurals.enrollment, 1) + .capitalize(Locale.current) + ) val totalFilterCount = "2" val filterCount = "1" @@ -168,18 +177,19 @@ class SearchTETest : BaseTest() { fun shouldSuccessfullyFilterByEventStatusOverdue() { val eventStatusFilter = context.getString(R.string.filters_title_event_status) val totalCount = "1" - - val programStage = "PNC Visit" - val orgUnit = "Ngelehun CHC" val registerTeiDetails = createRegisterTEI() val overdueDate = getCurrentDate() + val dateFormat = + SimpleDateFormat(SIMPLE_DATE_FORMAT, java.util.Locale.getDefault()).format(Date()) + val scheduledEventTitle = context.getString(R.string.scheduled_for) + .format(dateFormat) setDatePicker() prepareTestAdultWomanProgrammeIntentAndLaunchActivity(rule) - teiFlowRobot { - registerTEI(registerTeiDetails, composeTestRule) - changeDueDate(overdueDate, composeTestRule) + teiFlowRobot(composeTestRule) { + registerTEI(registerTeiDetails) + changeDueDate(scheduledEventTitle, overdueDate) pressBack() composeTestRule.onNodeWithTag(SECONDARY_BUTTON_TAG).performClick() pressBack() @@ -289,7 +299,7 @@ class SearchTETest : BaseTest() { clickOnTEI(teiName, teiLastName) } - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnMenuReOpen() pressBack() @@ -311,7 +321,10 @@ class SearchTETest : BaseTest() { val name = "Anna" val lastName = "Jones" val enrollmentStatus = context.getString(R.string.filters_title_enrollment_status) - .format(context.resources.getQuantityString(R.plurals.enrollment, 1).capitalize(Locale.current)) + .format( + context.resources.getQuantityString(R.plurals.enrollment, 1) + .capitalize(Locale.current) + ) val totalCount = "2" val totalFilterCount = "1" @@ -336,7 +349,10 @@ class SearchTETest : BaseTest() { } searchTeiRobot(composeTestRule) { - checkListOfSearchTEI(name, lastName) + checkListOfSearchTEI( + title = "First name: $name", + attributes = mapOf("Last name:" to lastName) + ) } } @@ -365,12 +381,6 @@ class SearchTETest : BaseTest() { } } - private fun createDateOfBirthSearch() = DateRegistrationUIModel( - 2001, - 1, - 1 - ) - private fun createDisplayListFields() = DisplayListFieldsUIModel( "Sarah", "Thompson", @@ -424,17 +434,7 @@ class SearchTETest : BaseTest() { 30 ) - private fun getSplitCurrentDate(): DateRegistrationUIModel { - val sdf = SimpleDateFormat(TeiFlowTest.DATE_FORMAT) - val dateFormat = sdf.format(Date()) - val splitDate: Array = dateFormat.removePrefix("0").split("/").toTypedArray() - val day = splitDate[0].toInt() - val month = splitDate[1].toInt() - val year = splitDate[2].toInt() - return DateRegistrationUIModel(year, month, day) - } - - private fun getCurrentDate() : String { + private fun getCurrentDate(): String { val sdf = SimpleDateFormat(TeiFlowTest.DATE_PICKER_FORMAT) val calendar = Calendar.getInstance() return sdf.format(calendar.time) @@ -442,7 +442,6 @@ class SearchTETest : BaseTest() { private val dateRegistration = createFirstSpecificDate() private val dateEnrollment = createEnrollmentDate() - private val currentDate = getSplitCurrentDate() companion object { const val PROGRAM_UID = "PROGRAM_UID" diff --git a/app/src/androidTest/java/org/dhis2/usescases/searchte/robot/SearchTeiRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/searchte/robot/SearchTeiRobot.kt index d15b9a15d9..9a6e0e3236 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/searchte/robot/SearchTeiRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/searchte/robot/SearchTeiRobot.kt @@ -4,14 +4,13 @@ import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.hasParent import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasText -import androidx.compose.ui.test.junit4.ComposeContentTestRule +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.onAllNodesWithTag import androidx.compose.ui.test.onLast import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTextInput -import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches @@ -19,7 +18,6 @@ import androidx.test.espresso.contrib.PickerActions import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItem import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition import androidx.test.espresso.contrib.RecyclerViewActions.scrollTo -import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText @@ -28,7 +26,6 @@ import org.dhis2.common.BaseRobot import org.dhis2.common.matchers.RecyclerviewMatchers import org.dhis2.common.matchers.RecyclerviewMatchers.Companion.hasItem import org.dhis2.common.matchers.RecyclerviewMatchers.Companion.hasNoMoreResultsInProgram -import org.dhis2.common.viewactions.clickChildViewWithId import org.dhis2.common.viewactions.openSpinnerPopup import org.dhis2.common.viewactions.typeChildViewWithId import org.dhis2.usescases.searchTrackEntity.adapters.SearchTEViewHolder @@ -37,12 +34,10 @@ import org.dhis2.usescases.searchte.entity.DisplayListFieldsUIModel import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.not import org.hisp.dhis.mobile.ui.designsystem.component.AdditionalInfoItem -import org.hisp.dhis.mobile.ui.designsystem.component.ListCard -import org.hisp.dhis.mobile.ui.designsystem.component.ListCardTitleModel fun searchTeiRobot( - composeTestRule: ComposeContentTestRule, + composeTestRule: ComposeTestRule, searchTeiRobot: SearchTeiRobot.() -> Unit ) { SearchTeiRobot(composeTestRule).apply { @@ -50,12 +45,7 @@ fun searchTeiRobot( } } -class SearchTeiRobot(val composeTestRule: ComposeContentTestRule) : BaseRobot() { - - fun closeSearchForm() { - waitToDebounce(2500) - onView(withId(R.id.close_filter)).perform(click()) - } +class SearchTeiRobot(val composeTestRule: ComposeTestRule) : BaseRobot() { fun clickOnTEI(teiName: String, teiLastName: String) { waitForView( @@ -132,16 +122,6 @@ class SearchTeiRobot(val composeTestRule: ComposeContentTestRule) : BaseRobot() closeKeyboard() } - fun clickOnDateField() { - onView(withId(R.id.recyclerView)) - .perform( - actionOnItemAtPosition( - 2, - clickChildViewWithId(R.id.inputEditText) - ) - ) - } - fun selectSpecificDate(year: Int, monthOfYear: Int, dayOfMonth: Int) { onView(withId(R.id.datePicker)).perform( PickerActions.setDate( @@ -161,18 +141,16 @@ class SearchTeiRobot(val composeTestRule: ComposeContentTestRule) : BaseRobot() composeTestRule.onNodeWithTag("SEARCH_BUTTON").performClick() } - fun checkListOfSearchTEI(firstSearchWord: String, secondSearchWord: String) { - onView(withId(R.id.scrollView)) - .check( - matches( - RecyclerviewMatchers.allElementsWithHolderTypeHave( - SearchTEViewHolder::class.java, allOf( - hasDescendant(withText(firstSearchWord)), - hasDescendant(withText(secondSearchWord)) - ) - ) - ) - ) + fun checkListOfSearchTEI(title: String, attributes: Map) { + //Checks title and all attributes are displayed + composeTestRule.onNodeWithText(title).assertIsDisplayed() + attributes.forEach { item -> + item.key?.let { composeTestRule.onNodeWithText(it).assertIsDisplayed() } + composeTestRule.onNode( + hasParent(hasTestTag("LIST_CARD_ADDITIONAL_INFO_COLUMN")) + and hasText(item.value), useUnmergedTree = true + ).assertIsDisplayed() + } } fun checkNoSearchResult() { @@ -210,14 +188,6 @@ class SearchTeiRobot(val composeTestRule: ComposeContentTestRule) : BaseRobot() val title = "First name: ${displayListFieldsUIModel.name}" val displayedAttributes = createAttributesList(displayListFieldsUIModel) - composeTestRule.setContent { - ListCard( - title = ListCardTitleModel(text = title), - additionalInfoList = displayedAttributes, - onCardClick = { } - ) - } - //When we expand all attribute list composeTestRule.onNodeWithText("Show more").performClick() @@ -236,10 +206,6 @@ class SearchTeiRobot(val composeTestRule: ComposeContentTestRule) : BaseRobot() onView(withId(R.id.navigation_map_view)).perform(click()) } - fun swipeCarouselToLeft() { - onView(withId(R.id.map_carousel)).perform(scrollToPosition(3)) - } - fun checkCarouselTEICardInfo(firstName: String) { onView(withId(R.id.map_carousel)) .check(matches(hasItem(hasDescendant(withText(firstName))))) @@ -249,14 +215,6 @@ class SearchTeiRobot(val composeTestRule: ComposeContentTestRule) : BaseRobot() onView(withId(R.id.openSearchButton)).perform(click()) } - fun clickOnShowMoreFilters() { - onView(withId(R.id.search_filter_general)).perform(click()) - } - - fun clickOnAcceptButton() { - onView(withId(R.id.accept_button)).perform(click()) - } - fun clickOnEnroll() { onView(withId(R.id.createButton)).perform(click()) } diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardIntents.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardIntents.kt index fe3011fd31..82305a577f 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardIntents.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardIntents.kt @@ -1,7 +1,8 @@ package org.dhis2.usescases.teidashboard import android.content.Intent -import androidx.test.rule.ActivityTestRule +import androidx.test.core.app.ApplicationProvider +import org.dhis2.LazyActivityScenarioRule import org.dhis2.usescases.searchTrackEntity.SearchTEActivity import org.dhis2.usescases.searchte.SearchTETest import org.dhis2.usescases.teiDashboard.TeiDashboardMobileActivity @@ -37,23 +38,40 @@ private const val TEI_UID_VALUE_ANALYTICS = "wsk89u7zquT" private const val ENROLLMENT_UID_VALUE_ANALYTICS = "ITyaPVATEwc" fun prepareTeiCompletedProgrammeAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { - startTeiDashboardActivity(CHILD_PROGRAM_UID_VALUE, TEI_UID_VALUE_COMPLETED, ENROLLMENT_VALUE_COMPLETED, rule) + startTeiDashboardActivity( + CHILD_PROGRAM_UID_VALUE, + TEI_UID_VALUE_COMPLETED, + ENROLLMENT_VALUE_COMPLETED, + rule + ) } fun prepareTeiOpenedForReferralProgrammeAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { - startTeiDashboardActivity(TB_PROGRAM_UID, TEI_UID_VALUE_OPEN_REFERRAL, ENROLLMENT_VALUE_OPEN_REFERRAL, rule) + startTeiDashboardActivity( + TB_PROGRAM_UID, + TEI_UID_VALUE_OPEN_REFERRAL, + ENROLLMENT_VALUE_OPEN_REFERRAL, + rule + ) } -fun prepareTeiOpenedProgrammeAndLaunchActivity(rule: ActivityTestRule) { - startTeiDashboardActivity(CHILD_PROGRAM_UID_VALUE, TEI_UID_VALUE_OPENED, ENROLLMENT_VALUE_OPENED, rule) +fun prepareTeiOpenedProgrammeAndLaunchActivity( + rule: LazyActivityScenarioRule +) { + startTeiDashboardActivity( + CHILD_PROGRAM_UID_VALUE, + TEI_UID_VALUE_OPENED, + ENROLLMENT_VALUE_OPENED, + rule + ) } fun prepareTeiOpenedForCompleteProgrammeAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { startTeiDashboardActivity( CHILD_PROGRAM_UID_VALUE, @@ -64,7 +82,7 @@ fun prepareTeiOpenedForCompleteProgrammeAndLaunchActivity( } fun prepareTeiWithExistingNoteAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { startTeiDashboardActivity( CHILD_PROGRAM_UID_VALUE, @@ -75,60 +93,107 @@ fun prepareTeiWithExistingNoteAndLaunchActivity( } fun prepareTeiOpenedWithFullEventsAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { - startTeiDashboardActivity(CHILD_PROGRAM_UID_VALUE, TEI_UID_VALUE_OPENED_FULL, ENROLLMENT_VALUE_OPENED_FULL, rule) + startTeiDashboardActivity( + CHILD_PROGRAM_UID_VALUE, + TEI_UID_VALUE_OPENED_FULL, + ENROLLMENT_VALUE_OPENED_FULL, + rule + ) } -fun prepareTeiToDeleteAndLaunchActivity(rule: ActivityTestRule) { - startTeiDashboardActivity(CHILD_PROGRAM_UID_VALUE, TEI_UID_VALUE_TO_DELETE, ENROLLMENT_VALUE_TO_DELETE, rule) +fun prepareTeiToDeleteAndLaunchActivity( + rule: LazyActivityScenarioRule +) { + startTeiDashboardActivity( + CHILD_PROGRAM_UID_VALUE, + TEI_UID_VALUE_TO_DELETE, + ENROLLMENT_VALUE_TO_DELETE, + rule + ) } fun prepareTeiOpenedWithNoPreviousEventProgrammeAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { - startTeiDashboardActivity(TB_PROGRAM_UID, TEI_UID_VALUE_TO_SCHEDULE, ENROLLMENT_VALUE_TO_SCHEDULE, rule) + startTeiDashboardActivity( + TB_PROGRAM_UID, + TEI_UID_VALUE_TO_SCHEDULE, + ENROLLMENT_VALUE_TO_SCHEDULE, + rule + ) } fun prepareTeiToCreateANewEventAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { - startTeiDashboardActivity(TB_PROGRAM_UID, TEI_UID_VALUE_TO_CREATE_EVENT, ENROLLMENT_VALUE_TO_CREATE_EVENT, rule) + startTeiDashboardActivity( + TB_PROGRAM_UID, + TEI_UID_VALUE_TO_CREATE_EVENT, + ENROLLMENT_VALUE_TO_CREATE_EVENT, + rule + ) } -fun prepareTeiOpenedToEditAndLaunchActivity(rule: ActivityTestRule) { - startTeiDashboardActivity(TB_PROGRAM_UID, TEI_UID_VALUE_TO_EDIT_EVENT, ENROLLMENT_VALUE_TO_EDIT_EVENT, rule) +fun prepareTeiOpenedToEditAndLaunchActivity( + rule: LazyActivityScenarioRule +) { + startTeiDashboardActivity( + TB_PROGRAM_UID, + TEI_UID_VALUE_TO_EDIT_EVENT, + ENROLLMENT_VALUE_TO_EDIT_EVENT, + rule + ) } fun prepareTeiToEnrollToOtherProgramAndLaunchActivity( - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { - startTeiDashboardActivity(CHILD_PROGRAM_UID_VALUE, TEI_UID_VALUE_TO_ENROLL, ENROLLMENT_VALUE_TO_ENROLL, rule) + startTeiDashboardActivity( + CHILD_PROGRAM_UID_VALUE, + TEI_UID_VALUE_TO_ENROLL, + ENROLLMENT_VALUE_TO_ENROLL, + rule + ) } fun prepareTeiForAnalyticsAndLaunchActivity( - rule: ActivityTestRule -){ - startTeiDashboardActivity(TB_PROGRAM_UID, TEI_UID_VALUE_ANALYTICS, ENROLLMENT_UID_VALUE_ANALYTICS, rule) + rule: LazyActivityScenarioRule +) { + startTeiDashboardActivity( + TB_PROGRAM_UID, + TEI_UID_VALUE_ANALYTICS, + ENROLLMENT_UID_VALUE_ANALYTICS, + rule + ) } fun startTeiDashboardActivity( programUID: String?, teiUID: String, enrollmentUID: String?, - rule: ActivityTestRule + rule: LazyActivityScenarioRule ) { - Intent().apply { + Intent( + ApplicationProvider.getApplicationContext(), + TeiDashboardMobileActivity::class.java, + ).apply { putExtra(PROGRAM_UID, programUID) putExtra(TEI_UID, teiUID) - putExtra(ENROLLMENT_UID,enrollmentUID) - }.also { rule.launchActivity(it) } + putExtra(ENROLLMENT_UID, enrollmentUID) + }.also { rule.launch(it) } } -fun prepareChildProgrammeIntentAndLaunchActivity(ruleSearch: ActivityTestRule) { - Intent().apply { +fun prepareChildProgrammeIntentAndLaunchActivity( + ruleSearch: LazyActivityScenarioRule +) { + Intent( + ApplicationProvider.getApplicationContext(), + SearchTEActivity::class.java, + ).apply { putExtra(SearchTETest.PROGRAM_UID, SearchTETest.CHILD_PROGRAM_UID_VALUE) putExtra(SearchTETest.CHILD_TE_TYPE, SearchTETest.CHILD_TE_TYPE_VALUE) - }.also { ruleSearch.launchActivity(it) } + }.also { ruleSearch.launch(it) } } diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardMobileActivityTest.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardMobileActivityTest.kt index ccf45ce1e9..0b7e5c91a3 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardMobileActivityTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardMobileActivityTest.kt @@ -6,7 +6,6 @@ import androidx.test.core.app.ActivityScenario import androidx.test.ext.junit.rules.activityScenarioRule import dhis2.org.analytics.charts.Charts import io.reactivex.Observable -import java.util.Calendar import org.dhis2.R import org.dhis2.android.rtsm.utils.NetworkUtils import org.dhis2.commons.filters.FilterManager @@ -29,6 +28,7 @@ import org.mockito.Mockito import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.whenever +import java.util.Calendar class TeiDashboardMobileActivityTest { @@ -52,7 +52,7 @@ class TeiDashboardMobileActivityTest { } - private var dispatcher:DispatcherProvider = mock() + private var dispatcher: DispatcherProvider = mock() var tei = Observable.just( TrackedEntityInstance.builder() .uid(TEI_Uid) @@ -181,15 +181,10 @@ class TeiDashboardMobileActivityTest { ) doReturn mock() - - ActivityScenario.launch(TeiDashboardMobileActivity::class.java).onActivity { activity -> val showMoreOptions = activity.findViewById(R.id.moreOptions) showMoreOptions.performClick() } - - } - } \ No newline at end of file diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt index e1c521fccb..097832e0e2 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTest.kt @@ -2,9 +2,9 @@ package org.dhis2.usescases.teidashboard import androidx.compose.ui.test.junit4.createComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.rule.ActivityTestRule import dhis2.org.analytics.charts.data.ChartType import org.dhis2.R +import org.dhis2.lazyActivityScenarioRule import org.dhis2.usescases.BaseTest import org.dhis2.usescases.searchTrackEntity.SearchTEActivity import org.dhis2.usescases.teiDashboard.TeiDashboardMobileActivity @@ -25,10 +25,10 @@ import org.junit.runner.RunWith class TeiDashboardTest : BaseTest() { @get:Rule - val rule = ActivityTestRule(TeiDashboardMobileActivity::class.java, false, false) + val rule = lazyActivityScenarioRule(launchActivity = false) @get:Rule - val ruleSearch = ActivityTestRule(SearchTEActivity::class.java, false, false) + val ruleSearch = lazyActivityScenarioRule(launchActivity = false) @get:Rule val composeTestRule = createComposeRule() @@ -39,7 +39,7 @@ class TeiDashboardTest : BaseTest() { prepareTeiCompletedProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { goToNotes() } @@ -55,7 +55,7 @@ class TeiDashboardTest : BaseTest() { fun shouldNotCreateANoteWhenClickClear() { prepareTeiCompletedProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { goToNotes() } @@ -72,7 +72,7 @@ class TeiDashboardTest : BaseTest() { fun shouldOpenNotesDetailsWhenClickOnNote() { prepareTeiWithExistingNoteAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { goToNotes() } @@ -86,7 +86,7 @@ class TeiDashboardTest : BaseTest() { fun shouldReactivateTEIWhenClickReOpenWithProgramCompletedEvents() { prepareTeiCompletedProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() clickOnMenuMoreOptions() @@ -99,14 +99,14 @@ class TeiDashboardTest : BaseTest() { fun shouldShowInactiveProgramWhenClickDeactivate() { prepareTeiOpenedProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() clickOnMenuMoreOptions() clickOnMenuDeactivate() - checkCancelledStateInfoBarIsDisplay(composeTestRule) - checkCanNotAddEvent(composeTestRule) - checkAllEventsAreClosed(composeTestRule) + checkCancelledStateInfoBarIsDisplay() + checkCanNotAddEvent() + checkAllEventsAreClosed() } } @@ -114,14 +114,14 @@ class TeiDashboardTest : BaseTest() { fun shouldCompleteProgramWhenClickComplete() { prepareTeiOpenedForCompleteProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() clickOnMenuMoreOptions() clickOnMenuComplete() - checkCompleteStateInfoBarIsDisplay(composeTestRule) - checkCanNotAddEvent(composeTestRule) - checkAllEventsAreClosed(composeTestRule) + checkCompleteStateInfoBarIsDisplay() + checkCanNotAddEvent() + checkAllEventsAreClosed() } } @@ -129,7 +129,7 @@ class TeiDashboardTest : BaseTest() { fun shouldShowQRWhenClickOnShare() { prepareTeiCompletedProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnShareButton() clickOnNextQR() @@ -140,16 +140,13 @@ class TeiDashboardTest : BaseTest() { fun shouldMakeAReferral() { prepareTeiOpenedForReferralProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() - clickOnFab(composeTestRule) - clickOnReferral(composeTestRule) + clickOnFab() + clickOnReferral() clickOnFirstReferralEvent() - clickOnReferralOption( - composeTestRule, - context.getString(R.string.one_time) - ) + clickOnReferralOption(context.getString(R.string.one_time)) clickOnReferralNextButton() checkEventWasCreated(LAB_MONITORING) } @@ -159,11 +156,11 @@ class TeiDashboardTest : BaseTest() { fun shouldSuccessfullyScheduleAnEvent() { prepareTeiOpenedWithNoPreviousEventProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() - clickOnFab(composeTestRule) - clickOnScheduleNew(composeTestRule) + clickOnFab() + clickOnScheduleNew() clickOnFirstReferralEvent() clickOnReferralNextButton() checkEventWasCreatedWithDate(LAB_MONITORING, LAB_MONITORING_SCHEDULE_DATE) @@ -176,17 +173,17 @@ class TeiDashboardTest : BaseTest() { prepareTeiOpenedProgrammeAndLaunchActivity(rule) - val babyPostNatal = 0 - teiDashboardRobot { + val babyPostNatal = "Baby Postnatal" + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() - clickOnEventWithPosition(babyPostNatal) + clickOnEventWithTitle(babyPostNatal) } - eventRobot { + eventRobot(composeTestRule) { scrollToBottomForm() clickOnFormFabButton() - clickOnNotNow(composeTestRule) + clickOnNotNow() } } @@ -197,7 +194,7 @@ class TeiDashboardTest : BaseTest() { val upperInformation = createExpectedUpperInformation() - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { checkUpperInfo(upperInformation) } } @@ -208,7 +205,7 @@ class TeiDashboardTest : BaseTest() { val enrollmentFullDetails = createExpectedEnrollmentInformation() - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnSeeDetails() checkFullDetails(enrollmentFullDetails) } @@ -218,7 +215,7 @@ class TeiDashboardTest : BaseTest() { fun shouldShowIndicatorsDetailsWhenClickOnIndicatorsTab() { prepareTeiCompletedProgrammeAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { goToAnalytics() } @@ -232,23 +229,23 @@ class TeiDashboardTest : BaseTest() { fun shouldOpenEventEditAndSaveSuccessfully() { prepareTeiOpenedToEditAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() - clickOnEventWith(composeTestRule, LAB_MONITORING) + clickOnEventWith(LAB_MONITORING) waitToDebounce(600) } - eventRobot { + eventRobot(composeTestRule) { waitToDebounce(600) fillRadioButtonForm(4) clickOnFormFabButton() - clickOnCompleteButton(composeTestRule) + clickOnCompleteButton() waitToDebounce(600) } - teiDashboardRobot { - checkEventWasCreatedAndClosed(composeTestRule, LAB_MONITORING) + teiDashboardRobot(composeTestRule) { + checkEventWasCreatedAndClosed(LAB_MONITORING) } } @@ -265,7 +262,7 @@ class TeiDashboardTest : BaseTest() { setDatePicker() prepareTeiToEnrollToOtherProgramAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnTimelineEvents() clickOnMenuMoreOptions() @@ -283,7 +280,7 @@ class TeiDashboardTest : BaseTest() { clickOnSaveEnrollment() } - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { waitToDebounce(1000) clickOnMenuMoreOptions() clickOnTimelineEvents() @@ -301,7 +298,7 @@ class TeiDashboardTest : BaseTest() { setupCredentials() prepareTeiForAnalyticsAndLaunchActivity(rule) - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { goToAnalytics() } @@ -341,9 +338,5 @@ class TeiDashboardTest : BaseTest() { const val LAB_MONITORING = "Lab monitoring" const val LAB_MONITORING_SCHEDULE_DATE = "10/9/2019" - - const val API_TEI_1_RESPONSE_OK = "mocks/teilist/teilist_1.json" - const val API_TEI_2_RESPONSE_OK = "mocks/teilist/teilist_2.json" - const val API_TEI_3_RESPONSE_OK = "mocks/teilist/teilist_3.json" } } diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTestNoComposable.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTestNoComposable.kt index abfbbfe78d..eb436cbe01 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTestNoComposable.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/TeiDashboardTestNoComposable.kt @@ -2,7 +2,7 @@ package org.dhis2.usescases.teidashboard import androidx.compose.ui.test.junit4.createComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.rule.ActivityTestRule +import org.dhis2.lazyActivityScenarioRule import org.dhis2.usescases.BaseTest import org.dhis2.usescases.searchTrackEntity.SearchTEActivity import org.dhis2.usescases.searchte.robot.searchTeiRobot @@ -17,7 +17,7 @@ import org.junit.runner.RunWith class TeiDashboardTestNoComposable : BaseTest() { @get:Rule - val ruleSearch = ActivityTestRule(SearchTEActivity::class.java, false, false) + val ruleSearch = lazyActivityScenarioRule(launchActivity = false) @get:Rule val composeTestRule = createComposeRule() @@ -38,7 +38,7 @@ class TeiDashboardTestNoComposable : BaseTest() { clickOnTEI(teiName, teiLastName) } - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { goToRelationships() } @@ -82,7 +82,7 @@ class TeiDashboardTestNoComposable : BaseTest() { //scrollToTEIandClick() } - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnMenuDeleteTEI() } @@ -111,7 +111,7 @@ class TeiDashboardTestNoComposable : BaseTest() { clickOnTEI(teiName, teiLastName) } - teiDashboardRobot { + teiDashboardRobot(composeTestRule) { clickOnMenuMoreOptions() clickOnMenuDeleteEnrollment() } diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/EventRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/EventRobot.kt index d9d9af03fd..fe403577b5 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/EventRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/EventRobot.kt @@ -8,7 +8,6 @@ import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import androidx.compose.ui.test.printToLog import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches @@ -18,7 +17,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withSubstring import androidx.test.espresso.matcher.ViewMatchers.withText import org.dhis2.R import org.dhis2.common.BaseRobot -import org.dhis2.common.matchers.clickOnTab import org.dhis2.common.matchers.hasCompletedPercentage import org.dhis2.common.viewactions.clickChildViewWithId import org.dhis2.common.viewactions.scrollToBottomRecyclerView @@ -29,13 +27,16 @@ import org.dhis2.ui.dialogs.bottomsheet.SECONDARY_BUTTON_TAG import org.dhis2.usescases.teiDashboard.dashboardfragments.teidata.DashboardProgramViewHolder import org.hamcrest.CoreMatchers.allOf -fun eventRobot(eventRobot: EventRobot.() -> Unit) { - EventRobot().apply { +fun eventRobot( + composeTestRule: ComposeTestRule, + eventRobot: EventRobot.() -> Unit +) { + EventRobot(composeTestRule).apply { eventRobot() } } -class EventRobot : BaseRobot() { +class EventRobot(val composeTestRule: ComposeTestRule) : BaseRobot() { fun scrollToBottomForm() { onView(withId(R.id.recyclerView)).perform(scrollToBottomRecyclerView()) @@ -44,15 +45,16 @@ class EventRobot : BaseRobot() { fun clickOnFormFabButton() { onView(withId(R.id.actionButton)).perform(click()) } - fun clickOnNotNow(composeTestRule: ComposeTestRule) { + + fun clickOnNotNow() { composeTestRule.onNodeWithTag(SECONDARY_BUTTON_TAG).performClick() } - fun clickOnCompleteButton(composeTestRule: ComposeTestRule) { + fun clickOnCompleteButton() { composeTestRule.onNodeWithTag(MAIN_BUTTON_TAG).performClick() } - fun checkSecondaryButtonNotVisible(composeTestRule: ComposeTestRule) { + fun checkSecondaryButtonNotVisible() { composeTestRule.onNodeWithTag(SECONDARY_BUTTON_TAG).assertDoesNotExist() } @@ -75,8 +77,8 @@ class EventRobot : BaseRobot() { } } - fun acceptUpdateEventDate(composeTestRule: ComposeTestRule) { - composeTestRule.onNodeWithText("OK",true).performClick() + fun acceptUpdateEventDate() { + composeTestRule.onNodeWithText("OK", true).performClick() } fun clickOnUpdate() { @@ -94,16 +96,14 @@ class EventRobot : BaseRobot() { fun checkDetails(eventDate: String, eventOrgUnit: String) { - onView(withId(R.id.eventSecundaryInfo)).check(matches( - allOf( - withSubstring(eventDate), - withSubstring(eventOrgUnit) + onView(withId(R.id.eventSecundaryInfo)).check( + matches( + allOf( + withSubstring(eventDate), + withSubstring(eventOrgUnit) + ) ) - )) - } - - fun clickOnNotesTab() { - onView(clickOnTab(1)).perform(click()) + ) } fun openMenuMoreOptions() { @@ -122,20 +122,21 @@ class EventRobot : BaseRobot() { onView(withId(R.id.possitive)).perform(click()) } - fun clickOnEventReportDate(composeTestRule: ComposeTestRule) { - - composeTestRule.onNode(hasTestTag("INPUT_DATE_TIME_ACTION_BUTTON") and hasAnySibling( - hasText("Report date") - )).assertIsDisplayed().performClick() + fun clickOnEventReportDate() { + composeTestRule.onNode( + hasTestTag("INPUT_DATE_TIME_ACTION_BUTTON") and hasAnySibling( + hasText("Report date") + ) + ).assertIsDisplayed().performClick() } - fun selectSpecificDate( composeTestRule: ComposeTestRule, date: String) { + fun selectSpecificDate(date: String) { composeTestRule.onNodeWithTag("DATE_PICKER").assertIsDisplayed() composeTestRule.onNode(hasText(date, true)).performClick() } - fun checkEventDetails(eventDate: String, eventOrgUnit: String, composeTestRule: ComposeTestRule) { + fun checkEventDetails(eventDate: String, eventOrgUnit: String) { onView(withId(R.id.completion)).check(matches(hasCompletedPercentage(100))) composeTestRule.onNodeWithText(formatStoredDateToUI(eventDate)).assertIsDisplayed() composeTestRule.onNodeWithText(eventOrgUnit).assertIsDisplayed() diff --git a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt index 0329c0841c..990c2fb976 100644 --- a/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt +++ b/app/src/androidTest/java/org/dhis2/usescases/teidashboard/robot/TeiDashboardRobot.kt @@ -2,10 +2,8 @@ package org.dhis2.usescases.teidashboard.robot import android.content.Context import android.view.View -import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.hasText -import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.onAllNodesWithText import androidx.compose.ui.test.onFirst @@ -31,7 +29,6 @@ import org.dhis2.common.BaseRobot import org.dhis2.common.matchers.RecyclerviewMatchers.Companion.atPosition import org.dhis2.common.matchers.RecyclerviewMatchers.Companion.hasItem import org.dhis2.common.matchers.RecyclerviewMatchers.Companion.isNotEmpty -import org.dhis2.common.matchers.isToast import org.dhis2.common.viewactions.clickChildViewWithId import org.dhis2.usescases.event.entity.EventStatusUIModel import org.dhis2.usescases.event.entity.TEIProgramStagesUIModel @@ -49,23 +46,22 @@ import org.hamcrest.CoreMatchers.not import org.hamcrest.Description import org.hamcrest.Matcher -fun teiDashboardRobot(teiDashboardRobot: TeiDashboardRobot.() -> Unit) { - TeiDashboardRobot().apply { +fun teiDashboardRobot( + composeTestRule: ComposeTestRule, + teiDashboardRobot: TeiDashboardRobot.() -> Unit +) { + TeiDashboardRobot(composeTestRule).apply { teiDashboardRobot() } } -class TeiDashboardRobot : BaseRobot() { +class TeiDashboardRobot(val composeTestRule: ComposeTestRule) : BaseRobot() { fun goToNotes() { onView(withId(R.id.navigation_notes)).perform(click()) Thread.sleep(500) } - fun clickOnSync() { - onView(withId(R.id.syncButton)).perform(click()) - } - fun goToRelationships() { onView(withId(R.id.navigation_relationships)).perform(click()) Thread.sleep(500) @@ -84,58 +80,28 @@ class TeiDashboardRobot : BaseRobot() { onView(withText(R.string.re_open)).perform(click()) } - fun checkCancelledStateInfoBarIsDisplay(composeTestRule: ComposeTestRule) { + fun checkCancelledStateInfoBarIsDisplay() { composeTestRule.onNodeWithTag(STATE_INFO_BAR_TEST_TAG).assertIsDisplayed() composeTestRule.onNodeWithText("Enrollment cancelled").assertIsDisplayed() } - fun clickOnEventWithPosition(position: Int) { - onView(withId(R.id.tei_recycler)) - .perform(actionOnItemAtPosition(position, click())) + fun clickOnEventWithTitle(title: String) { + composeTestRule.onNodeWithText(title).performClick() } - fun clickOnEventWith(composeTestRule: ComposeTestRule, searchParam: String) { - composeTestRule.onAllNodesWithText(searchParam, useUnmergedTree = true).onFirst().performClick() - } - - fun clickOnEventWith(eventName: String, eventStatus: Int, date: String) { - onView(withId(R.id.tei_recycler)) - .perform( - actionOnItem( - allOf( - hasDescendant(withText(eventName)), - hasDescendant(withText(eventStatus)), - hasDescendant(withText(date)) - ), - click() - ) - ) + fun clickOnEventWith(searchParam: String) { + composeTestRule.onAllNodesWithText(searchParam, useUnmergedTree = true).onFirst() + .performClick() } - fun clickOnGroupEventByName(name: String) { - onView(withId(R.id.tei_recycler)) - .perform( - actionOnItem( - hasDescendant(withText(name)), - click() - ) - ) - } - - fun clickOnFab(composeTestRule: ComposeTestRule) { + fun clickOnFab() { composeTestRule.onNodeWithTag(TEST_ADD_EVENT_BUTTON, useUnmergedTree = true).performClick() } - fun clickOnReferral(composeTestRule: ComposeTestRule) { + fun clickOnReferral() { val targetContext: Context = InstrumentationRegistry.getInstrumentation().targetContext val referalTag = targetContext.resources.getString(R.string.referral) composeTestRule.onNodeWithTag(referalTag).performClick() - // onView(withTagValue(equalTo(referalTag))).perform(click()) - } - - fun checkCannotAddMoreEventToastIsShown() { - onView(withText(R.string.program_not_allow_events)).inRoot(isToast()) - .check(matches(isDisplayed())) } fun clickOnFirstReferralEvent() { @@ -144,7 +110,7 @@ class TeiDashboardRobot : BaseRobot() { .perform(actionOnItemAtPosition(0, click())) } - fun clickOnReferralOption(composeTestRule: ComposeTestRule, oneTime: String) { + fun clickOnReferralOption(oneTime: String) { composeTestRule.onNodeWithText(oneTime).performClick() } @@ -212,14 +178,15 @@ class TeiDashboardRobot : BaseRobot() { onView(withText(R.string.complete)).perform(click()) } - fun checkCompleteStateInfoBarIsDisplay(composeTestRule: ComposeTestRule) { + fun checkCompleteStateInfoBarIsDisplay() { composeTestRule.onNodeWithTag(STATE_INFO_BAR_TEST_TAG).assertIsDisplayed() composeTestRule.onNodeWithText("Enrollment completed").assertIsDisplayed() } - fun checkCanNotAddEvent(composeTestRule: ComposeTestRule) { - composeTestRule.onNodeWithTag(TEST_ADD_EVENT_BUTTON, useUnmergedTree = true).assertDoesNotExist() + fun checkCanNotAddEvent() { + composeTestRule.onNodeWithTag(TEST_ADD_EVENT_BUTTON, useUnmergedTree = true) + .assertDoesNotExist() } fun clickOnShareButton() { @@ -253,15 +220,75 @@ class TeiDashboardRobot : BaseRobot() { } fun checkFullDetails(enrollmentUIModel: EnrollmentUIModel) { - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.enrollmentDate))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.enrollmentDate) + ) + ) + ) + ) + ) + ) - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.birthday))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.birthday) + ) + ) + ) + ) + ) + ) - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.orgUnit))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.orgUnit) + ) + ) + ) + ) + ) + ) - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.latitude))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.latitude) + ) + ) + ) + ) + ) + ) - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.longitude))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.longitude) + ) + ) + ) + ) + ) + ) onView(withId(R.id.recyclerView)) @@ -274,11 +301,47 @@ class TeiDashboardRobot : BaseRobot() { waitToDebounce(2000) - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.name))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.name) + ) + ) + ) + ) + ) + ) - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.lastName))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.lastName) + ) + ) + ) + ) + ) + ) - onView(withId(R.id.recyclerView)).check(matches(not(recyclerChildViews(hasItem(hasDescendant(withText(enrollmentUIModel.sex))))))) + onView(withId(R.id.recyclerView)).check( + matches( + not( + recyclerChildViews( + hasItem( + hasDescendant( + withText(enrollmentUIModel.sex) + ) + ) + ) + ) + ) + ) } @@ -294,14 +357,17 @@ class TeiDashboardRobot : BaseRobot() { val adapter: RecyclerView.Adapter = recyclerView.adapter as RecyclerView.Adapter for (position in 0.. eventViewModel.displayOrganisationUnit(program) } ?: true, + ?.let { program -> eventViewModel.displayOrganisationUnit(program) } + ?: true, onSyncIconClick = { eventViewModel.eventSyncClicked.value = it.event?.uid() }, @@ -65,6 +68,7 @@ class ProgramEventDetailLiveAdapter( }, ) ListCard( + modifier = Modifier.testTag("EVENT_ITEM"), listAvatar = card.avatar, title = ListCardTitleModel(text = card.title), lastUpdated = card.lastUpdated,