Skip to content

Commit

Permalink
Fix #2536: Introduce a central utility for matching item in RecyclerV…
Browse files Browse the repository at this point in the history
…iew (#5391)

<!-- READ ME FIRST: Please fill in the explanation section below and
check off every point from the Essential Checklist! -->
## Explanation
Fix #2536

I worked on the below functions renaming the title and adding an
argument for the recyclerviewId to each function to make it reusable, I
also added kdocs to help understand the functions.
P.S:- I created the functions in the RecyclerviewMatcher class.
 
![Screenshot 2024-04-30 at 01 24
45](https://github.com/oppia/oppia-android/assets/54560535/6a0464e0-e72f-4516-83e1-3a53d2025a6b)

![Screenshot 2024-04-30 at 01 24
26](https://github.com/oppia/oppia-android/assets/54560535/34332586-e082-4991-9b6b-b8f8c647e7d0)

![Screenshot 2024-04-30 at 01 24
57](https://github.com/oppia/oppia-android/assets/54560535/7090b959-fb45-4787-9957-7e182d47a042)


## Essential Checklist
<!-- Please tick the relevant boxes by putting an "x" in them. -->
- [x] The PR title and explanation each start with "Fix #bugnum: " (If
this PR fixes part of an issue, prefix the title with "Fix part of
#bugnum: ...".)
- [x] Any changes to
[scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets)
files have their rationale included in the PR explanation.
- [x] The PR follows the [style
guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android
Studio
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and
is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).
  • Loading branch information
deonwaju authored May 8, 2024
1 parent 60ed74c commit a818170
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import android.content.Intent
import android.view.View
import android.view.ViewParent
import android.widget.FrameLayout
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.NestedScrollView
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ActivityScenario.launch
import androidx.test.core.app.ApplicationProvider
Expand All @@ -21,9 +19,7 @@ import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent
Expand Down Expand Up @@ -67,6 +63,12 @@ import org.oppia.android.app.model.ScreenName
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.profile.ProfileChooserActivity
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.scrollToPosition
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.verifyItemDisplayedOnListItem
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.verifyItemDisplayedOnListItemDoesNotExist
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.verifyTextInDialog
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.verifyTextOnListItemAtPosition
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.verifyTextViewOnListItemAtPositionDoesNotExist
import org.oppia.android.app.settings.profile.ProfileListActivity
import org.oppia.android.app.shim.ViewBindingShimModule
import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule
Expand Down Expand Up @@ -157,6 +159,8 @@ class AdministratorControlsActivityTest {
@Inject
lateinit var context: Context

private val administratorControlsListRecyclerViewId: Int = R.id.administrator_controls_list

@get:Rule
val activityTestRule = ActivityTestRule(
AdministratorControlsActivity::class.java,
Expand Down Expand Up @@ -214,11 +218,13 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
verifyItemDisplayedOnAdministratorControlListItem(
verifyItemDisplayedOnListItem(
recyclerViewId = administratorControlsListRecyclerViewId,
itemPosition = 0,
targetView = R.id.general_text_view
)
verifyTextOnAdministratorListItemAtPosition(
verifyTextOnListItemAtPosition(
recyclerViewId = administratorControlsListRecyclerViewId,
itemPosition = 0,
targetViewId = R.id.edit_account_text_view,
stringIdToMatch = R.string.administrator_controls_edit_account
Expand All @@ -236,13 +242,15 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
verifyItemDisplayedOnAdministratorControlListItemDoesNotExist(
verifyItemDisplayedOnListItemDoesNotExist(
recyclerViewId = administratorControlsListRecyclerViewId,
itemPosition = 0,
targetView = R.id.general_text_view
)
verifyTextViewOnAdministratorListItemAtPositionDoesNotExist(
verifyTextViewOnListItemAtPositionDoesNotExist(
recyclerViewId = administratorControlsListRecyclerViewId,
itemPosition = 0,
targetViewId = R.id.edit_account_text_view,
targetViewId = R.id.edit_account_text_view
)
}
}
Expand All @@ -255,11 +263,13 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
verifyItemDisplayedOnAdministratorControlListItem(
verifyItemDisplayedOnListItem(
recyclerViewId = administratorControlsListRecyclerViewId,
itemPosition = 1,
targetView = R.id.profile_management_text_view
)
verifyTextOnAdministratorListItemAtPosition(
verifyTextOnListItemAtPosition(
recyclerViewId = administratorControlsListRecyclerViewId,
itemPosition = 1,
targetViewId = R.id.edit_profiles_text_view,
stringIdToMatch = R.string.administrator_controls_edit_profiles
Expand All @@ -275,7 +285,7 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(position = 3)
scrollToPosition(position = 3, recyclerViewId = administratorControlsListRecyclerViewId)
onView(withId(R.id.log_out_text_view)).perform(click())
verifyTextInDialog(textInDialogId = R.string.log_out_dialog_message)
onView(withText(R.string.log_out_dialog_okay_button)).perform(click())
Expand All @@ -291,7 +301,7 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(position = 2)
scrollToPosition(position = 2, recyclerViewId = administratorControlsListRecyclerViewId)
onView(withId(R.id.app_version_text_view)).perform(click())
intended(hasComponent(AppVersionActivity::class.java.name))
}
Expand Down Expand Up @@ -320,7 +330,7 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(position = 3)
scrollToPosition(position = 3, recyclerViewId = administratorControlsListRecyclerViewId)
onView(withId(R.id.log_out_text_view)).perform(click())
verifyTextInDialog(textInDialogId = R.string.log_out_dialog_message)
verifyTextInDialog(textInDialogId = R.string.log_out_dialog_okay_button)
Expand All @@ -336,9 +346,9 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(position = 3)
scrollToPosition(position = 3, recyclerViewId = administratorControlsListRecyclerViewId)
onView(isRoot()).perform(orientationLandscape())
scrollToPosition(position = 3)
scrollToPosition(position = 3, recyclerViewId = administratorControlsListRecyclerViewId)
onView(withId(R.id.log_out_text_view)).perform(click())
verifyTextInDialog(textInDialogId = R.string.log_out_dialog_message)
verifyTextInDialog(textInDialogId = R.string.log_out_dialog_okay_button)
Expand All @@ -354,7 +364,7 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(position = 3)
scrollToPosition(position = 3, recyclerViewId = administratorControlsListRecyclerViewId)
onView(withId(R.id.log_out_text_view)).perform(click())
onView(isRoot()).perform(orientationLandscape())
verifyTextInDialog(textInDialogId = R.string.log_out_dialog_message)
Expand All @@ -371,7 +381,7 @@ class AdministratorControlsActivityTest {
)
).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(position = 3)
scrollToPosition(position = 3, recyclerViewId = administratorControlsListRecyclerViewId)
onView(withId(R.id.log_out_text_view)).perform(click())
verifyTextInDialog(textInDialogId = R.string.log_out_dialog_message)
onView(withText(R.string.log_out_dialog_cancel_button)).perform(click())
Expand Down Expand Up @@ -407,7 +417,7 @@ class AdministratorControlsActivityTest {
)

// Open the app version fragment
scrollToPosition(position = 3)
scrollToPosition(position = 3, recyclerViewId = administratorControlsListRecyclerViewId)
onView(withId(R.id.app_version_text_view)).perform(click())

// Check that the multipane container has only one child and it is the app version fragment
Expand Down Expand Up @@ -880,70 +890,6 @@ class AdministratorControlsActivityTest {
return view.getParent()
}

private fun verifyItemDisplayedOnAdministratorControlListItem(
itemPosition: Int,
targetView: Int
) {
onView(
atPositionOnView(
recyclerViewId = R.id.administrator_controls_list,
position = itemPosition,
targetViewId = targetView
)
).check(matches(isDisplayed()))
}

private fun verifyItemDisplayedOnAdministratorControlListItemDoesNotExist(
itemPosition: Int,
targetView: Int
) {
onView(
atPositionOnView(
recyclerViewId = R.id.administrator_controls_list,
position = itemPosition,
targetViewId = targetView
)
).check(doesNotExist())
}

private fun verifyTextOnAdministratorListItemAtPosition(
itemPosition: Int,
targetViewId: Int,
@StringRes stringIdToMatch: Int
) {
onView(
atPositionOnView(
recyclerViewId = R.id.administrator_controls_list,
position = itemPosition,
targetViewId = targetViewId
)
).check(matches(withText(context.getString(stringIdToMatch))))
}

private fun verifyTextViewOnAdministratorListItemAtPositionDoesNotExist(
itemPosition: Int,
targetViewId: Int,
) {
onView(
atPositionOnView(
recyclerViewId = R.id.administrator_controls_list,
position = itemPosition,
targetViewId = targetViewId
)
).check(doesNotExist())
}

private fun scrollToPosition(position: Int) {
onView(withId(R.id.administrator_controls_list))
.perform(scrollToPosition<RecyclerView.ViewHolder>(position))
}

private fun verifyTextInDialog(@StringRes textInDialogId: Int) {
onView(withText(context.getString(textInDialogId)))
.inRoot(isDialog())
.check(matches(isDisplayed()))
}

// TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them.
@Singleton
@Component(
Expand Down
Loading

0 comments on commit a818170

Please sign in to comment.