UNPKG

appium-flutter-driver

Version:
156 lines 6.52 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.startIOSSession = startIOSSession; exports.connectIOSSession = connectIOSSession; exports.getObservatoryWsUri = getObservatoryWsUri; const appium_ios_device_1 = require("appium-ios-device"); const appium_xcuitest_driver_1 = require("appium-xcuitest-driver"); const bluebird_1 = __importDefault(require("bluebird")); const node_net_1 = __importDefault(require("node:net")); const portscanner_1 = require("portscanner"); const observatory_1 = require("./observatory"); const log_monitor_1 = require("./log-monitor"); const LOCALHOST = `127.0.0.1`; async function startIOSSession(caps, ...args) { this.log.info(`Starting an IOS proxy session`); const iosdriver = new appium_xcuitest_driver_1.XCUITestDriver({}); if (!caps.observatoryWsUri) { iosdriver.eventEmitter.once('syslogStarted', (syslog) => { this._logmon = new log_monitor_1.LogMonitor(syslog, async (entry) => { if ((0, observatory_1.extractObservatoryUrl)(entry)) { this.log.debug(`Matched the syslog line '${entry.message}'`); return true; } return false; }); this._logmon.start(); }); } // @ts-expect-error can be ignored await iosdriver.createSession(...args); // the session starts without any apps if (caps.app === undefined && caps.bundleId === undefined) { return [iosdriver, null]; } return [iosdriver, await connectIOSSession.bind(this)(iosdriver, caps)]; } async function connectIOSSession(iosdriver, caps, clearLog = false) { const observatoryWsUri = await getObservatoryWsUri.bind(this)(iosdriver, caps, clearLog); return await observatory_1.connectSocket.bind(this)(observatoryWsUri, iosdriver, caps); } async function requireFreePort(port) { // Try to close existing local server if it exists if (this.localServer) { this.log.info(`Closing existing local server on port ${port}`); await new Promise((resolve) => { 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 } this.log.info(`Previous local server closed`); resolve(); }); }); } if ((await (0, portscanner_1.checkPortStatus)(port, LOCALHOST)) !== `open`) { return; } this.log.warn(`Port #${port} is busy. Did you quit the previous driver session(s) properly?`); throw new Error(`The port :${port} is occupied by an other process. ` + `You can either quit that process or select another free port.`); } async function getObservatoryWsUri(proxydriver, caps, clearLog = false) { if (clearLog) { this._logmon?.clearlastMatch(); this._logmon?.stop(); this._logmon?.start(); } let urlObject; if (caps.observatoryWsUri) { urlObject = new URL(caps.observatoryWsUri); urlObject.protocol = `ws`; // defaults to skip the port-forwarding as backward compatibility if (caps.skipPortForward === undefined || caps.skipPortForward) { return urlObject.toJSON(); } } else { if (!this._logmon) { throw new Error(`The mandatory syslog service must be running in order to initialize the Flutter driver. ` + `Have you disabled it in capabilities?`); } let lastMatch = null; try { lastMatch = await this._logmon.waitForLastMatchExist(caps.maxRetryCount, caps.retryBackoffTime); } catch (e) { this.log.error(e); } if (!lastMatch) { throw new Error(`No observatory URL matching to '${observatory_1.OBSERVATORY_URL_PATTERN}' 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.`); } urlObject = (0, observatory_1.extractObservatoryUrl)(lastMatch); } if (!proxydriver.isRealDevice()) { this.log.info(`Running on iOS simulator`); return urlObject.toJSON(); } const remotePort = urlObject.port; const localPort = caps.forwardingPort ?? remotePort; urlObject.port = localPort; this.log.info(`Running on iOS real device`); const { udid } = proxydriver.opts; await requireFreePort.bind(this)(localPort); this.localServer = node_net_1.default.createServer(async (localSocket) => { let remoteSocket; try { remoteSocket = await appium_ios_device_1.utilities.connectPort(udid, remotePort); } catch { localSocket.destroy(); return; } const destroyCommChannel = () => { remoteSocket.unpipe(localSocket); localSocket.unpipe(remoteSocket); }; remoteSocket.once(`close`, () => { destroyCommChannel(); localSocket.destroy(); }); remoteSocket.on('error', (e) => this.log.debug(e)); localSocket.once(`end`, destroyCommChannel); localSocket.once(`close`, () => { destroyCommChannel(); remoteSocket.destroy(); }); localSocket.on('error', (e) => this.log.warn(e.message)); localSocket.pipe(remoteSocket); remoteSocket.pipe(localSocket); }); const listeningPromise = new bluebird_1.default((resolve, reject) => { this.localServer?.once(`listening`, resolve); this.localServer?.once(`error`, reject); }); this.localServer?.listen(localPort); try { await listeningPromise; } catch (e) { this.localServer = null; throw new Error(`Cannot listen on the local port ${localPort}. Original error: ${e.message}`); } this.log.info(`Forwarding the remote port ${remotePort} to the local port ${localPort}`); process.on(`beforeExit`, () => { this.localServer?.close(); this.localServer = null; }); return urlObject.toJSON(); } //# sourceMappingURL=ios.js.map