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
465 stars 184 forks source link

Error: Cannot determine the Dart Observatory URL after 10 retries. #611

Closed pothurajtharun closed 1 year ago

pothurajtharun commented 1 year ago

Hi All,

Description: While running the automation scripts on iOS real device, the app is launched on real device and after some time throwing an error Cannot determine the Dart Observatory URL after 10 retries.. It is unable to find the elements after launching the app.

Test Environment:

Attaching the log: appium-port-4779.log

Note: The same test environment works fine on flutter Android application on real devices.

KazuCocoa commented 1 year ago

It seems like the ios app hadn't printed the opbservatory url. Was it a profile build?

https://github.com/appium/appium-flutter-driver?tab=readme-ov-file#note

pothurajtharun commented 1 year ago

Hi @KazuCocoa , Yeah it is profile build. To print the observatory URL do we need to output the URL to console or some thing else from the iOS app development side specifically ? Because the same code which built the debug build for android it works fine.

Can you please share any input how to make the iOS app to print the observatory URL ?

Thanks!

pothurajtharun commented 1 year ago

@KazuCocoa , I have tried the ways mentioned here Several Ways To Start App & Notes as follows.

Mobile Activate App:

driver = new IOSDriver(remote, mobileCapabilities);  //session without app capability and automationName:Flutter
((SupportsContextSwitching) driver).context("NATIVE_APP");
((IOSDriver) driver).installApp("/usr/local/automation/MobileApps/ios/corbita.ipa"); //App installed
((IOSDriver) driver).activateApp("com.xyz.abcenterprise"); //App launched.

After these steps also no observatory URL was written in logs.

Logs : Mobile_Activate_App.log

Flutter_AppLaunch:

driver = new IOSDriver(remote, mobileCapabilities);  //session without app capability and automationName:Flutter
((SupportsContextSwitching) driver).context("NATIVE_APP");
((IOSDriver) driver).installApp("/usr/local/automation/MobileApps/ios/corbita.ipa"); //App installed
((SupportsContextSwitching) driver).context("FLUTTER");
driver.executeScript("flutter:launchApp", "253cb28df38fb7a0d7c97decac32071907735310","com.xyz.abcenterprise"); //App launched.

After these steps also no observatory URL was written in logs.

Logs : Flutter_AppLaunch.log

In the second approach, please let me knowis it the correct way of passing the parameters ?

Thanks!

KazuCocoa commented 1 year ago

What I know of was just build as a profile build, and launch the app with https://github.com/appium/appium-flutter-driver#several-ways-to-start-an-application . If not available on your environment case, maybe something is needed.

Possibly https://github.com/appium/appium-flutter-driver/issues/393#issuecomment-1692686293 would help, especially ios-deploy to the flutter's issue to start the iOS app process as debug mode.

pothurajtharun commented 1 year ago

Hi @KazuCocoa ,

I used go-ios to install and launch the flutter ios app(profile mode) as follows

ios install --path=/usr/local/automation/MobileApps/ios/xyz.ipa && ios launch com.xyz.abcenterprise

