App-Crawler and Firebase Robo Test can't perform a click on a RecyclerView. What am I doing wrong?

69 Views Asked by At

I'm testing my android app with an App-Crawler Robo Script Tester to debug my roboscripts. Firebase Robo Test shows this error:

action {
11-25 19:42:06.495: I/Robo(6000):   target_action {
11-25 19:42:06.495: I/Robo(6000):     action_parameters {
11-25 19:42:06.495: I/Robo(6000):       directive {
11-25 19:42:06.495: I/Robo(6000):       }
11-25 19:42:06.495: I/Robo(6000):       view_position {
11-25 19:42:06.495: I/Robo(6000):       }
11-25 19:42:06.495: I/Robo(6000):     }
11-25 19:42:06.495: I/Robo(6000):     target {
11-25 19:42:06.495: I/Robo(6000):       description {
11-25 19:42:06.495: I/Robo(6000):         android_class_name: "android.view.ViewGroup"
11-25 19:42:06.495: I/Robo(6000):         class_name: "androidx.recyclerview.widget.RecyclerView"
11-25 19:42:06.495: I/Robo(6000):         component_type: 1
11-25 19:42:06.495: I/Robo(6000):         identifiers {
11-25 19:42:06.495: I/Robo(6000):           child_position: 1
11-25 19:42:06.495: I/Robo(6000):           mode_agnostic_sequence: "0.0.0.0.0.0.0.0.0.0.2"
11-25 19:42:06.495: I/Robo(6000):           mode_specific_sequence: "0.0.1.0.0.0.0.1.0.0.1"
11-25 19:42:06.495: I/Robo(6000):         }
11-25 19:42:06.495: I/Robo(6000):         input_type: 1
11-25 19:42:06.495: I/Robo(6000):         resource_name: "house_intellect.nfc_reports:id/calendars_list"
11-25 19:42:06.495: I/Robo(6000):       }
11-25 19:42:06.495: I/Robo(6000):       state {
11-25 19:42:06.495: I/Robo(6000):         is_enabled: true
11-25 19:42:06.495: I/Robo(6000):         is_focusable: true
11-25 19:42:06.495: I/Robo(6000):         is_shown: true
11-25 19:42:06.495: I/Robo(6000):         visible_bounds {
11-25 19:42:06.495: I/Robo(6000):           bottom: 2541
11-25 19:42:06.495: I/Robo(6000):           left: 42
11-25 19:42:06.495: I/Robo(6000):           right: 1038
11-25 19:42:06.495: I/Robo(6000):           top: 779
11-25 19:42:06.495: I/Robo(6000):         }
11-25 19:42:06.495: I/Robo(6000):       }
11-25 19:42:06.495: I/Robo(6000):     }
11-25 19:42:06.495: I/Robo(6000):     type: 1
11-25 19:42:06.495: I/Robo(6000):   }
11-25 19:42:06.495: I/Robo(6000): }
11-25 19:42:06.496: W/Robo(6000): Notifying controller of internal platform error.
11-25 19:42:06.496: W/Robo(6000): androidx.test.tools.crawler.platform.common.InternalPlatformException: View position is set but the screen element is neither a RecyclerView or an AdapterView.
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.hybrid.HybridInteractionController.perform(HybridInteractionController.java:34)
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.hybrid.HybridInteractionController.click(HybridInteractionController.java:10)
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.ActionExecutor.execute(ActionExecutor.java:59)
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.ActionExecutor.performAction(ActionExecutor.java:4)
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.RemotePlatform.handlePerformAction(RemotePlatform.java:22)
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.RemotePlatform.messageLoop(RemotePlatform.java:59)
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.RemotePlatform.lambda$startCrawlAndWaitUntilFinished$0$androidx-test-tools-crawler-platform-RemotePlatform(RemotePlatform.java:1)
11-25 19:42:06.496: W/Robo(6000):   at androidx.test.tools.crawler.platform.RemotePlatform$$ExternalSyntheticLambda1.run(Unknown Source:6)
11-25 19:42:06.496: W/Robo(6000):   at java.lang.Thread.run(Thread.java:920)

App-Crawler shows this error:

FAILED: Found 1 crash.
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/widget/RecyclerView;
FATAL EXCEPTION: ControllerMessenger
Process: house_intellect.nfc_reports, PID: 13281
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/widget/RecyclerView;
        at androidx.test.espresso.contrib.RecyclerViewActions$ActionOnItemAtPositionViewAction.getConstraints(RecyclerViewActions.java:5)
        at androidx.test.espresso.ViewInteraction$SingleExecutionViewAction.getConstraints(ViewInteraction.java:6)
        at androidx.test.espresso.ViewInteraction.a(ViewInteraction.java:57)
        at androidx.test.espresso.ViewInteraction.a(ViewInteraction.java:96)
        at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:3)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.widget.RecyclerView" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/androidx.test.tools.crawler-1/base.apk", zip file "/data/app/house_intellect.nfc_reports-2/base.apk"],nativeLibraryDirectories=[/data/app/androidx.test.tools.crawler-1/lib/x86, /data/app/house_intellect.nfc_reports-2/lib/x86, /system/lib, /vendor/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

My RecyclerView xml:

<androidx.recyclerview.widget.RecyclerView
                android:id="@+id/calendars_list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/margin_medium"
                android:fadeScrollbars="false"
                android:scrollbars="vertical"
                app:adapter="@{viewModel.availableCalendarsAdapter}"
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                app:layout_constraintBottom_toTopOf="@id/new_calendar"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:listitem="@layout/calendar_layout" />

My roboscript.json:

"actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "timestamp": 1700968034609,
        "actionCode": -1,
        "delayTime": 7000,
        "canScrollTo": false,
        "elementDescriptors": []
      },
      {
        "eventType": "VIEW_CLICKED",
        "timestamp": 1700968042058,
        "replacementText": "",
        "actionCode": -1,
        "delayTime": 0,
        "canScrollTo": false,
        "elementDescriptors": [
          {
            "resourceId": "house_intellect.nfc_reports:id/selectedCalendar",
            "recyclerViewChildPosition": 0,
          },
          {
            "resourceId": "my.package:id/calendars_list",
          },
          {
            "resourceId": "my.package:id/bottom_sheet",
          }
        ]
      }
  ]

My dependencies:

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.3.2'
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.0-alpha01'

I've found some info that the App-Crawler is severely outdated and can't click on androidx recyclerviews without this error, but the Firebase Robo Test at least should be able to click on an item?

What am I doing wrong?

I tried making an Espresso Test from the Android Studio generated roboscript, it works. I also tried with addressing the elements by their respective classes, by ids, both and separately. Firebase Robo Test log seems to identify the recyclerview correctly using the autogenerated roboscript, but the error persists. I tried to wrap recyclerviews in two layers of RelativeLayouts as suggested in another question here on stackOverflow, but haven't had any success. None of my recyclerviews in all of my projects can be tested this way.

1

There are 1 best solutions below

0
On

RecyclerView ViewHolder item clicks proved to be impossible, however after some source code digging I've found out that App-Crawler uses much more trivial code for ViewGroups, and RecyclerView is a ViewGroup. I used groupViewChildPosition for indexed items clicks instead of recyclerViewChildPosition elements suggested by Android Studio Robo Script generator. I've found out as well that problems are not limited by intexing notation, I had to remove every mention of unsupported classes like RecyclerView. This experience allowed me to assume that sometimes App-Crawler can't identify elements not only by class, but by it's "id" as well, that was the case with navigation menu views, so I referenced them by their class only while dropping all other search criteria for good. Here is my resulting working Robo Script snipper for a RecyclerView and a Navigation Menu:

    [
       {
          "eventType":"VIEW_CLICKED",
          "timestamp":1700866615439,
          "replacementText":"",
          "actionCode":-1,
          "delayTime":0,
          "canScrollTo":true,
          "elementDescriptors":[
             {
                "className":"androidx.recyclerview.widget.RecyclerView.ViewHolder",
                "recyclerViewChildPosition":-1,
                "adapterViewChildPosition":-1,
                "groupViewChildPosition":0,
                "resourceId":"",
                "contentDescription":"",
                "text":""
             },
             {
                "resourceId":"house_intellect.nfc_reports:id/calendars_list",
                "recyclerViewChildPosition":-1,
                "adapterViewChildPosition":-1,
                "groupViewChildPosition":1,
                "contentDescription":"",
                "text":""
             },
             {
                "className":"android.widget.RelativeLayout",
                "recyclerViewChildPosition":-1,
                "adapterViewChildPosition":-1,
                "groupViewChildPosition":0,
                "contentDescription":"",
                "text":""
             }
          ]
       },
       {
          "eventType":"VIEW_CLICKED",
          "timestamp":1596381450162,
          "replacementText":"",
          "actionCode":-1,
          "delayTime":0,
          "canScrollTo":false,
          "elementDescriptors":[
             {
                "className":"com.google.android.material.internal.NavigationMenuItemView",
                "groupViewChildPosition":4,
                "contentDescription":"",
                "text":""
             },
             {
                "className":"com.google.android.material.internal.NavigationMenuView",
                "contentDescription":"",
                "text":""
             },
             {
                "className":"com.google.android.material.navigation.NavigationView",
                "contentDescription":"",
                "text":""
             }
          ]
       }
    ]