android / android-test

An extensive framework for testing Android apps
https://android.github.io/android-test
Apache License 2.0
1.14k stars 306 forks source link

Espresso not triggering SelectionTracker #1382

Open aljohnston112 opened 2 years ago

aljohnston112 commented 2 years ago

Description

A longClick() with RecyclerViewActions.actionOnItemAtPosition does not trigger the selection of the item in a RecyclerView that has been passed to a SelectionTracker.

Steps to Reproduce

Set up a SelectionTracker with a RecyclerView in a Fragment.

Use launchActivity and onActivity set the Fragment to the Activity.

longClick() an item in the RecyclerView

Notice that nothing was selected.

It is worth noting that if debugging, and at a breakpoint, if you manually longClick(), a selection will be triggered.

Expected Results

The SelectionTracker to be triggered by a longClick() on an item in the RecyclerView passed to it, therefore triggering a selection.

Actual Results

The SelectionTracker was not triggered by a longClick() on an item in the RecyclerView passed to it, and a selection was not triggered.

AndroidX Test and Android OS Versions

androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

Android 11

Here is some context:

https://stackoverflow.com/questions/72538316/how-do-you-use-espresso-to-test-a-selectiontracker?noredirect=1#comment128138564_72538316

aljohnston112 commented 2 years ago
        val cdl  = CountDownLatch(1)
        scenario.onActivity {
            val recyclerView = it.findViewById<RecyclerView>(R.id.fragment_editor_recycler_view)
            val ite = recyclerView.getChildAt(0)
            ite.getLocationOnScreen(location)
            cdl.countDown()
        }
        cdl.await()
        onView(isRoot()).perform(
            GeneralClickAction(
                Tap.LONG,
                { FloatArray(location.size){ i -> (location[i]+1).toFloat() } },
                Press.FINGER,
                InputDevice.SOURCE_UNKNOWN,
                MotionEvent.BUTTON_PRIMARY
            )
        )

Long click still does not trigger SelectionTracker when clicked through the root view. I have verified it is connected to the Fragment's RecyclerView. This is clearly a bug.

SimonMarquis commented 1 year ago

InputDevice seems to be the culprit. Changing the default value to something like SOURCE_TOUCHSCREEN or SOURCE_MOUSE triggered the SelectionTracker for us.

- ViewActions.click()
+ ViewActions.click(InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.BUTTON_PRIMARY)

I'm not sure what changed between 1.5.0 betas and 1.5.0 stable though.

kozmotronik commented 1 week ago

The @SimonMarquis 's tip helped me overcome this issue. However, in my case, I have to long click in order to trigger selection tracker. This is why ViewActions.click was not suitable for my case. The ViewActions.longClick does not allow to specify the InputDevice either. So I ended up with the following code and got it working for selection tracker:

onView(withId(R.id.recyclerView)).perform(actionOnItemAtPosition(0, new GeneralClickAction(
                Tap.LONG, GeneralLocation.CENTER, Press.FINGER, InputDevice.SOURCE_TOUCHSCREEN,
                MotionEvent.BUTTON_PRIMARY
        )));

Although there is some workarounds like this, the framework should get needed peaces so that it handles well triggering of the selection tracker without extra boilerplate code.