UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

175 lines 7.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isStrictHostUtilityMode = isStrictHostUtilityMode; exports.assertWdaHostSessionCapsSupported = assertWdaHostSessionCapsSupported; exports.createWdaHostOps = createWdaHostOps; exports.assertWdaHostPlatformSupported = assertWdaHostPlatformSupported; const utils_1 = require("../utils"); const XCODE_ONLY_CAPS = [ 'usePrebuiltWDA', 'useXctestrunFile', 'prebuildWDA', 'xcodeOrgId', 'xcodeSigningId', 'xcodeConfigFile', 'keychainPath', 'keychainPassword', 'allowProvisioningDeviceRegistration', 'resultBundlePath', ]; /** * Whether the selected session strategy must avoid host-side Xcode/Simulator utilities. */ function isStrictHostUtilityMode(opts, platform = process.platform) { return platform !== 'darwin' && Boolean(opts.webDriverAgentUrl || opts.usePreinstalledWDA); } /** * Verifies host-only utility requirements that can be checked before device discovery. */ function assertWdaHostSessionCapsSupported(opts, platform = process.platform) { if (platform === 'darwin') { return; } if (!opts.webDriverAgentUrl && !opts.usePreinstalledWDA) { throw new Error(`The selected XCUITest session strategy requires macOS with Xcode. ` + `Use 'appium:usePreinstalledWDA' with a signed prebuilt WebDriverAgent or provide ` + `'appium:webDriverAgentUrl' to run from '${platform}'.`); } if (!opts.udid || opts.udid.toLowerCase() === 'auto') { throw new Error(`Running XCUITest from '${platform}' without macOS/Xcode requires an explicit real-device ` + `'appium:udid'. Simulator discovery and automatic device selection require macOS.`); } if (opts.usePreinstalledWDA && !opts.webDriverAgentUrl && !opts.platformVersion) { throw new Error(`Running preinstalled WebDriverAgent from '${platform}' requires 'appium:platformVersion' ` + `so RemoteXPC eligibility can be checked without probing host Xcode or Simulator tools.`); } const xcodeOnlyCaps = XCODE_ONLY_CAPS.filter((capName) => Boolean(opts[capName])); if (opts.usePreinstalledWDA && !opts.webDriverAgentUrl && xcodeOnlyCaps.length > 0) { throw new Error(`The following capabilities require macOS/Xcode and cannot be used with the ` + `RemoteXPC preinstalled WebDriverAgent strategy on '${platform}': ` + xcodeOnlyCaps.join(', ')); } } /** * Creates WebDriverAgent host operations provided by the XCUITest driver. */ function createWdaHostOps(driver) { return { simulator: createSimulatorHostOps(driver), realDevicePreinstalled: createRealDevicePreinstalledHostOps(driver), }; } /** * Verifies the selected WDA lifecycle can run on the current host platform. */ function assertWdaHostPlatformSupported(driver) { if (process.platform === 'darwin') { return; } assertWdaHostSessionCapsSupported(driver.opts); if (driver.opts.webDriverAgentUrl) { return; } if (!driver.isRealDevice()) { throw new Error(`XCUITest simulator sessions require macOS with Xcode. ` + `Use a real device with 'appium:usePreinstalledWDA' or provide 'appium:webDriverAgentUrl' ` + `to run from '${process.platform}'.`); } if (!driver.opts.usePreinstalledWDA) { throw new Error(`The default real-device WebDriverAgent startup strategy requires macOS with Xcode. ` + `Use 'appium:usePreinstalledWDA' with a signed prebuilt WebDriverAgent or provide ` + `'appium:webDriverAgentUrl' to run from '${process.platform}'.`); } if (driver.opts.platformVersion && !(0, utils_1.isIos18OrNewerPlatform)(driver.opts.platformVersion)) { throw new Error(`Running preinstalled WebDriverAgent from '${process.platform}' requires a real device ` + `with RemoteXPC tunnel support. The current platformVersion is ` + `'${driver.opts.platformVersion}'; use iOS/tvOS 18.0 or newer, or provide ` + `'appium:webDriverAgentUrl' for an externally managed WDA.`); } if (!driver.remoteXPCFacade.eligible) { throw new Error(`RemoteXPC is required to launch preinstalled WebDriverAgent from '${process.platform}', ` + `but this session is not eligible for RemoteXPC.`); } } function stringifyLaunchEnvironment(env) { return Object.entries(env).reduce((acc, [key, value]) => { acc[key] = String(value); return acc; }, {}); } function createSimulatorHostOps(driver) { return { async launchPreinstalled({ udid, bundleId, env }) { await driver.device.simctl.exec('launch', { args: ['--terminate-running-process', udid, bundleId], env, }); }, async terminate({ bundleId }) { await driver.device.terminateApp(bundleId); }, }; } function createRealDevicePreinstalledHostOps(driver) { return { async launchPreinstalled({ udid, bundleId, env }) { try { const dvt = await driver.remoteXPCFacade.requireService('launch preinstalled WebDriverAgent', (Services) => Services.startDVTService(udid)); try { await dvt.processControl.launch({ bundleId, environment: stringifyLaunchEnvironment(env), killExisting: true, }); } finally { await dvt.dvtService.close(); } } catch (err) { if (process.platform !== 'darwin') { throw err; } driver.log.warn(`Failed to launch preinstalled WebDriverAgent via RemoteXPC. ` + `Falling back to devicectl. Original error: ${err.message}`); const { devicectl } = driver.device; if (!devicectl) { throw err; } await devicectl.launchApp(bundleId, { env, terminateExisting: true, }); } }, async terminate({ udid, bundleId }) { try { const dvt = await driver.remoteXPCFacade.requireService('terminate preinstalled WebDriverAgent', (Services) => Services.startDVTService(udid)); try { const pid = await dvt.processControl.getPidForBundleIdentifier(bundleId); if (!pid) { driver.log.info(`The preinstalled WebDriverAgent process '${bundleId}' was not running`); return; } await dvt.processControl.kill(pid); } finally { await dvt.dvtService.close(); } } catch (err) { if (process.platform !== 'darwin') { throw err; } driver.log.warn(`Failed to terminate preinstalled WebDriverAgent via RemoteXPC. ` + `Falling back to devicectl. Original error: ${err.message}`); const { devicectl } = driver.device; if (!devicectl) { throw err; } await devicectl.terminateApp(bundleId); } }, }; } //# sourceMappingURL=wda-host-ops.js.map