UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

108 lines 4.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AppTerminationClient = void 0; const appium_ios_device_1 = require("appium-ios-device"); const utils_1 = require("../utils"); const installation_proxy_client_1 = require("./installation-proxy-client"); class AppTerminationClient { udid; platformVersion; devicectl; log; remoteXPCFacade; constructor(udid, platformVersion, devicectl, log, remoteXPCFacade = null) { this.udid = udid; this.platformVersion = platformVersion; this.devicectl = devicectl; this.log = log; this.remoteXPCFacade = remoteXPCFacade; } async terminate(bundleId) { let result = (await this.remoteXPCFacade?.attemptService(`terminate '${bundleId}'`, async (Services) => { const dvt = await Services.startDVTService(this.udid); try { const pid = await dvt.processControl.getPidForBundleIdentifier(bundleId); if (!pid) { return { terminated: false, reason: 'not_running' }; } await dvt.processControl.kill(pid); return { terminated: true, pid }; } finally { await dvt.dvtService.close(); } })) ?? null; if (!result) { result = await this.terminateLegacy(bundleId); } if (result.terminated) { this.log.debug(`Killed process for '${bundleId}' app with PID ${result.pid}`); return true; } switch (result.reason) { case 'not_running': this.log.info(`The process of '${bundleId}' app was not running`); break; case 'error': this.log.warn(`Failed to kill '${bundleId}'. Original error: ${result.detail ?? 'unknown'}`); break; } return false; } async terminateLegacy(bundleId) { let instrumentService; let installProxyClient; try { installProxyClient = await installation_proxy_client_1.InstallationProxyClient.create(this.udid); const apps = await installProxyClient.listApplications({ returnAttributes: ['CFBundleIdentifier', 'CFBundleExecutable'], }); if (!apps[bundleId]) { return { terminated: false, reason: 'not_running' }; } const executableName = apps[bundleId].CFBundleExecutable; this.log.debug(`The executable name for the bundle id '${bundleId}' was '${executableName}'`); if ((0, utils_1.isIos17OrNewerPlatform)(this.platformVersion)) { if (process.platform !== 'darwin') { return { terminated: false, reason: 'error', detail: `devicectl is only available on macOS; cannot terminate '${bundleId}' via devicectl from '${process.platform}'`, }; } this.log.debug(`Calling devicectl to kill the process`); const pids = (await this.devicectl.listProcesses()) .filter(({ executable }) => executable.endsWith(`/${executableName}`)) .map(({ processIdentifier }) => processIdentifier); if ((0, utils_1.isEmpty)(pids)) { return { terminated: false, reason: 'not_running' }; } await this.devicectl.sendSignalToProcess(pids[0], 2); return { terminated: true, pid: pids[0] }; } // iOS < 17: use instrument service instrumentService = await appium_ios_device_1.services.startInstrumentService(this.udid); const processes = await instrumentService.callChannel(appium_ios_device_1.INSTRUMENT_CHANNEL.DEVICE_INFO, 'runningProcesses'); const matchingProcess = processes.selector.find((proc) => proc.name === executableName); if (!matchingProcess) { return { terminated: false, reason: 'not_running' }; } await instrumentService.callChannel(appium_ios_device_1.INSTRUMENT_CHANNEL.PROCESS_CONTROL, 'killPid:', `${matchingProcess.pid}`); return { terminated: true, pid: matchingProcess.pid }; } catch (err) { const detail = err.stderr ?? err.message; return { terminated: false, reason: 'error', detail: String(detail) }; } finally { if (installProxyClient) { await installProxyClient.close(); } if (instrumentService) { instrumentService.close(); } } } } exports.AppTerminationClient = AppTerminationClient; //# sourceMappingURL=app-termination-client.js.map