After launching the app Error: Cannot determine the Dart Observatory URL after 10 retries. is not seen and the execution continued further as follows.

  1. Switch to NATIVE_APP context.
  2. Click the element as per the logs {"using":"accessibility id","value":"Allow"} is clicked.
  3. Assert element as per the logs (//XCUIElementTypeImage[contains(@name,'Welcome to xyz 2.0')] is displayed.
  4. Switch to FLUTTER context.
  5. Click the flutter element ?

After 5th step flutter element is on screen and it's not clicked and got the below error:

2023-10-28 13:59:03:314 [FlutterDriver] >>> {"command":"tap","isRegExp":"false","label":"Next","finderType":"BySemanticsLabel"}
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)] Encountered internal error running command: TypeError: Cannot read properties of null (reading 'executeSocketCommand')
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)]     at FlutterDriver.executeElementCommand (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/sessions/observatory.ts:194:35)
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)]     at FlutterDriver.tapEl (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/commands/gesture.ts:17:21)
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)]     at FlutterDriver.click (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/commands/gesture.ts:5:29)
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)]     at commandExecutor (/Users/tharunpothuraj/node_modules/@appium/base-driver/lib/basedriver/driver.ts:107:18)
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)]     at /Users/tharunpothuraj/node_modules/async-lock/lib/index.js:171:12
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)]     at AsyncLock._promiseTry (/Users/tharunpothuraj/node_modules/async-lock/lib/index.js:304:31)
2023-10-28 13:59:03:359 [FlutterDriver@907d (c5251ec9)]     at exec (/Users/tharunpothuraj/node_modules/async-lock/lib/index.js:170:9)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at AsyncLock.acquire (/Users/tharunpothuraj/node_modules/async-lock/lib/index.js:187:3)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at FlutterDriver.executeCommand (/Users/tharunpothuraj/node_modules/@appium/base-driver/lib/basedriver/driver.ts:123:39)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at processTicksAndRejections (node:internal/process/task_queues:95:5)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at FlutterDriver.executeCommand (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/driver.ts:184:16)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at defaultBehavior (/usr/local/lib/node_modules/appium/lib/appium.js:722:14)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at AppiumDriver.executeWrappedCommand (/usr/local/lib/node_modules/appium/lib/appium.js:828:16)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at AppiumDriver.executeCommand (/usr/local/lib/node_modules/appium/lib/appium.js:734:17)
2023-10-28 13:59:03:360 [FlutterDriver@907d (c5251ec9)]     at asyncHandler (/usr/local/lib/node_modules/appium/node_modules/@appium/base-driver/lib/protocol/protocol.js:393:19)
2023-10-28 13:59:03:367 [HTTP] <-- POST /session/c5251ec9-fa02-447d-89cb-632ac2edbf9a/element/eyJpc1JlZ0V4cCI6ImZhbHNlIiwibGFiZWwiOiJOZXh0IiwiZmluZGVyVHlwZSI6IkJ5U2VtYW50aWNzTGFiZWwifQ%3D%3D/click 500 53 ms - 626
2023-10-28 13:59:03:367 [HTTP] 
2023-10-28 13:59:03:378 [HTTP] --> GET /session/c5251ec9-fa02-447d-89cb-632ac2edbf9a/screenshot
2023-10-28 13:59:03:378 [HTTP] {}

Attaching the full appium log appium-port-4779.log

Note: All these executions are performed over Wi-Fi.

Thanks!

KazuCocoa commented 1 year ago

What's about using ios-deploy as https://github.com/flutter/flutter/blob/888b7b9b19642e18e001e3edfa9438c2624d8773/packages/flutter_tools/lib/src/ios/ios_deploy.dart#L121-L165 ? That was the Flutter team's command to launch an ios according to the https://github.com/appium/appium-flutter-driver/issues/393#issuecomment-1692686293 's link.

pothurajtharun commented 1 year ago

@KazuCocoa , I tried with the following ios-deploy command.

ios-deploy --debug --justlaunch --bundle /usr/local/automation/MobileApps/ios/Payload/Runner.app

The app is launched successfully and performed the steps as mentioned above and got the same error

