This is an automated email from the ASF dual-hosted git repository.

erisu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-paramedic.git


The following commit(s) were added to refs/heads/master by this push:
     new ae6dc41  feat!: remove custom port & port range support (#289)
ae6dc41 is described below

commit ae6dc415db44a97d71698302fd306c0042829ff3
Author: エリス <[email protected]>
AuthorDate: Thu Dec 18 14:21:24 2025 +0900

    feat!: remove custom port & port range support (#289)
    
    * feat!: remove tcp-port-used & refactor server creation
    * feat!: remove support for custom ports
---
 README.md                     |  15 +-----
 lib/LocalServer.js            | 112 +++++++++++++++++++++++++-----------------
 lib/ParamedicConfig.js        |  11 -----
 lib/paramedic.js              |   3 +-
 main.js                       |   3 +-
 package-lock.json             |  64 +-----------------------
 package.json                  |   1 -
 paramedic-plugin/paramedic.js |  36 ++------------
 8 files changed, 73 insertions(+), 172 deletions(-)

diff --git a/README.md b/README.md
index 6fea4f5..6106c89 100644
--- a/README.md
+++ b/README.md
@@ -53,8 +53,6 @@ Cordova Paramedic is currently used to automatically run all 
plugin tests on CI.
       - [`--justbuild` (optional)](#--justbuild-optional)
     - [Emulator/Device to use for tests](#emulatordevice-to-use-for-tests)
       - [`--target` (optional)](#--target-optional)
-    - [Test Result Server](#test-result-server)
-      - [`--port` (optional)](#--port-optional)
     - [Test configuration](#test-configuration)
       - [`--timeout` (optional)](#--timeout-optional)
       - [`--outputDir` (optional)](#--outputdir-optional)
@@ -239,7 +237,7 @@ cordova-paramedic --platform ios --plugin 
cordova-plugin-inappbrowser --justbuil
 
 #### `--target` (optional)
 
-For Android: The device ID (from `adb devices -l`) of a device the tests 
should be run on.  
+For Android: The device ID (from `adb devices -l`) of a device the tests 
should be run on.
 
 ```shell
 cordova-paramedic --platform android --plugin cordova-plugin-contacts --target 
02e7f7e9215da7f8
@@ -251,17 +249,6 @@ For iOS: A string that is used to pick the device (from 
the `cordova run --list
 cordova-paramedic --platform ios --plugin cordova-plugin-contacts --target 
"iPhone-8"
 ```
 
-### Test Result Server
-
-#### `--port` (optional)
-
-Port to use for posting results from emulator back to paramedic server 
(default is from `8008`). You can also specify a range using `--startport` and 
`endport` and paramedic will select the first available.
-
-```shell
-cordova-paramedic --platform ios --plugin cordova-plugin-inappbrowser --port 
8010
-cordova-paramedic --platform ios --plugin cordova-plugin-inappbrowser 
--startport 8000 endport 8020
-```
-
 ### Test configuration
 
 #### `--timeout` (optional)
diff --git a/lib/LocalServer.js b/lib/LocalServer.js
index 7be4e34..90e5caf 100644
--- a/lib/LocalServer.js
+++ b/lib/LocalServer.js
@@ -21,7 +21,6 @@ const http = require('node:http');
 const { EventEmitter } = require('node:events');
 
 const WebSocket = require('ws');
-const portChecker = require('tcp-port-used');
 
 const { logger, utilities } = require('./utils');
 
@@ -49,16 +48,20 @@ const WS_VALID_EVENTS = [
 ];
 
 class LocalServer extends EventEmitter {
-    constructor (port) {
+    constructor (config, httpServer, port) {
         super();
 
+        this.config = config;
+        this.httpServer = httpServer;
         this.port = port;
-        this.httpServer = null;
+
         this.wss = null;
     }
 
-    createSocketListener () {
-        this.httpServer = http.createServer();
+    /**
+     * Setup a WebSocket Server with the running HTTP server.
+     */
+    createWebSocketServer () {
         this.wss = new WebSocket.Server({ server: this.httpServer });
 
         /**
@@ -132,12 +135,6 @@ class LocalServer extends EventEmitter {
             }
         }, WS_HEARTBEAT_INTERVAL);
 
-        this.httpServer.listen(this.port, '0.0.0.0', () => {
-            logger.info(
-                `[paramedic] local-server: WebSocket server listening on 
ws://0.0.0.0:${this.port}`
-            );
-        });
-
         this.wss.stop = () => {
             clearInterval(interval);
             this.httpServer.close();
@@ -153,12 +150,11 @@ class LocalServer extends EventEmitter {
      * Android emulators must use their special loopback address 10.0.2.2.
      *
      * @param {string} platform - Platform name (e.g., "android" or "ios").
-     * @param {boolean} shouldReversePort - Whether ADB reverse port is 
enabled.
      * @returns {string} IP address the host
      */
-    getServerIP (platform, shouldReversePort = false) {
+    getServerIP (platform) {
         // Android emulator
-        if (platform === utilities.ANDROID && !shouldReversePort) {
+        if (platform === utilities.ANDROID) {
             return '10.0.2.2';
         }
         // iOS simulator/devices & Android device with reverse, or desktop
@@ -175,9 +171,46 @@ class LocalServer extends EventEmitter {
         return `ws://${this.getServerIP(platform)}:${this.port}`;
     }
 
+    /**
+     * Check if a device is connected by checking the client size.
+     *
+     * @returns {Boolean}
+     */
     isDeviceConnected () {
         return this.wss && this.wss.clients.size > 0;
     }
+
+    /**
+     * Attempts to start a server that the testing app uses to send back test 
results.
+     *
+     * @param {ParamedicConfig} config
+     *   The paramedic configuration object containing relevant settings
+     *   (e.g., port range to try, verbose logging flag, etc).
+     * @returns {Promise<LocalServer>}
+     */
+    static async startServer (config) {
+        
logger.warn('------------------------------------------------------------');
+        logger.warn('2. Create and configure local server to receive test 
results');
+        
logger.warn('------------------------------------------------------------');
+
+        // Holder for the running server instance and used port.
+        logger.normal('[paramedic] Creating local server...');
+        try {
+            const httpServer = await attemptToCreateServer();
+            const port = httpServer.address().port;
+            logger.normal(`[paramedic] Server is running on port: ${port}`);
+
+            // Now create a WebSocket server
+            const localServer = new LocalServer(config, httpServer, port);
+            localServer.createWebSocketServer();
+
+            return localServer;
+        } catch (err) {
+            if (config.isVerbose()) {
+                logger.warn(`[paramedic] Failed to create local server with 
error: ${err.message}`);
+            }
+        }
+    }
 }
 
 /**
@@ -190,38 +223,25 @@ function toReadableDateTime (epochMs) {
     return new Date(epochMs).toLocaleString();
 }
 
-function getRandomInt (min, max) {
-    return Math.floor(Math.random() * (max - min)) + min;
+/**
+ * Attempts to create a server and start listening on any random port.
+ *
+ * Failure case:
+ * - The Promise is rejected if the server fails to listen.
+ *
+ * Success case:
+ * - The Promise is resolved with the server instance once it successfully
+ *   begins listening.
+ *
+ * @returns Promise<Server|Error>
+ */
+function attemptToCreateServer () {
+    return new Promise((resolve, reject) => {
+        const server = http.createServer();
+        server.on('error', reject);
+        server.on('listening', () => resolve(server));
+        server.listen(0, '0.0.0.0');
+    });
 }
 
-LocalServer.startServer = function (ports, noListener) {
-    
logger.warn('------------------------------------------------------------');
-    logger.warn('2. Create and configure local server to receive test 
results');
-    
logger.warn('------------------------------------------------------------');
-
-    logger.normal('local-server: scanning ports from ' + ports.start + ' to ' 
+ ports.end);
-
-    return LocalServer.getAvailablePort(ports.start, ports.end)
-        .then((port) => {
-            logger.normal('local-server: port ' + port + ' is available');
-            logger.info('local-server: starting local medic server');
-
-            const localServer = new LocalServer(port);
-
-            if (!noListener) localServer.createSocketListener();
-
-            return localServer;
-        });
-};
-
-LocalServer.getAvailablePort = function (startPort, endPort) {
-    const port = getRandomInt(startPort, endPort);
-    return portChecker.check(port)
-        .then((isInUse) => {
-            if (!isInUse) return port;
-            if (startPort < endPort) return 
LocalServer.getAvailablePort(startPort, endPort);
-            throw new Error('Unable to find available port');
-        });
-};
-
 module.exports = LocalServer;
diff --git a/lib/ParamedicConfig.js b/lib/ParamedicConfig.js
index 6363205..18afe9b 100644
--- a/lib/ParamedicConfig.js
+++ b/lib/ParamedicConfig.js
@@ -17,8 +17,6 @@
     under the License.
 */
 
-const DEFAULT_START_PORT = 7008;
-const DEFAULT_END_PORT = 7208;
 const DEFAULT_TIMEOUT = 60 * 60 * 1000; // 60 minutes in msec - this will 
become a param
 const DEFAULT_CLI = 'cordova'; // use globally installed cordova by default
 
@@ -95,13 +93,6 @@ class ParamedicConfig {
         this._config.skipMainTests = skipMainTests;
     }
 
-    getPorts () {
-        return {
-            start: this._config.startPort || DEFAULT_START_PORT,
-            end: this._config.endPort || DEFAULT_END_PORT
-        };
-    }
-
     getTimeout () {
         return DEFAULT_TIMEOUT;
     }
@@ -153,8 +144,6 @@ ParamedicConfig.parseFromArguments = function (argv) {
         args: '',
         plugins: Array.isArray(argv.plugin) ? argv.plugin : [argv.plugin],
         verbose: !!argv.verbose,
-        startPort: argv.startport || argv.port,
-        endPort: argv.endport || argv.port,
         outputDir: argv.outputDir ? argv.outputDir : null,
         tccDb: argv.tccDbPath ? argv.tccDb : null,
         cleanUpAfterRun: !!argv.cleanUpAfterRun,
diff --git a/lib/paramedic.js b/lib/paramedic.js
index 8a04eb2..fdee09b 100644
--- a/lib/paramedic.js
+++ b/lib/paramedic.js
@@ -73,8 +73,7 @@ class ParamedicRunner {
 
             // Start server if the tests are to run
             if (this.config.runMainTests()) {
-                const noListener = false;
-                this.server = await Server.startServer(this.config.getPorts(), 
noListener);
+                this.server = await Server.startServer(this.config);
 
                 this.injectReporters();
                 this.subcribeForEvents();
diff --git a/main.js b/main.js
index af28efd..131acbb 100755
--- a/main.js
+++ b/main.js
@@ -27,7 +27,7 @@ const { utilities } = require('./lib/utils');
 
 const USAGE = `Error missing args.
 
-cordova-paramedic --platform PLATFORM --plugin PATH [--justbuild --timeout 
MSECS --startport PORTNUM --endport PORTNUM --version ...]
+cordova-paramedic --platform PLATFORM --plugin PATH [--justbuild --timeout 
MSECS --version ...]
 
 --platform PLATFORM : the platform id. Currently supports 'ios', 'browser' 
'android'.
     Path to platform can be specified as link to git repo like:
@@ -47,7 +47,6 @@ cordova-paramedic --platform PLATFORM --plugin PATH 
[--justbuild --timeout MSECS
 --justbuild : (optional) just builds the project, without running the tests
 --outputDir : (optional) path to save Junit results file & Device logs
 --skipMainTests : (optional) Do not run main (cordova-test-framework) tests
---startport/--endport PORTNUM : (optional) ports to find available and use for 
posting results from emulator back to paramedic server (default is from 8008 to 
8009)
 --target : (optional) target to deploy to
 --tccDb : (optional) iOS only - specifies the path for the TCC.db file to be 
copied.
 --timeout MSECS : (optional) time in millisecs to wait for tests to pass|fail
diff --git a/package-lock.json b/package-lock.json
index dc14a95..9bcaa36 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,7 +13,6 @@
         "jasmine-reporters": "^2.5.2",
         "jasmine-spec-reporter": "^7.0.0",
         "minimist": "^1.2.8",
-        "tcp-port-used": "^1.0.2",
         "tmp": "^0.2.5",
         "tree-kill": "^1.2.2",
         "ws": "^8.18.3"
@@ -862,6 +861,7 @@
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz";,
       "integrity": 
"sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+      "dev": true,
       "license": "MIT"
     },
     "node_modules/define-data-property": {
@@ -1987,15 +1987,6 @@
         "node": ">= 0.4"
       }
     },
-    "node_modules/ip-regex": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz";,
-      "integrity": 
"sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/is-array-buffer": {
       "version": "3.0.5",
       "resolved": 
"https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz";,
@@ -2339,12 +2330,6 @@
         "url": "https://github.com/sponsors/ljharb";
       }
     },
-    "node_modules/is-url": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz";,
-      "integrity": 
"sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
-      "license": "MIT"
-    },
     "node_modules/is-weakmap": {
       "version": "2.0.2",
       "resolved": 
"https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz";,
@@ -2391,20 +2376,6 @@
         "url": "https://github.com/sponsors/ljharb";
       }
     },
-    "node_modules/is2": {
-      "version": "2.0.9",
-      "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz";,
-      "integrity": 
"sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==",
-      "license": "MIT",
-      "dependencies": {
-        "deep-is": "^0.1.3",
-        "ip-regex": "^4.1.0",
-        "is-url": "^1.2.4"
-      },
-      "engines": {
-        "node": ">=v0.10.0"
-      }
-    },
     "node_modules/isarray": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz";,
@@ -3378,39 +3349,6 @@
         "url": "https://opencollective.com/webpack";
       }
     },
-    "node_modules/tcp-port-used": {
-      "version": "1.0.2",
-      "resolved": 
"https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz";,
-      "integrity": 
"sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
-      "license": "MIT",
-      "dependencies": {
-        "debug": "4.3.1",
-        "is2": "^2.0.6"
-      }
-    },
-    "node_modules/tcp-port-used/node_modules/debug": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz";,
-      "integrity": 
"sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/tcp-port-used/node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz";,
-      "integrity": 
"sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "license": "MIT"
-    },
     "node_modules/tmp": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz";,
diff --git a/package.json b/package.json
index 7d32d58..e0f3393 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,6 @@
     "jasmine-reporters": "^2.5.2",
     "jasmine-spec-reporter": "^7.0.0",
     "minimist": "^1.2.8",
-    "tcp-port-used": "^1.0.2",
     "tmp": "^0.2.5",
     "tree-kill": "^1.2.2",
     "ws": "^8.18.3"
diff --git a/paramedic-plugin/paramedic.js b/paramedic-plugin/paramedic.js
index 8bbc8a7..7333cc6 100644
--- a/paramedic-plugin/paramedic.js
+++ b/paramedic-plugin/paramedic.js
@@ -18,11 +18,7 @@
     under the License.
 */
 
-const PARAMEDIC_SERVER_DEFAULT_URL = 'http://127.0.0.1:8008';
-
-function Paramedic () {
-
-}
+function Paramedic () { }
 
 Paramedic.prototype.initialize = function () {
     const me = this;
@@ -108,41 +104,15 @@ Paramedic.prototype.loadParamedicServerUrl = function () {
         xhr.open('GET', '../medic.json', false);
         xhr.send(null);
         const cfg = JSON.parse(xhr.responseText);
-
-        return cfg.logurl || PARAMEDIC_SERVER_DEFAULT_URL;
+        return cfg.logurl;
     } catch (ex) {
         console.log('Unable to load paramedic server url: ' + ex);
     }
 
-    return PARAMEDIC_SERVER_DEFAULT_URL;
-};
-
-Paramedic.prototype.loadParamedicServerUrl = function () {
-    return getMedicConfig().logurl;
+    throw new Error('[paramedic] Failed to find logurl.');
 };
 
 cordova.paramedic = new Paramedic();
 cordova.paramedic.initialize();
 
-function getMedicConfig () {
-    const cfg = {
-        logurl: PARAMEDIC_SERVER_DEFAULT_URL
-    };
-
-    try {
-        // attempt to synchronously load medic config
-        const xhr = new XMLHttpRequest();
-        xhr.open('GET', '../medic.json', false);
-        xhr.send(null);
-        const parsedCfg = JSON.parse(xhr.responseText);
-        if (parsedCfg.logurl) {
-            cfg.logurl = parsedCfg.logurl;
-        }
-    } catch (ex) {
-        console.log('Unable to load paramedic server url: ' + ex);
-    }
-
-    return cfg;
-}
-
 module.exports = Paramedic;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to