appium / appium-flutter-driver

Appium Flutter Driver is a test automation tool for Flutter apps on multiple platforms/OSes. Appium Flutter Driver is part of the Appium mobile test automation tool maintained by community
MIT License
463 stars 184 forks source link

Unable to see some Android Native permission popups while running automation. #609

Open pothurajtharun opened 1 year ago

pothurajtharun commented 1 year ago

Prerequisite: External USB drive is connected to the mobile device and the automation scripts are running wireless.

Description: I'm running an flutter debug android mobile application which needs some native OS permissions to perform some operations to the connected USB drive.

Test Environment:

Prerequisite: User is connected an external USB drive to the Mobile.

Steps followed:

  1. Initially user will be in FLUTTER context.
  2. Perform some click operation on flutter elements in the FTUE screens.
  3. After FTUE screens, user will redirect to android settings permission screen.
  4. Switch to NATIVE_APP context and click on android native switch_widget button.
  5. Click OK button(android:id/button2) element Xpath as per the logs.

Issue: The moment user click on the above button, a pop up(Usb Access) should display. Only while running the test scripts through appium the pop is not displayed.

Note: The same flow if you perform manually then the pop up is displayed without any issues.

Attached logs for both:

Appium.log

Manual_ADB.log

Please take a look on both logs and let me know if anything is needed.

Thanks!

KazuCocoa commented 1 year ago

Around these lines?

10-23 12:29:45.873 18941 18973 I appium  : FindElement command
10-23 12:29:45.880 18941 18973 I appium  : method: 'id', selector: 'android:id/button2'
10-23 12:29:45.881 18941 18973 I appium  : Waiting up to 10000ms for the device to idle
10-23 12:29:45.927 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":{"ELEMENT":"00000000-0000-0089-ffff-ffff00000834","element-6066-11e4-a52e-4f735466cecf":"00000000-0000-0089-ffff-ffff00000834"}}
10-23 12:29:45.949 18941 18973 I appium  : channel read: GET /session/de650097-c608-4e83-94d1-ab8cb6565f60/element/00000000-0000-0089-ffff-ffff00000834/attribute/displayed
10-23 12:29:45.953 18941 18973 I appium  : GetElementAttribute command
10-23 12:29:45.966 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":"true"}
10-23 12:29:45.995 18941 18973 I appium  : channel read: POST /session/de650097-c608-4e83-94d1-ab8cb6565f60/element
10-23 12:29:45.998 18941 18973 I appium  : FindElement command
10-23 12:29:46.003 18941 18973 I appium  : method: 'id', selector: 'android:id/button2'
10-23 12:29:46.004 18941 18973 I appium  : Waiting up to 10000ms for the device to idle
10-23 12:29:46.039 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":{"ELEMENT":"00000000-0000-0089-ffff-ffff00000834","element-6066-11e4-a52e-4f735466cecf":"00000000-0000-0089-ffff-ffff00000834"}}
10-23 12:29:46.064 18941 18973 I appium  : channel read: GET /session/de650097-c608-4e83-94d1-ab8cb6565f60/element/00000000-0000-0089-ffff-ffff00000834/rect
10-23 12:29:46.067 18941 18973 I appium  : GetRect command
10-23 12:29:46.087 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":{"height":149,"width":192,"x":608,"y":1322}}
10-23 12:29:46.113 18941 18973 I appium  : channel read: POST /session/de650097-c608-4e83-94d1-ab8cb6565f60/element
10-23 12:29:46.116 18941 18973 I appium  : FindElement command
10-23 12:29:46.120 18941 18973 I appium  : method: 'id', selector: 'android:id/button2'
10-23 12:29:46.121 18941 18973 I appium  : Waiting up to 10000ms for the device to idle
10-23 12:29:46.153 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":{"ELEMENT":"00000000-0000-0089-ffff-ffff00000834","element-6066-11e4-a52e-4f735466cecf":"00000000-0000-0089-ffff-ffff00000834"}}
10-23 12:29:46.175 18941 18973 I appium  : channel read: GET /session/de650097-c608-4e83-94d1-ab8cb6565f60/element/00000000-0000-0089-ffff-ffff00000834/rect
10-23 12:29:46.178 18941 18973 I appium  : GetRect command
10-23 12:29:46.195 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":{"height":149,"width":192,"x":608,"y":1322}}
10-23 12:29:46.219 18941 18973 I appium  : channel read: POST /session/de650097-c608-4e83-94d1-ab8cb6565f60/element
10-23 12:29:46.223 18941 18973 I appium  : FindElement command
10-23 12:29:46.227 18941 18973 I appium  : method: 'id', selector: 'android:id/button2'
10-23 12:29:46.228 18941 18973 I appium  : Waiting up to 10000ms for the device to idle
10-23 12:29:46.261 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":{"ELEMENT":"00000000-0000-0089-ffff-ffff00000834","element-6066-11e4-a52e-4f735466cecf":"00000000-0000-0089-ffff-ffff00000834"}}
10-23 12:29:46.282 18941 18973 I appium  : channel read: GET /session/de650097-c608-4e83-94d1-ab8cb6565f60/element/00000000-0000-0089-ffff-ffff00000834/rect
10-23 12:29:46.285 18941 18973 I appium  : GetRect command
10-23 12:29:46.301 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":{"height":149,"width":192,"x":608,"y":1322}}
10-23 12:29:46.325 18941 18973 I appium  : channel read: POST /session/de650097-c608-4e83-94d1-ab8cb6565f60/actions
10-23 12:29:46.328 18941 18973 I appium  : W3CActions command
10-23 12:29:46.352  1018  2449 I sensors-hal: [ssc_utils]get_qmi_debug_flag:243, support_qmi_debug : false
10-23 12:29:46.356 18941 18973 I appium  : [4639248 (success)] Synthesized: MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=704.0, y[0]=1396.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=4639248, downTime=4639247, deviceId=0, source=0x1002, displayId=0, eventId=-421964328 }
10-23 12:29:46.364 18941 18973 I appium  : [4639256 (success)] Synthesized: MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=704.0, y[0]=1396.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=4639256, downTime=4639247, deviceId=0, source=0x1002, displayId=0, eventId=-341564541 }
10-23 12:29:46.371 18941 18973 I appium  : AppiumResponse: {"sessionId":"de650097-c608-4e83-94d1-ab8cb6565f60","value":null}
10-23 12:29:46.385  1002  1126 D android.hardware.audio.service: AcdbCmdSetOnlineData: Unable to set delta file data!
10-23 12:29:46.385  1002  1126 D android.hardware.audio.service: [ACDB Command]->[AcdbCmdSetAudProcInstanceData]->Unable to save delta file data
10-23 12:29:46.385  1002  1126 E ACDB-LOADER: [acdb_loader_store_set_audio_cal] ACDB settting parameters failed -1
10-23 12:29:46.397 19160 19160 D com.xyz.xyz.discovery.USBDevice: requestUsbPermission : onReceive : com.xyz.xyz.flutter_rust_bridge_template.USB_PERMISSION
10-23 12:29:46.422 18941 18973 I appium  : channel read: POST /session/de650097-c608-4e83-94d1-ab8cb6565f60/element
10-23 12:29:46.425 18941 18973 I appium  : FindElement command
10-23 12:29:46.428  4576  4576 I GoogleInputMethodService: GoogleInputMethodService.onFinishInput():3260 
10-23 12:29:46.429 18941 18973 I appium  : method: 'xpath', selector: '//android.widget.Button[contains(@text,'Use this folder')]'

I don't see any weird behavior in the log perspective. If you could click the element in NATIVE_APP context, or do it in a release build (not flutter debugger enabled), it might be Flutter internal handler related

pothurajtharun commented 1 year ago

@KazuCocoa, The above scenario performed on android debug build. When i perform the above mentioned steps manually i can see a pop up. But only when the app is launched through the appium-flutter-driver and followed the above steps the pop up is not displayed.

So do you mean that in android debug mode builds something needs to be handle at flutter side ?

KazuCocoa commented 1 year ago