2023-10-30 05:52:44:988 [FlutterDriver] Executing Flutter driver command 'click'
2023-10-30 05:52:44:988 [FlutterDriver] >>> {"command":"tap","isRegExp":"false","label":"Next","finderType":"BySemanticsLabel"}
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)] Encountered internal error running command: TypeError: Cannot read properties of null (reading 'executeSocketCommand')
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at FlutterDriver.executeElementCommand (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/sessions/observatory.ts:194:35)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at FlutterDriver.tapEl (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/commands/gesture.ts:17:21)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at FlutterDriver.click (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/commands/gesture.ts:5:29)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at commandExecutor (/Users/tharunpothuraj/node_modules/@appium/base-driver/lib/basedriver/driver.ts:107:18)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at /Users/tharunpothuraj/node_modules/async-lock/lib/index.js:171:12
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at AsyncLock._promiseTry (/Users/tharunpothuraj/node_modules/async-lock/lib/index.js:304:31)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at exec (/Users/tharunpothuraj/node_modules/async-lock/lib/index.js:170:9)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at AsyncLock.acquire (/Users/tharunpothuraj/node_modules/async-lock/lib/index.js:187:3)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at FlutterDriver.executeCommand (/Users/tharunpothuraj/node_modules/@appium/base-driver/lib/basedriver/driver.ts:123:39)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at processTicksAndRejections (node:internal/process/task_queues:95:5)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at FlutterDriver.executeCommand (/Users/tharunpothuraj/.appium/node_modules/appium-flutter-driver/lib/driver.ts:184:16)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at defaultBehavior (/usr/local/lib/node_modules/appium/lib/appium.js:722:14)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at AppiumDriver.executeWrappedCommand (/usr/local/lib/node_modules/appium/lib/appium.js:828:16)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at AppiumDriver.executeCommand (/usr/local/lib/node_modules/appium/lib/appium.js:734:17)
2023-10-30 05:52:44:991 [FlutterDriver@a0ef (976b29a3)]     at asyncHandler (/usr/local/lib/node_modules/appium/node_modules/@appium/base-driver/lib/protocol/protocol.js:393:19)
2023-10-30 05:52:44:992 [HTTP] <-- POST /session/976b29a3-b1b6-4b8a-acd5-fa137272b335/element/eyJpc1JlZ0V4cCI6ImZhbHNlIiwibGFiZWwiOiJOZXh0IiwiZmluZGVyVHlwZSI6IkJ5U2VtYW50aWNzTGFiZWwifQ%3D%3D/click 500 4 ms - 626
2023-10-30 05:52:44:992 [HTTP] 
2023-10-30 05:52:45:020 [HTTP] --> GET /session/976b29a3-b1b6-4b8a-acd5-fa137272b335/screenshot

Attaching the full appium log: appium-ios-deploy-justlaunch.log

Please take a look once.

Thanks!

KazuCocoa commented 1 year ago

Have you run flutter:connectObservatoryWsUrl in the ios-deploy method case?

Launch the app outside the driver: for users who want to manage the application under test by yourselves

https://github.com/appium/appium-flutter-driver?tab=readme-ov-file#several-ways-to-start-an-application

pothurajtharun commented 1 year ago

I didn't ran this flutter:connectObservatoryWsUrl before.

Right after the app is launched i ran the above script as follows

processBuilder.command("ios-deploy", "--debug","--justlaunch", "--bundle","/usr/local/automation/MobileApps/ios/Payload/Runner.app");
driver.executeScript("flutter:connectObservatoryWsUrl");

The appium logs also shows that Connecting to Dart Observatory: ws://127.0.0.1:51488/DS60QhnPzSw=/ws and able to identify the flutter based elements.

