From e1c0f836a68ad2efbedfc77343794d0d97ef6090 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 1 May 2023 23:48:16 -0700 Subject: [PATCH] feat: start wda process via Xctest in a real device (#687) * move some implementation to wda * tune * Update webdriveragent.js * update review * refactor: set started=true after getStatus * chore: use WDA_RUNNER_BUNDLE_ID * refactor: rename * chore: refer to updatedWDABundleId to build xctrunner * add fixme to not create xcodebuild instance for webDriverAgentUrl * return a bit early * refactor: fix review * refactor: fix review --- lib/constants.js | 4 +- lib/webdriveragent.js | 122 +++++++++++++++++++++++++++++++----------- package.json | 1 + 3 files changed, 96 insertions(+), 31 deletions(-) diff --git a/lib/constants.js b/lib/constants.js index caea65cec..82f005d1c 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -1,6 +1,7 @@ import path from 'path'; const WDA_RUNNER_BUNDLE_ID = 'com.facebook.WebDriverAgentRunner'; +const WDA_RUNNER_BUNDLE_ID_FOR_XCTEST = `${WDA_RUNNER_BUNDLE_ID}.xctrunner`; const WDA_RUNNER_APP = 'WebDriverAgentRunner-Runner.app'; const WDA_SCHEME = 'WebDriverAgentRunner'; const PROJECT_FILE = 'project.pbxproj'; @@ -17,5 +18,6 @@ const WDA_UPGRADE_TIMESTAMP_PATH = path.join('.appium', 'webdriveragent', 'upgra export { WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_APP, PROJECT_FILE, WDA_SCHEME, PLATFORM_NAME_TVOS, PLATFORM_NAME_IOS, - SDK_SIMULATOR, SDK_DEVICE, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH + SDK_SIMULATOR, SDK_DEVICE, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, + WDA_RUNNER_BUNDLE_ID_FOR_XCTEST }; diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 93898047b..2424a95aa 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -14,8 +14,10 @@ import AsyncLock from 'async-lock'; import { exec } from 'teen_process'; import { bundleWDASim } from './check-dependencies'; import { - WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_APP, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, + WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_BUNDLE_ID_FOR_XCTEST, WDA_RUNNER_APP, + WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, } from './constants'; +import {Xctest} from 'appium-ios-device'; const WDA_LAUNCH_TIMEOUT = 60 * 1000; const WDA_AGENT_PORT = 8100; @@ -59,31 +61,47 @@ class WebDriverAgent { this.updatedWDABundleId = args.updatedWDABundleId; - this.xcodebuild = new XcodeBuild(this.xcodeVersion, this.device, { - platformVersion: this.platformVersion, - platformName: this.platformName, - iosSdkVersion: this.iosSdkVersion, - agentPath: this.agentPath, - bootstrapPath: this.bootstrapPath, - realDevice: this.isRealDevice, - showXcodeLog: args.showXcodeLog, - xcodeConfigFile: args.xcodeConfigFile, - xcodeOrgId: args.xcodeOrgId, - xcodeSigningId: args.xcodeSigningId, - keychainPath: args.keychainPath, - keychainPassword: args.keychainPassword, - useSimpleBuildTest: args.useSimpleBuildTest, - usePrebuiltWDA: args.usePrebuiltWDA, - updatedWDABundleId: this.updatedWDABundleId, - launchTimeout: args.wdaLaunchTimeout || WDA_LAUNCH_TIMEOUT, - wdaRemotePort: this.wdaRemotePort, - useXctestrunFile: this.useXctestrunFile, - derivedDataPath: args.derivedDataPath, - mjpegServerPort: this.mjpegServerPort, - allowProvisioningDeviceRegistration: args.allowProvisioningDeviceRegistration, - resultBundlePath: args.resultBundlePath, - resultBundleVersion: args.resultBundleVersion, - }, this.log); + this.usePreinstalledWDA = args.usePreinstalledWDA; + this.xctestApiClient = null; + + // FIXME: maybe 'this.webDriverAgentUrl' also can ignore + // the xcodebuild instance itself. + + this.xcodebuild = this.usePreinstalledWDA + ? null + : new XcodeBuild(this.xcodeVersion, this.device, { + platformVersion: this.platformVersion, + platformName: this.platformName, + iosSdkVersion: this.iosSdkVersion, + agentPath: this.agentPath, + bootstrapPath: this.bootstrapPath, + realDevice: this.isRealDevice, + showXcodeLog: args.showXcodeLog, + xcodeConfigFile: args.xcodeConfigFile, + xcodeOrgId: args.xcodeOrgId, + xcodeSigningId: args.xcodeSigningId, + keychainPath: args.keychainPath, + keychainPassword: args.keychainPassword, + useSimpleBuildTest: args.useSimpleBuildTest, + usePrebuiltWDA: args.usePrebuiltWDA, + updatedWDABundleId: this.updatedWDABundleId, + launchTimeout: args.wdaLaunchTimeout || WDA_LAUNCH_TIMEOUT, + wdaRemotePort: this.wdaRemotePort, + useXctestrunFile: this.useXctestrunFile, + derivedDataPath: args.derivedDataPath, + mjpegServerPort: this.mjpegServerPort, + allowProvisioningDeviceRegistration: args.allowProvisioningDeviceRegistration, + resultBundlePath: args.resultBundlePath, + resultBundleVersion: args.resultBundleVersion, + }, this.log); + } + + /** + * + * @returns {string} Bundle ID for Xctest. + */ + get bundleIdForXctest () { + return `${this.updatedWDABundleId}.xctrunner` || WDA_RUNNER_BUNDLE_ID_FOR_XCTEST; } setWDAPaths (bootstrapPath, agentPath) { @@ -248,6 +266,9 @@ class WebDriverAgent { return; } + if (this.usePreinstalledWDA) { + return; + } try { await this.xcodebuild.cleanProject(); } catch (e) { @@ -255,6 +276,30 @@ class WebDriverAgent { } } + /** + * Launch WDA with preinstalled package without xcodebuild. + * @param {string} sessionId Launch WDA and establish the session with this sessionId + * @return {?object} State Object + */ + async launchWithPreinstalledWDA(sessionId) { + const xctestEnv = { + USE_PORT: this.wdaLocalPort || WDA_AGENT_PORT, + WDA_PRODUCT_BUNDLE_IDENTIFIER: this.bundleIdForXctest + }; + if (this.mjpegServerPort) { + xctestEnv.MJPEG_SERVER_PORT = this.mjpegServerPort; + } + this.log.info('Launching WebDriverAgent on the device without xcodebuild'); + this.xctestApiClient = new Xctest(this.device.udid, this.bundleIdForXctest, null, {env: xctestEnv}); + + await this.xctestApiClient.start(); + + this.setupProxies(sessionId); + const status = await this.getStatus(); + this.started = true; + return status; + } + /** * Return current running WDA's status like below after launching WDA * { @@ -286,6 +331,13 @@ class WebDriverAgent { return await this.getStatus(); } + if (this.usePreinstalledWDA) { + if (this.isRealDevice) { + return await this.launchWithPreinstalledWDA(sessionId); + } + throw new Error('usePreinstalledWDA is available only for a real device.'); + } + this.log.info('Launching WebDriverAgent on the device'); this.setupProxies(sessionId); @@ -393,10 +445,17 @@ class WebDriverAgent { } async quit () { - this.log.info('Shutting down sub-processes'); - - await this.xcodebuild.quit(); - await this.xcodebuild.reset(); + if (this.usePreinstalledWDA) { + if (this.xctestApiClient) { + this.log.info('Stopping the XCTest session'); + this.xctestApiClient.stop(); + this.xctestApiClient = null; + } + } else { + this.log.info('Shutting down sub-processes'); + await this.xcodebuild.quit(); + await this.xcodebuild.reset(); + } if (this.jwproxy) { this.jwproxy.sessionId = null; @@ -437,6 +496,9 @@ class WebDriverAgent { } async retrieveDerivedDataPath () { + if (this.usePreinstalledWDA) { + return; + } return await this.xcodebuild.retrieveDerivedDataPath(); } diff --git a/package.json b/package.json index a5b994186..f8e7a711a 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "@appium/base-driver": "^9.0.0", "@appium/support": "^3.0.0", "@babel/runtime": "^7.0.0", + "appium-ios-device": "^2.5.0", "appium-ios-simulator": "^5.0.1", "async-lock": "^1.0.0", "asyncbox": "^2.5.3",