If Android OS handled events by screen and via AccessibilityNodeInfo (native app context) or Dart VM (Flutter) differently, such a difference could present because Appium achieves automation via OS's accessibility functionality in the native app context. Not sure if the application layer or Appium can inject the behavior. You could try out the same flow in the native app context only with a release build to check it could be by debug functions by Android/Flutter. so it is to find possible issues.

only when the app is launched through the appium-flutter-driver and followed the above steps the pop up is not displayed.

The app was launched by below command, so you could launch the app with the same command and follow the same steps manually to check if the launching step itself is an issue.

/Users/tharunpothuraj/Library/Android/sdk/platform-tools/adb -P 5037 -s 192.168.1.192:5555 shell am start -W -n com.example.xyz/com.example.xyz.MainActivity -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000

pothurajtharun commented 1 year ago

The app was launched by below command, so you could launch the app with the same command and follow the same steps manually to check if the launching step itself is an issue.

I launched the app as mentioned in the above comment and after that followed the steps manually and able to see the popup. So the issue is not with app launching.

You could try out the same flow in the native app context only with a release build to check it could be by debug functions by Android/Flutter.

@KazuCocoa This statement you mean launch the app with automationName:Uiautomator2 and continue with NATIVE_APP context ? Because the release mode flutter apk won't print the observatory URI in device log so the test may fail with automationName:Flutter

KazuCocoa commented 1 year ago

launch the app with automationName:Uiautomator2 and continue with NATIVE_APP context ? Because the release mode flutter apk won't print the observatory URI in device log so the test may fail with automationName:Flutter

Ideally, yes. I'm not sure your app could achieve your scenario with a release module, but it would help. If still the same thing occurs, then the root cause may be between Flutter <-> native android (triggered event via Android's internal event via accessibilitynodeinfo or something)

pothurajtharun commented 11 months ago

I tried with flutter release mode build as well with automationName:Uiautomator2. The same issue in debug mode build is also observed in release mode build. Pop up is not displayed while executing the scripts.

I'm not sure why the issue only happens when we launch the app programmatically and execute the scripts. Manually it work pretty fine as expected.

appium-android.log logcat-2023_11_20_22_08_03.log

@KazuCocoa, could you please help me with some pointers if you would have come across with this kind of issues in past ?

Thanks!

KazuCocoa commented 11 months ago

I tried with flutter release mode build as well with automationName:Uiautomator2. The same issue in debug mode build is also observed in release mode build. Pop up is not displayed while executing the scripts.

It could indicate actions via androidx.test.uiautomator:uiautomator (e.g. https://developer.android.com/reference/androidx/test/uiautomator/UiObject2#click() ) or https://developer.android.com/reference/android/view/MotionEvent was not able to fire the popup event I guess.

How did you achieve the click action? Common methods are element.click or tap with w3c actions.

Possibly, you may need to debug the app under test with breakpoints since it is Android OS internal and the app under test's behavior related.

pothurajtharun commented 11 months ago

@KazuCocoa Just to answer your question the click operation is performed as follows. I will debug the scenario further.

private void doTap(Point point, long duration) {
    Sequence tap =
        new Sequence(FINGER, 1)
            .addAction(FINGER.createPointerMove(ofMillis(0), viewport(), point.x, point.y))
            .addAction(FINGER.createPointerDown(LEFT.asArg()))
            .addAction(new Pause(FINGER, ofMillis(duration)))
            .addAction(FINGER.createPointerUp(LEFT.asArg()));
    driver.perform(Collections.singletonList(tap));
  }

Is there any difference between these two ways element.clickor tap with w3c actions to fire the popup event ?

KazuCocoa commented 11 months ago

I don't recall the details, but you already tried the most low-level action with MotionEvent. Then, maybe the .click has no much difference in the level.

Then, i guess the popup was not triggered or closed immediately by the MotionEvent by some reason. Perhaps... debugging the app under test might help. For example, if a method in the test app is actually triggered, then, how the UI would be. This debugging means by adding breakpoints and attaching the ANdroid Studio's debugger to the app etc.