2023-10-30 10:34:24:837 [FlutterDriver] Attempt #1 of 10
2023-10-30 10:34:24:843 [FlutterDriver] No observatory URL matching to '/(Observatory listening on |An Observatory debugger and profiler on\s.+\sis available at: |The Dart VM service is listening on )((http|\/\/)[a-zA-Z0-9:/=_\-.\[\]]+)/' was found in the device log. Please make sure the application under test is configured properly according to https://github.com/appium-userland/appium-flutter-driver#usage and that it does not crash on startup.
2023-10-30 10:34:24:843 [FlutterDriver] Waiting 3000ms before retrying
2023-10-30 10:34:27:846 [FlutterDriver] Attempt #2 of 10
2023-10-30 10:34:27:848 [FlutterDriver] Running on iOS real device
2023-10-30 10:34:27:851 [FlutterDriver] Forwarding the remote port 51488 to the local port 51488
2023-10-30 10:34:27:873 [FlutterDriver] Connecting to Dart Observatory: ws://127.0.0.1:51488/DS60QhnPzSw=/ws
2023-10-30 10:34:27:879 [FlutterDriver] Listing all isolates: [{"type":"@Isolate","id":"isolates/1003585828608283","name":"main","number":"1003585828608283","isSystemIsolate":false,"isolateGroupId":"isolateGroups/212154136458189460"}]
2023-10-30 10:34:27:894 [FlutterDriver@c9d0 (a52f7134)] Responding to client with driver.execute() result: null
2023-10-30 10:34:27:895 [HTTP] <-- POST /session/a52f7134-8100-44b0-b9c5-030ca98bb97a/execute/sync 200 3072 ms - 14
2023-10-30 10:34:27:895 [HTTP] 
2023-10-30 10:34:27:901 [HTTP] --> POST /session/a52f7134-8100-44b0-b9c5-030ca98bb97a/timeouts
2023-10-30 10:34:27:901 [HTTP] {"implicit":5000}
2023-10-30 10:34:27:901 [FlutterDriver@c9d0 (a52f7134)] Calling AppiumDriver.timeouts() with args: [null,null,null,null,5000,"a52f7134-8100-44b0-b9c5-030ca98bb97a"]
2023-10-30 10:34:27:902 [FlutterDriver] Executing Flutter driver command 'timeouts'
2023-10-30 10:34:27:902 [FlutterDriver@c9d0 (a52f7134)] W3C timeout argument: {"implicit":5000}}
2023-10-30 10:34:27:902 [FlutterDriver@c9d0 (a52f7134)] Set implicit wait to 5000ms
2023-10-30 10:34:27:903 [FlutterDriver@c9d0 (a52f7134)] Responding to client with driver.timeouts() result: null
2023-10-30 10:34:27:903 [HTTP] <-- POST /session/a52f7134-8100-44b0-b9c5-030ca98bb97a/timeouts 200 2 ms - 14
2023-10-30 10:34:27:903 [HTTP] 
2023-10-30 10:34:28:308 [HTTP] --> POST /session/a52f7134-8100-44b0-b9c5-030ca98bb97a/context
2023-10-30 10:34:28:308 [HTTP] {"name":"NATIVE_APP"}
2023-10-30 10:34:28:311 [FlutterDriver@c9d0 (a52f7134)] Calling AppiumDriver.setContext() with args: ["NATIVE_APP","a52f7134-8100-44b0-b9c5-030ca98bb97a"]
2023-10-30 10:34:28:311 [FlutterDriver] Executing Flutter driver command 'setContext'
2023-10-30 10:34:28:312 [XCUITestDriver@927d (14b29ea8)] Attempting to set context to 'NATIVE_APP' from 'NATIVE_APP'
2023-10-30 10:34:28:312 [XCUITestDriver@927d (14b29ea8)] Already in 'NATIVE_APP' context. Doing nothing.
2023-10-30 10:34:28:312 [FlutterDriver@c9d0 (a52f7134)] Responding to client with driver.setContext() result: null
2023-10-30 10:34:28:313 [HTTP] <-- POST /session/a52f7134-8100-44b0-b9c5-030ca98bb97a/context 200 5 ms - 14

But my bad luck is that only some times(2/10) times the observatory URL was written to iPhone system logs. I have to look into the ways how to print the observatory URL to iPhone system logs on every app launch.

Thanks @KazuCocoa. My issue is resolved with your comments. Hence closing the ticket.

canibal1 commented 3 months ago

Have you run flutter:connectObservatoryWsUrl in the ios-deploy method case?

Launch the app outside the driver: for users who want to manage the application under test by yourselves

https://github.com/appium/appium-flutter-driver?tab=readme-ov-file#several-ways-to-start-an-application

@KazuCocoa how can I implement this method in python?

KazuCocoa commented 3 months ago

For example, with subprocess lib in Python, it calls the ios-deploy command and handles the process outside Appium but in your code. This is how to run a command in Python.

canibal1 commented 3 months ago

@KazuCocoa I have an iOS project written in Native. I integrated Flutter into this project with "add to app". I added enableFlutterDriverExtension(); to the main function in the Flutter main.dart file. I get build in profile mode using the method in the Photo1. I also run WebDriverAgentRunner before starting. The Python code and log are as follows. I still get the error "Cannot determine the Dart Observatory URL after 10 retries."

Screenshot 2024-07-31 at 09 43 46

Photo1

Log File: log.txt

Test Environment:

Python 3.12.1 Appium: 2.5.4

import os
from appium.webdriver import Remote
from appium.options.ios.xcuitest.base import XCUITestOptions
from appium_flutter_finder.flutter_finder import FlutterElement, FlutterFinder

options = XCUITestOptions()
options.automation_name = 'flutter'
options.platform_name = 'ios'
options.set_capability('platformVersion', '17.5.1')
options.set_capability('deviceName', 'iPhone 12')
options.set_capability('udid', 'xxxxxxx-xxxxxx')
options.set_capability('bundleId', 'com.xxxx.xxx')
options.set_capability('xcodeSigningId', 'iPhone Developer')
options.set_capability('autoAcceptAlerts', True)
options.set_capability('xcodeOrgId', "xxxxxxxxxx")
options.set_capability('language', "en")
options.set_capability('locale', "US")
options.set_capability('app', f'{os.path.dirname(os.path.realpath(__file__))}/../sample2/ios_project_profile.zip')
driver = Remote('http://localhost:4723', options=options)

