Skip to content

Commit

Permalink
feat: Add the device property to the driver (#2364)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach authored Mar 27, 2024
1 parent be49758 commit 92148aa
Show file tree
Hide file tree
Showing 36 changed files with 412 additions and 380 deletions.
29 changes: 11 additions & 18 deletions lib/commands/app-management.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ export default {
const srcAppPath = await this.helpers.configureApp(app, '.app');
this.log.info(
`Installing '${srcAppPath}' to the ${this.isRealDevice() ? 'real device' : 'Simulator'} ` +
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
`with UDID '${this.opts.device.udid}'`,
`with UDID '${this.device.udid}'`,
);
if (!(await fs.exists(srcAppPath))) {
throw this.log.errorWithException(
Expand All @@ -36,7 +35,7 @@ export default {
const bundleId = await extractBundleId(srcAppPath);
const {install} = await this.checkAutInstallationState(
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
{enforceAppInstall: false, fullReset: false, noReset: false, bundleId, device: this.opts.device, app: srcAppPath}
{enforceAppInstall: false, fullReset: false, noReset: false, bundleId, device: this.device, app: srcAppPath}
);

if (!install) {
Expand All @@ -45,8 +44,7 @@ export default {
}
}

// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.installApp(
await this.device.installApp(
srcAppPath,
timeoutMs ?? this.opts.appPushTimeout,
strategy ?? this.opts.appInstallStrategy,
Expand All @@ -62,8 +60,7 @@ export default {
* @this {XCUITestDriver}
*/
async mobileIsAppInstalled(bundleId) {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
const installed = await this.opts.device.isAppInstalled(bundleId);
const installed = await this.device.isAppInstalled(bundleId);
this.log.info(`App '${bundleId}' is${installed ? '' : ' not'} installed`);
return installed;
},
Expand All @@ -78,14 +75,10 @@ export default {
async mobileRemoveApp(bundleId) {
this.log.info(
`Uninstalling the application with bundle identifier '${bundleId}' ` +
`from the ${this.isRealDevice() ? 'real device' : 'Simulator'} with UDID '${
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
this.opts.device.udid
}'`,
`from the ${this.isRealDevice() ? 'real device' : 'Simulator'} with UDID '${this.device.udid}'`,
);
try {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.removeApp(bundleId);
await this.device.removeApp(bundleId);
this.log.info(`Removal of '${bundleId}' succeeded`);
return true;
} catch (err) {
Expand Down Expand Up @@ -158,8 +151,9 @@ export default {
throw new errors.UnsupportedOperationError('A real device is required');
}

// @ts-expect-error - do not assign arbitrary properties to `this.opts`
return await this.opts.device.terminateApp(bundleId, this.opts.platformVersion);
return await /** @type {import('../real-device').RealDevice} */ (this.device).terminateApp(
bundleId, String(this.opts.platformVersion)
);
},

/**
Expand Down Expand Up @@ -232,7 +226,7 @@ export default {
throw new errors.NotImplementedError(`This extension is only supported on real devices`);
}

const service = await services.startInstallationProxyService(this.opts.device.udid);
const service = await services.startInstallationProxyService(this.device.udid);
try {
return await service.listApplications({applicationType});
} finally {
Expand All @@ -258,8 +252,7 @@ export default {
);
}

// @ts-ignore This opt must exist
const simctl = this.opts.device.simctl;
const simctl = /** @type {import('../driver').Simulator} */ (this.device).simctl;
const dataRoot = await simctl.getAppContainer(bundleId, 'data');
this.log.debug(`Got the data container root of ${bundleId} at '${dataRoot}'`);
if (!await fs.exists(dataRoot)) {
Expand Down
8 changes: 4 additions & 4 deletions lib/commands/appearance.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ export default {

if (this.isSimulator()) {
try {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
return void (await this.opts.device.setAppearance(style));
return void (await /** @type {import('../driver').Simulator} */ (this.device).setAppearance(style));
} catch (e) {
this.log.debug(e.stack);
}
Expand Down Expand Up @@ -53,8 +52,9 @@ export default {
let style;
if (this.isSimulator()) {
try {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
style = await this.opts.device.getAppearance();
style = /** @type {Style} */ (
await /** @type {import('../driver').Simulator} */ (this.device).getAppearance()
);
} catch (ign) {}
}
if (!style) {
Expand Down
9 changes: 3 additions & 6 deletions lib/commands/biometric.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export default {
async mobileEnrollBiometric(isEnabled = true) {
assertSimulator(this);

// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.enrollBiometric(isEnabled);
await /** @type {import('../driver').Simulator} */ (this.device).enrollBiometric(isEnabled);
},

/**
Expand All @@ -33,8 +32,7 @@ export default {
async mobileSendBiometricMatch(type = 'touchId', match = true) {
assertSimulator(this);

// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.sendBiometricMatch(match, type);
await /** @type {import('../driver').Simulator} */ (this.device).sendBiometricMatch(match, type);
},

/**
Expand All @@ -48,8 +46,7 @@ export default {
async mobileIsBiometricEnrolled() {
assertSimulator(this);

// @ts-expect-error - do not assign arbitrary properties to `this.opts`
return await this.opts.device.isBiometricEnrolled();
return await /** @type {import('../driver').Simulator} */ (this.device).isBiometricEnrolled();
},
};

Expand Down
8 changes: 3 additions & 5 deletions lib/commands/certificate.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export default {
* @param {string} [commonName] - Common name of the certificate. If this is not set, the command will try to parse it from the provided `content`.
* @param {boolean} isRoot - Defines where the certificate should be installed; either the Trusted Root Store (`true`) or the Keychain (`false`). On environments other than Xcode 11.4+ Simulator, this option is ignored.
* @returns {Promise<string|void>} The content of the generated `.mobileconfig` file as
a base64-encoded string. This config might be useful for debugging purposes. If the certificate has been successfully set via CLI, then nothing is returned.
* a base64-encoded string. This config might be useful for debugging purposes. If the certificate has been successfully set via CLI, then nothing is returned.
* @this {XCUITestDriver}
*/
async mobileInstallCertificate(content, commonName, isRoot = true) {
Expand All @@ -306,8 +306,7 @@ export default {
if (this.isSimulator()) {
try {
const methodName = isRoot ? 'addRootCertificate' : 'addCertificate';
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.simctl[methodName](Buffer.from(content, 'base64').toString(), {
await /** @type {import('../driver').Simulator} */ (this.device).simctl[methodName](Buffer.from(content, 'base64').toString(), {
raw: true,
});
return;
Expand Down Expand Up @@ -387,8 +386,7 @@ export default {
}
}
} else {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.openUrl(certUrl);
await /** @type {import('../driver').Simulator} */ (this.device).openUrl(certUrl);
}

let isCertAlreadyInstalled = false;
Expand Down
6 changes: 2 additions & 4 deletions lib/commands/condition.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ export default {
*/
async listConditionInducers() {
requireConditionInducerCompatibleDevice(this);
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
const conditionInducerService = await services.startInstrumentService(this.opts.device.udid);
const conditionInducerService = await services.startInstrumentService(this.device.udid);
try {
const ret = await conditionInducerService.callChannel(
INSTRUMENT_CHANNEL.CONDITION_INDUCER,
Expand Down Expand Up @@ -100,8 +99,7 @@ export default {
if (this._conditionInducerService && !this._conditionInducerService._socketClient.destroyed) {
this.log.errorAndThrow(`Condition inducer has been started. A condition is already active.`);
}
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
this._conditionInducerService = await services.startInstrumentService(this.opts.device.udid);
this._conditionInducerService = await services.startInstrumentService(this.device.udid);
const ret = await this._conditionInducerService.callChannel(
INSTRUMENT_CHANNEL.CONDITION_INDUCER,
'enableConditionWithIdentifier:profileIdentifier:',
Expand Down
3 changes: 1 addition & 2 deletions lib/commands/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,7 @@ const helpers = {
async getNewRemoteDebugger() {
let socketPath;
if (!this.isRealDevice()) {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
socketPath = await this.opts.device.getWebInspectorSocket();
socketPath = await /** @type {import('../driver').Simulator} */ (this.device).getWebInspectorSocket();
}
return createRemoteDebugger(
{
Expand Down
3 changes: 1 addition & 2 deletions lib/commands/deviceInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export default {
);

if (this.isRealDevice()) {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
const lockdownInfo = await utilities.getDeviceInfo(this.opts.device.udid);
const lockdownInfo = await utilities.getDeviceInfo(this.device.udid);
return {...infoByWda, ...{lockdownInfo}};
}

Expand Down
36 changes: 14 additions & 22 deletions lib/commands/file-movement.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ async function createService(udid, remotePath) {
/**
* Save the given base64 data chunk as a binary file on the Simulator under test.
*
* @param {Object} device - The device object, which represents the device under test.
* @param {import('../driver').Simulator} device - The device object, which represents the device under test.
* This object is expected to have the `udid` property containing the
* valid device ID.
* @param {string} remotePath - The remote path on the device. This variable can be prefixed with
Expand Down Expand Up @@ -140,7 +140,7 @@ async function pushFileToSimulator(device, remotePath, base64Data) {
/**
* Save the given base64 data chunk as a binary file on the device under test.
*
* @param {Object} device - The device object, which represents the device under test.
* @param {import('../real-device').RealDevice} device - The device object, which represents the device under test.
* This object is expected to have the `udid` property containing the
* valid device ID.
* @param {string} remotePath - The remote path on the device. This variable can be prefixed with
Expand Down Expand Up @@ -179,7 +179,7 @@ async function deleteFileOrFolder(device, remotePath, isSimulator) {
* Get the content of given file or folder from iOS Simulator and return it as base-64 encoded string.
* Folder content is recursively packed into a zip archive.
*
* @param {Object} device - The device object, which represents the device under test.
* @param {import('../driver').Simulator} device - The device object, which represents the device under test.
* This object is expected to have the `udid` property containing the
* valid device ID.
* @param {string} remotePath - The path to a file or a folder, which exists in the corresponding application
Expand Down Expand Up @@ -225,7 +225,7 @@ async function pullFromSimulator(device, remotePath, isFile) {
* Get the content of given file or folder from the real device under test and return it as base-64 encoded string.
* Folder content is recursively packed into a zip archive.
*
* @param {Object} device - The device object, which represents the device under test.
* @param {import('../real-device').RealDevice} device - The device object, which represents the device under test.
* This object is expected to have the `udid` property containing the
* valid device ID.
* @param {string} remotePath - The path to an existing remote file on the device. This variable can be prefixed with
Expand Down Expand Up @@ -266,7 +266,7 @@ async function pullFromRealDevice(device, remotePath, isFile) {
/**
* Remove the file or folder from the device
*
* @param {Object} device - The device object, which represents the device under test.
* @param {import('../driver').Simulator} device - The device object, which represents the device under test.
* This object is expected to have the `udid` property containing the
* valid device ID.
* @param {string} remotePath - The path to a file or a folder, which exists in the corresponding application
Expand Down Expand Up @@ -304,7 +304,7 @@ async function deleteFromSimulator(device, remotePath) {
/**
* Remove the file or folder from the device
*
* @param {Object} device - The device object, which represents the device under test.
* @param {import('../real-device').RealDevice} device - The device object, which represents the device under test.
* This object is expected to have the `udid` property containing the
* valid device ID.
* @param {string} remotePath - The path to an existing remote file on the device. This variable can be prefixed with
Expand Down Expand Up @@ -361,10 +361,8 @@ export default {
base64Data = Buffer.from(base64Data).toString('utf8');
}
return this.isSimulator()
? // @ts-expect-error - do not assign arbitrary properties to `this.opts`
await pushFileToSimulator(this.opts.device, remotePath, base64Data)
: // @ts-expect-error - do not assign arbitrary properties to `this.opts`
await pushFileToRealDevice(this.opts.device, remotePath, base64Data);
? await pushFileToSimulator(/** @type {import('../driver').Simulator} */ (this.device), remotePath, base64Data)
: await pushFileToRealDevice(/** @type {import('../real-device').RealDevice} */ (this.device), remotePath, base64Data);
},

/**
Expand Down Expand Up @@ -398,10 +396,8 @@ export default {
);
}
return this.isSimulator()
? // @ts-expect-error - do not assign arbitrary properties to `this.opts`
await pullFromSimulator(this.opts.device, remotePath, true)
: // @ts-expect-error - do not assign arbitrary properties to `this.opts`
await pullFromRealDevice(this.opts.device, remotePath, true);
? await pullFromSimulator(/** @type {import('../driver').Simulator} */ (this.device), remotePath, true)
: await pullFromRealDevice(/** @type {import('../real-device').RealDevice} */ (this.device), remotePath, true);
},

/**
Expand All @@ -427,8 +423,7 @@ export default {
if (!remotePath.endsWith('/')) {
remotePath = `${remotePath}/`;
}
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await deleteFileOrFolder(this.opts.device, remotePath, this.isSimulator());
await deleteFileOrFolder(this.device, remotePath, this.isSimulator());
},

/**
Expand All @@ -445,8 +440,7 @@ export default {
`'${remotePath}' is given instead`,
);
}
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await deleteFileOrFolder(this.opts.device, remotePath, this.isSimulator());
await deleteFileOrFolder(this.device, remotePath, this.isSimulator());
},

/**
Expand All @@ -463,10 +457,8 @@ export default {
remotePath = `${remotePath}/`;
}
return this.isSimulator()
? // @ts-expect-error - do not assign arbitrary properties to `this.opts`
await pullFromSimulator(this.opts.device, remotePath, false)
: // @ts-expect-error - do not assign arbitrary properties to `this.opts`
await pullFromRealDevice(this.opts.device, remotePath, false);
? await pullFromSimulator(/** @type {import('../driver').Simulator} */ (this.device), remotePath, false)
: await pullFromRealDevice(/** @type {import('../real-device').RealDevice} */ (this.device), remotePath, false);
},

/**
Expand Down
3 changes: 1 addition & 2 deletions lib/commands/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,7 @@ const commands = {
if (this.isRealDevice()) {
await this.proxyCommand('/url', 'POST', {url});
} else {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.simctl.openUrl(url);
await /** @type {import('../driver').Simulator} */ (this.device).simctl.openUrl(url);
}
},
/**
Expand Down
3 changes: 1 addition & 2 deletions lib/commands/gesture.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ const commands = {
if (!this.isSimulator()) {
throw new errors.UnknownError('Shake is not supported on real devices');
}
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.shake();
await /** @type {import('../driver').Simulator} */ (this.device).shake();
},
/**
* @this {XCUITestDriver}
Expand Down
4 changes: 2 additions & 2 deletions lib/commands/keychains.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default {
*/
async mobileClearKeychains() {
assertSimulator(this);
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.clearKeychains();

await /** @type {import('../driver').Simulator} */ (this.device).clearKeychains();
},
};
5 changes: 1 addition & 4 deletions lib/commands/localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ export default {
// Assign skipSyncUiDialogTranslation: true option in order to avoid shutting down the WDA session
localizationOptions.language = Object.assign(language, {skipSyncUiDialogTranslation: true});
}
return /** @type {boolean} */ (
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.configureLocalization(localizationOptions)
);
return await /** @type {import('../driver').Simulator} */ (this.device).configureLocalization(localizationOptions);
},
};
3 changes: 1 addition & 2 deletions lib/commands/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ export default {
}

if (this.isSimulator()) {
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
await this.opts.device.setGeolocation(`${latitude}`, `${longitude}`);
await /** @type {import('../driver').Simulator} */ (this.device).setGeolocation(`${latitude}`, `${longitude}`);
return /** @type {Location} */ ({latitude, longitude, altitude: 0});
}

Expand Down
6 changes: 2 additions & 4 deletions lib/commands/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ export default {
}
if (_.isUndefined(this.logs.syslog)) {
this.logs.crashlog = new IOSCrashLog({
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
sim: this.opts.device,
sim: this.device,
udid: this.isRealDevice() ? this.opts.udid : undefined,
});

Expand All @@ -115,8 +114,7 @@ export default {
});
} else {
this.logs.syslog = new IOSSimulatorLog({
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
sim: this.opts.device,
sim: this.device,
showLogs: this.opts.showIOSLog,
xcodeVersion: this.xcodeVersion,
iosSimulatorLogsPredicate: this.opts.iosSimulatorLogsPredicate,
Expand Down
Loading

0 comments on commit 92148aa

Please sign in to comment.