Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support prebuiltWDAPath for iOS 17 #868

Merged
merged 6 commits into from
Mar 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 79 additions & 4 deletions lib/webdriveragent.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { waitForCondition } from 'asyncbox';
import _ from 'lodash';
import path from 'path';
import url from 'url';
Expand Down Expand Up @@ -66,6 +67,7 @@ class WebDriverAgent {

this.updatedWDABundleId = args.updatedWDABundleId;

this.wdaLaunchTimeout = args.wdaLaunchTimeout || WDA_LAUNCH_TIMEOUT;
this.usePreinstalledWDA = args.usePreinstalledWDA;
this.xctestApiClient = null;

Expand All @@ -87,7 +89,7 @@ class WebDriverAgent {
useSimpleBuildTest: args.useSimpleBuildTest,
usePrebuiltWDA: args.usePrebuiltWDA,
updatedWDABundleId: this.updatedWDABundleId,
launchTimeout: args.wdaLaunchTimeout || WDA_LAUNCH_TIMEOUT,
launchTimeout: this.wdaLaunchTimeout,
wdaRemotePort: this.wdaRemotePort,
useXctestrunFile: this.useXctestrunFile,
derivedDataPath: args.derivedDataPath,
Expand Down Expand Up @@ -184,7 +186,6 @@ class WebDriverAgent {
* }
*
* @return {Promise<any?>} State Object
* @throws {Error} If there was invalid response code or body
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
*/
async getStatus () {
const noSessionProxy = new NoSessionProxy({
Expand Down Expand Up @@ -287,6 +288,73 @@ class WebDriverAgent {
}
}


/**
* @typedef {Object} LaunchWdaViaDeviceCtlOptions
* @property {Record<string, string|number>} [env] environment variables for the launching WDA process
*/

/**
* Launch WDA with preinstalled package with 'xcrun devicectl device process launch'.
* The WDA package must be prepared properly like published via
* https://github.com/appium/WebDriverAgent/releases
* with proper sign for this case.
*
* When we implement launching XCTest service via appium-ios-device,
* this implementation can be replaced with it.
*
* @param {LaunchWdaViaDeviceCtlOptions} [opts={}] launching WDA with devicectl command options.
* @return {Promise<void>}
*/
async _launchViaDevicectl(opts = {}) {
// FIXME: use appium-xcuitest-driver's Devicectl. Maybe it needs to be included in the `this.device`?
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
//

const {env} = opts;

let xcrunBinnaryPath;
try {
xcrunBinnaryPath = await fs.which('xcrun');
} catch (e) {
throw new Error(
`xcrun has not been found in PATH. ` +
`Please make sure XCode development tools are installed`,
);
}

const cmd = [
'devicectl',
'device',
'process',
'launch',
`--device`, this.device.udid,
'--terminate-existing'
];
if (!_.isEmpty(env)) {
cmd.push('--environment-variables', JSON.stringify(_.mapValues(env, (v) => _.toString(v))));
};
cmd.push(this.bundleIdForXctest);

const {stdout} = await exec(xcrunBinnaryPath, cmd);
this.log.debug(`The output of devicectl command: ${stdout}`);

// Launching app via decictl does not wait for the app start.
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
// We should wait for the app start by ourselves.
try {
await waitForCondition(async () => !_.isNull(await this.getStatus()), {
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
waitMs: this.wdaLaunchTimeout,
intervalMs: 300,
});

} catch (err) {
throw new Error(
`Failed to start the preinstalled WebDriverAgent in ${this.wdaLaunchTimeout} ms. ` +
`The WebDriverAgent might not be properly built or the device might be locked. ` +
'appium:wdaLaunchTimeout capability modifies the timeout.'
);
}
}

/**
* Launch WDA with preinstalled package without xcodebuild.
* @param {string} sessionId Launch WDA and establish the session with this sessionId
Expand All @@ -302,8 +370,15 @@ class WebDriverAgent {
}
this.log.info('Launching WebDriverAgent on the device without xcodebuild');
if (this.isRealDevice) {
this.xctestApiClient = new Xctest(this.device.udid, this.bundleIdForXctest, null, {env: xctestEnv});
await this.xctestApiClient.start();
// Current method to launch WDA process can be done via 'xcrun devicectl',
// but it has limitation about the WDA preinstalled package.
// https://github.com/appium/appium/issues/19206#issuecomment-2014182674
if (util.compareVersions(this.platformVersion, '>=', '17.0')) {
KazuCocoa marked this conversation as resolved.
Show resolved Hide resolved
await this._launchViaDevicectl({env: xctestEnv});
} else {
this.xctestApiClient = new Xctest(this.device.udid, this.bundleIdForXctest, null, {env: xctestEnv});
await this.xctestApiClient.start();
}
} else {
await this.device.simctl.exec('launch', {
args: [
Expand Down
Loading