finder = FlutterFinder()

driver.switch_to.context("FLUTTER")

key_finder = finder.by_value_key(key="pageOneKey")
driver.execute_script('flutter:waitFor', key_finder, 7000)
goto_next_route_element = FlutterElement(driver, key_finder)
print(goto_next_route_element.text)

key_finder2 = finder.by_value_key(key="pageTwoKey")
goto_next_route_element2 = FlutterElement(driver, key_finder2)
goto_next_route_element2.click()
KazuCocoa commented 3 months ago

Could you try out the latest flutter driver? Then, what about adding showIOSLog: true as well?

canibal1 commented 3 months ago

@KazuCocoa Current Test Environment:

Python 3.12.1 Appium: 2.11.2 flutter@2.9.0 [installed (npm)]

iPhone 12 (17.5.1)

I am currently using the latest version of flutter driver. The error has changed as follows.

Traceback (most recent call last):
  File "/Users/nemo.user/StudioProjects/appium-flutter-driver/example/python/example_old_ios.py", line 36, in <module>
    driver = Remote('http://localhost:4723', options=options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nemo.user/Desktop/automated_test_project/venv/lib/python3.12/site-packages/appium/webdriver/webdriver.py", line 229, in __init__
    super().__init__(
  File "/Users/nemo.user/Desktop/automated_test_project/venv/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py", line 208, in __init__
    self.start_session(capabilities)
  File "/Users/nemo.user/Desktop/automated_test_project/venv/lib/python3.12/site-packages/appium/webdriver/webdriver.py", line 321, in start_session
    response = self.execute(RemoteCommand.NEW_SESSION, w3c_caps)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nemo.user/Desktop/automated_test_project/venv/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py", line 347, in execute
    self.error_handler.check_response(response)
  File "/Users/nemo.user/Desktop/automated_test_project/venv/lib/python3.12/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: No observatory URL matching to '/(Observatory listening on |An Observatory debugger and profiler on\s.+\sis available at: |The Dart VM service is listening on )((http|\/\/)[a-zA-Z0-9:/=_\-.\[\]]+)/' was found in the device log. Please make sure the application under test is configured properly according to https://github.com/appium/appium-flutter-driver#usage and that it does not crash on startup.
Stacktrace:
UnknownError: An unknown server-side error occurred while processing the command. Original error: No observatory URL matching to '/(Observatory listening on |An Observatory debugger and profiler on\s.+\sis available at: |The Dart VM service is listening on )((http|\/\/)[a-zA-Z0-9:/=_\-.\[\]]+)/' was found in the device log. Please make sure the application under test is configured properly according to https://github.com/appium/appium-flutter-driver#usage and that it does not crash on startup.
    at getResponseForW3CError (/opt/homebrew/lib/node_modules/appium/node_modules/@appium/base-driver/lib/protocol/errors.js:1145:9)
    at asyncHandler (/opt/homebrew/lib/node_modules/appium/node_modules/@appium/base-driver/lib/protocol/protocol.js:485:57)

I want to say that I cannot share the IOS log because there may be a security problem in sharing it. There are tens of thousands of lines in the log. My personal data may be in it.

Is there a log you could ask me to research or something you could ask me to try that would be really helpful.

KazuCocoa commented 3 months ago

You could search if the syslog has one of matched string below. https://github.com/appium/appium-flutter-driver/blob/bb32e367a516ea44a1967b69c066a47caf380c15/driver/lib/sessions/observatory.ts#L13-L18

If iOS app could expose Dart VM (for Flutter debug usage and for this driver usage), the syslog should have this matched string in the log. If no, this driver cannot attach to the DartVM to achieve automation.

canibal1 commented 3 months ago

@KazuCocoa Unfortunately, it doesn't appear in the logs either. I'm trying to get a profile mode build from a Native iOS app with Flutter embedded in it. I'm emphasizing this part because I may need to do something extra, but I don't know what to do.