Skip to content

Conversation

@GayatriNairAtBrowserstack
Copy link
Contributor

@GayatriNairAtBrowserstack GayatriNairAtBrowserstack commented Jun 12, 2025

This PR addresses an issue where the local server is not properly closed after the terminateApp command is executed when the forwardingPort capability is active. This leads to a subsequent session failure, as Flutter attempts to establish a connection on the same port that was not released.

This fix ensures the local server is correctly terminated, allowing new sessions to start without port conflicts.

Context
Problem: When using the forwardingPort capability, the local server fails to shut down upon terminateApp.
Impact: Any subsequent test session fails because the port is already in use.
Solution: The changes in this PR ensure the server instance is properly closed.
Environment
Flutter Version: 2.15.2
Logs 📝

Passing Session Log :
passingAppiumLogs.txt
without forwardingPort
cap:

 Creating session with W3C capabilities: {
  "alwaysMatch": {
    "platformName": "iOS",
    "appium:udid": "00008030-001214812650802E",
    "appium:bundleId": "com.bstack.bstackFlutterApp",
    "appium:automationName": "Flutter",
    "appium:platform": "iOS",
    "appium:deviceName": "iPhone 11 Pro Max",
    "appium:platformVersion": "18.5",
    "appium:mjpegPort": 9090,
    "appium:showXcodeLog": true,
    "appium:wdaLaunchTimeout": 300000,
    "appium:flutterObservatoryTimeout": 60000
  },
  "firstMatch": [
    {}
  ]
}
[da31d3d8][HTTP] --> POST /session/da31d3d8-2d9a-4d83-863d-d640192ddf7b/appium/device/terminate_app {"appId":"com.bstack.bstackFlutterApp"}
[da31d3d8][FlutterDriver@8a92] Calling AppiumDriver.terminateApp() with args: ["com.bstack.bstackFlutterApp",null,null,null,"da31d3d8-2d9a-4d83-863d-d640192ddf7b"]
[da31d3d8][FlutterDriver] Executing Flutter driver command 'terminateApp'
[da31d3d8][XCUITestDriver@f5f5] Proxying [POST /wda/apps/terminate] to [POST http://127.0.0.1:8100/session/CDBEF850-9050-4169-889F-BE0D0751C58E/wda/apps/terminate] with body: {"bundleId":"com.bstack.bstackFlutterApp"}
[d56a4232][FlutterDriver@8a92] Connection to ws://127.0.0.1:50067/m1KHJ2i6adQ=/ws closed
[da31d3d8][XCUITestDriver@f5f5] Got response with status 200: {"value":true,"sessionId":"CDBEF850-9050-4169-889F-BE0D0751C58E"}
[da31d3d8][FlutterDriver@8a92] Responding to client with driver.terminateApp() result: true
[da31d3d8][HTTP] <-- POST /session/da31d3d8-2d9a-4d83-863d-d640192ddf7b/appium/device/terminate_app 200 1084 ms - 14
[da31d3d8][HTTP] --> POST /session/da31d3d8-2d9a-4d83-863d-d640192ddf7b/appium/device/activate_app {"bundleId":"com.bstack.bstackFlutterApp"}
[da31d3d8][FlutterDriver@8a92] Calling AppiumDriver.activateApp() with args: ["com.bstack.bstackFlutterApp",null,null,null,"da31d3d8-2d9a-4d83-863d-d640192ddf7b"]
[da31d3d8][FlutterDriver] Executing Flutter driver command 'activateApp'
[da31d3d8][XCUITestDriver@f5f5] Proxying [POST /wda/apps/launch] to [POST http://127.0.0.1:8100/session/CDBEF850-9050-4169-889F-BE0D0751C58E/wda/apps/launch] with body: {"bundleId":"com.bstack.bstackFlutterApp"}
[d56a4232][FlutterDriver@8a92] Matched the syslog line 'Jun 12 11:20:50 iPhone-11-Pro-Max Runner(Flutter)[2422] <Notice>: flutter: Observatory listening on http://127.0.0.1:50073/tg_7Kg6F6es=/'
[da31d3d8][XCUITestDriver@f5f5] Got response with status 200: {"value":null,"sessionId":"CDBEF850-9050-4169-889F-BE0D0751C58E"}
[da31d3d8][FlutterDriver@8a92] Running on iOS real device
[da31d3d8][FlutterDriver@8a92] Forwarding the remote port 50073 to the local port 50073
[da31d3d8][FlutterDriver@8a92] Establishing a connection to the Dart Observatory
[da31d3d8][FlutterDriver@8a92] Connecting to Dart Observatory: ws://127.0.0.1:50073/tg_7Kg6F6es=/ws
[da31d3d8][FlutterDriver@8a92] Listing all isolates: [{"type":"@Isolate","id":"isolates/577637096812395","name":"main","number":"577637096812395","isSystemIsolate":false}]
[da31d3d8][FlutterDriver@8a92] Responding to client with driver.activateApp() result: null
[da31d3d8][HTTP] <-- POST /session/da31d3d8-2d9a-4d83-863d-d640192ddf7b/appium/device/activate_app 200 3030 ms - 14
[da31d3d8][HTTP] --> POST /session/da31d3d8-2d9a-4d83-863d-d640192ddf7b/context {"name":"FLUTTER"}
[da31d3d8][FlutterDriver@8a92] Calling AppiumDriver.setContext() with args: ["FLUTTER","da31d3d8-2d9a-4d83-863d-d640192ddf7b"]

Failin Session logs with forwardingPort
failingsession.log

[FlutterDriver@549a] Creating session with W3C capabilities: {
  "alwaysMatch": {
    "platformName": "iOS",
    "appium:udid": "00008030-001214812650802E",
    "appium:bundleId": "com.bstack.bstackFlutterApp",
    "appium:automationName": "Flutter",
    "appium:platform": "iOS",
    "appium:deviceName": "iPhone 11 Pro Max",
    "appium:platformVersion": "18.5",
    "appium:forwardingPort": 8281,
    "appium:mjpegPort": 9090,
    "appium:showXcodeLog": true,
    "appium:wdaLaunchTimeout": 300000,
    "appium:flutterObservatoryTimeout": 60000
  },
  "firstMatch": [
    {}
  ]
}

[be382874][HTTP] --> POST /session/be382874-63f7-4d2f-9a3c-b8ad3909156b/appium/device/terminate_app {"appId":"com.bstack.bstackFlutterApp"}
[be382874][FlutterDriver@549a] Calling AppiumDriver.terminateApp() with args: ["com.bstack.bstackFlutterApp",null,null,null,"be382874-63f7-4d2f-9a3c-b8ad3909156b"]
[be382874][FlutterDriver] Executing Flutter driver command 'terminateApp'
[be382874][XCUITestDriver@94dc] Proxying [POST /wda/apps/terminate] to [POST http://127.0.0.1:8100/session/F7803E11-F787-4003-A6F0-0EFA3081A05A/wda/apps/terminate] with body: {"bundleId":"com.bstack.bstackFlutterApp"}
[758f3f70][FlutterDriver@549a] Connection to ws://127.0.0.1:8281/LSD3s4wgHD4=/ws closed
[be382874][XCUITestDriver@94dc] Got response with status 200: {"value":true,"sessionId":"F7803E11-F787-4003-A6F0-0EFA3081A05A"}
[be382874][FlutterDriver@549a] Responding to client with driver.terminateApp() result: true
[be382874][HTTP] <-- POST /session/be382874-63f7-4d2f-9a3c-b8ad3909156b/appium/device/terminate_app 200 1034 ms - 14
[be382874][HTTP] --> POST /session/be382874-63f7-4d2f-9a3c-b8ad3909156b/appium/device/activate_app {"bundleId":"com.bstack.bstackFlutterApp"}
[be382874][FlutterDriver@549a] Calling AppiumDriver.activateApp() with args: ["com.bstack.bstackFlutterApp",null,null,null,"be382874-63f7-4d2f-9a3c-b8ad3909156b"]
[be382874][FlutterDriver] Executing Flutter driver command 'activateApp'
[be382874][XCUITestDriver@94dc] Proxying [POST /wda/apps/launch] to [POST http://127.0.0.1:8100/session/F7803E11-F787-4003-A6F0-0EFA3081A05A/wda/apps/launch] with body: {"bundleId":"com.bstack.bstackFlutterApp"}
[758f3f70][FlutterDriver@549a] Matched the syslog line 'Jun 12 11:49:12 iPhone-11-Pro-Max Runner(Flutter)[2447] <Notice>: flutter: Observatory listening on http://127.0.0.1:51490/xfilMlZHQwg=/'
[be382874][XCUITestDriver@94dc] Got response with status 200: {"value":null,"sessionId":"F7803E11-F787-4003-A6F0-0EFA3081A05A"}
[be382874][FlutterDriver@549a] Running on iOS real device
[be382874][FlutterDriver@549a] Port #8281 is busy. Did you quit the previous driver session(s) properly?
[be382874][FlutterDriver@549a] Encountered internal error running command: Error: The port :8281 is occupied by an other process. You can either quit that process or select another free port.
    at FlutterDriver.requireFreePort (/Users/gayatri/Documents/Work/Repos/appium-njb/packages/appium/flutter/2.15.2/node_modules/appium-flutter-driver/lib/sessions/ios.ts:68:9)
    at FlutterDriver.getObservatoryWsUri (/Users/gayatri/Documents/Work/Repos/appium-njb/packages/appium/flutter/2.15.2/node_modules/appium-flutter-driver/lib/sessions/ios.ts:123:3)
    at FlutterDriver.connectIOSSession (/Users/gayatri/Documents/Work/Repos/appium-njb/packages/appium/flutter/2.15.2/node_modules/appium-flutter-driver/lib/sessions/ios.ts:56:28)
    at FlutterDriver.reConnectFlutterDriver (/Users/gayatri/Documents/Work/Repos/appium-njb/packages/appium/flutter/2.15.2/node_modules/appium-flutter-driver/lib/sessions/session.ts:20:21)
    at FlutterDriver.activateApp (/Users/gayatri/Documents/Work/Repos/appium-njb/packages/appium/flutter/2.15.2/node_modules/appium-flutter-driver/lib/driver.ts:158:5)
[be382874][HTTP] <-- POST /session/be382874-63f7-4d2f-9a3c-b8ad3909156b/appium/device/activate_app 500 3010 ms - 717

Passing Session with fix
passsingAppiumLogsWithFix.txt

[d463f3b9][XCUITestDriver@3c76] Creating session with W3C capabilities: {
  "alwaysMatch": {
    "platformName": "iOS",
    "appium:udid": "00008030-001214812650802E",
    "appium:bundleId": "com.bstack.bstackFlutterApp",
    "appium:automationName": "Flutter",
    "appium:platform": "iOS",
    "appium:deviceName": "iPhone 11 Pro Max",
    "appium:platformVersion": "18.5",
    "appium:forwardingPort": 8280,
    "appium:mjpegServerPort": 9090,
    "appium:showXcodeLog": true,
    "appium:wdaLaunchTimeout": 300000,
    "appium:flutterObservatoryTimeout": 60000
  },
  "firstMatch": [
    {}
  ]
}
[d463f3b9][HTTP] --> POST /session/d463f3b9-235e-430b-aab3-059617ca2c24/appium/device/terminate_app {"appId":"com.bstack.bstackFlutterApp"}
[d463f3b9][FlutterDriver@1512] Calling AppiumDriver.terminateApp() with args: ["com.bstack.bstackFlutterApp",null,null,null,"d463f3b9-235e-430b-aab3-059617ca2c24"]
[d463f3b9][FlutterDriver] Executing Flutter driver command 'terminateApp'
[d463f3b9][XCUITestDriver@3c76] Proxying [POST /wda/apps/terminate] to [POST http://127.0.0.1:8100/session/15F6D270-1932-472A-98D6-651878DB33F8/wda/apps/terminate] with body: {"bundleId":"com.bstack.bstackFlutterApp"}
[f5c4a73b][FlutterDriver@1512] Connection to ws://127.0.0.1:8280/I1w6l_NOMME=/ws closed
[d463f3b9][XCUITestDriver@3c76] Got response with status 200: {"value":true,"sessionId":"15F6D270-1932-472A-98D6-651878DB33F8"}
[d463f3b9][FlutterDriver@1512] Responding to client with driver.terminateApp() result: true
[d463f3b9][HTTP] <-- POST /session/d463f3b9-235e-430b-aab3-059617ca2c24/appium/device/terminate_app 200 1039 ms - 14
[d463f3b9][HTTP] --> POST /session/d463f3b9-235e-430b-aab3-059617ca2c24/appium/device/activate_app {"bundleId":"com.bstack.bstackFlutterApp"}
[d463f3b9][FlutterDriver@1512] Calling AppiumDriver.activateApp() with args: ["com.bstack.bstackFlutterApp",null,null,null,"d463f3b9-235e-430b-aab3-059617ca2c24"]
[d463f3b9][FlutterDriver] Executing Flutter driver command 'activateApp'
[d463f3b9][XCUITestDriver@3c76] Proxying [POST /wda/apps/launch] to [POST http://127.0.0.1:8100/session/15F6D270-1932-472A-98D6-651878DB33F8/wda/apps/launch] with body: {"bundleId":"com.bstack.bstackFlutterApp"}
[f5c4a73b][FlutterDriver@1512] Matched the syslog line 'Jun 12 20:49:52 iPhone-11-Pro-Max Runner(Flutter)[2757] <Notice>: flutter: Observatory listening on http://127.0.0.1:62888/wLFWV6Texvg=/'
[d463f3b9][XCUITestDriver@3c76] Got response with status 200: {"value":null,"sessionId":"15F6D270-1932-472A-98D6-651878DB33F8"}
[d463f3b9][FlutterDriver@1512] Running on iOS real device
[d463f3b9][FlutterDriver@1512] Closing existing local server on port 8280
[d463f3b9][FlutterDriver@1512] Previous local server closed
[d463f3b9][FlutterDriver@1512] Forwarding the remote port 62888 to the local port 8280
[d463f3b9][FlutterDriver@1512] Establishing a connection to the Dart Observatory
[d463f3b9][FlutterDriver@1512] Connecting to Dart Observatory: ws://127.0.0.1:8280/wLFWV6Texvg=/ws
[d463f3b9][FlutterDriver@1512] Listing all isolates: [{"type":"@Isolate","id":"isolates/72449685159971","name":"main","number":"72449685159971","isSystemIsolate":false}]
[d463f3b9][FlutterDriver@1512] Responding to client with driver.activateApp() result: null
[d463f3b9][HTTP] <-- POST /session/d463f3b9-235e-430b-aab3-059617ca2c24/appium/device/activate_app 200 3056 ms - 14
[d463f3b9][HTTP] --> POST /session/d463f3b9-235e-430b-aab3-059617ca2c24/context {"name":"FLUTTER"}

@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Jun 12, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: KazuCocoa / name: Kazuaki Matsuo (9969192)
  • ✅ login: GayatriNairAtBrowserstack / name: Gayatri Nair (b25fa78, 37182c9)

@KazuCocoa
Copy link
Member

Thank you. Could you sign the CLA? @GayatriNairAtBrowserstack

@KazuCocoa KazuCocoa requested a review from Copilot June 12, 2025 16:17

This comment was marked as outdated.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR ensures that the local server is properly closed when terminateApp is called with the forwardingPort capability enabled, preventing port conflicts during subsequent sessions.

  • Added logic to check for an existing local server and attempt to close it before proceeding.
  • Ensured proper logging of server closure actions.

if (this.localServer) {
this.log.info(`Closing existing local server on port ${port}`);
await new Promise<void>((resolve) => {
this.localServer?.close(() => {
Copy link

Copilot AI Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider handling potential errors in the close callback by accepting and checking the error parameter (e.g., using a signature like close(err) => { ... }). This ensures that any issues during the closure are properly logged or handled.

Suggested change
this.localServer?.close(() => {
this.localServer?.close((err) => {
if (err) {
this.log.error(`Error occurred while closing the local server: ${err.message}`);
return resolve(); // Resolve even if there's an error to avoid hanging
}

Copilot uses AI. Check for mistakes.
@GayatriNairAtBrowserstack
Copy link
Contributor Author

Thank you. Could you sign the CLA? @GayatriNairAtBrowserstack

done @KazuCocoa

@KazuCocoa
Copy link
Member

Thank you! Both comments by the Copilot are reasonable. I'll apply them also and merge this PR.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@KazuCocoa KazuCocoa merged commit 8a8f150 into appium:main Jun 13, 2025
2 of 7 checks passed
@KazuCocoa
Copy link
Member

2.17.0 has this change

@GayatriNairAtBrowserstack
Copy link
Contributor Author

2.17.0 has this change

Thankn you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants