Skip to content

Commit

Permalink
chore: Import all mixin methods explicitly (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach authored Sep 21, 2023
1 parent d6b6bfb commit c691f20
Show file tree
Hide file tree
Showing 27 changed files with 182 additions and 70 deletions.
97 changes: 92 additions & 5 deletions lib/simctl.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
import _ from 'lodash';
import subcommands from './subcommands/index.js';
import which from 'which';
import log, { LOG_PREFIX } from './logger';
import {
DEFAULT_EXEC_TIMEOUT, getXcrunBinary,
} from './helpers';
import { exec as tpExec, SubProcess } from 'teen_process';
import addmediaCommands from './subcommands/addmedia';
import appinfoCommands from './subcommands/appinfo';
import bootCommands from './subcommands/boot';
import bootstatusCommands from './subcommands/bootstatus';
import createCommands from './subcommands/create';
import deleteCommands from './subcommands/delete';
import eraseCommands from './subcommands/erase';
import getappcontainerCommands from './subcommands/get_app_container';
import installCommands from './subcommands/install';
import ioCommands from './subcommands/io';
import keychainCommands from './subcommands/keychain';
import launchCommands from './subcommands/launch';
import listCommands from './subcommands/list';
import openurlCommands from './subcommands/openurl';
import pbcopyCommands from './subcommands/pbcopy';
import pbpasteCommands from './subcommands/pbpaste';
import privacyCommands from './subcommands/privacy';
import pushCommands from './subcommands/push';
import envCommands from './subcommands/getenv';
import shutdownCommands from './subcommands/shutdown';
import spawnCommands from './subcommands/spawn';
import terminateCommands from './subcommands/terminate';
import uiCommands from './subcommands/ui';
import uninstallCommands from './subcommands/uninstall';
import locationCommands from './subcommands/location';

const SIMCTL_ENV_PREFIX = 'SIMCTL_CHILD_';
const DEFAULT_OPTS = {
Expand Down Expand Up @@ -99,6 +123,10 @@ class Simctl {
return this._devicesSetPath;
}

/**
* @param {string?} [commandName=null]
* @returns {string}
*/
requireUdid (commandName = null) {
if (!this.udid) {
throw new Error(`udid is required to be set for ` +
Expand All @@ -107,6 +135,9 @@ class Simctl {
return this.udid;
}

/**
* @returns {Promise<string>}
*/
async requireXcrun () {
const xcrunBinary = getXcrunBinary();

Expand Down Expand Up @@ -188,12 +219,68 @@ class Simctl {
throw e;
}
}
}

addMedia = addmediaCommands.addMedia;

appInfo = appinfoCommands.appInfo;

bootDevice = bootCommands.bootDevice;

startBootMonitor = bootstatusCommands.startBootMonitor;

createDevice = createCommands.createDevice;

deleteDevice = deleteCommands.deleteDevice;

eraseDevice = eraseCommands.eraseDevice;

getAppContainer = getappcontainerCommands.getAppContainer;

getEnv = envCommands.getEnv;

installApp = installCommands.installApp;

getScreenshot = ioCommands.getScreenshot;

addRootCertificate = keychainCommands.addRootCertificate;
addCertificate = keychainCommands.addCertificate;
resetKeychain = keychainCommands.resetKeychain;

launchApp = launchCommands.launchApp;

getDevicesByParsing = listCommands.getDevicesByParsing;
getDevices = listCommands.getDevices;
getRuntimeForPlatformVersionViaJson = listCommands.getRuntimeForPlatformVersionViaJson;
getRuntimeForPlatformVersion = listCommands.getRuntimeForPlatformVersion;
getDeviceTypes = listCommands.getDeviceTypes;
list = listCommands.list;

setLocation = locationCommands.setLocation;
clearLocation = locationCommands.clearLocation;

openUrl = openurlCommands.openUrl;

setPasteboard = pbcopyCommands.setPasteboard;

getPasteboard = pbpasteCommands.getPasteboard;

grantPermission = privacyCommands.grantPermission;
revokePermission = privacyCommands.revokePermission;
resetPermission = privacyCommands.resetPermission;

pushNotification = pushCommands.pushNotification;

shutdownDevice = shutdownCommands.shutdownDevice;

spawnProcess = spawnCommands.spawnProcess;
spawnSubProcess = spawnCommands.spawnSubProcess;

terminateApp = terminateCommands.terminateApp;

getAppearance = uiCommands.getAppearance;
setAppearance = uiCommands.setAppearance;

// add all the subcommands to the Simctl prototype
for (const [fnName, fn] of _.toPairs(subcommands)) {
Simctl.prototype[fnName] = fn;
removeApp = uninstallCommands.removeApp;
}

export default Simctl;
Expand Down
3 changes: 3 additions & 0 deletions lib/subcommands/addmedia.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const commands = {};
* Add the particular media file to Simulator's library.
* It is required that Simulator is in _booted_ state.
*
* @this {import('../simctl').Simctl}
* @param {string} filePath - Full path to a media file on the local
* file system.
* @return {Promise<import('teen_process').TeenProcessExecResult>} Command execution result.
Expand All @@ -12,6 +13,8 @@ const commands = {};
* @throws {Error} If the `udid` instance property is unset
*/
commands.addMedia = async function addMedia (filePath) {
/** @type {import('teen_process').TeenProcessExecResult} */
// @ts-ignore The returned type is ok
return await this.exec('addmedia', {
args: [this.requireUdid('addmedia'), filePath],
});
Expand Down
3 changes: 3 additions & 0 deletions lib/subcommands/appinfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const commands = {};
* Simulator server should be in 'booted' state for this call to work properly.
* The tool is only available since Xcode SDK 8.1
*
* @this {import('../simctl').Simctl}
* @param {string} bundleId - The bundle identifier of the target application.
* @return {Promise<string>} The information about installed application.
*
Expand Down Expand Up @@ -41,6 +42,8 @@ const commands = {};
* @throws {Error} If the `udid` instance property is unset
*/
commands.appInfo = async function appInfo (bundleId) {
/** @type {import('teen_process').TeenProcessExecResult} */
// @ts-ignore The returned type is ok
const {stdout} = await this.exec('appinfo', {
args: [this.requireUdid('appinfo'), bundleId],
});
Expand Down
1 change: 1 addition & 0 deletions lib/subcommands/boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const commands = {};
/**
* Boot the particular Simulator if it is not running.
*
* @this {import('../simctl').Simctl}
* @throws {Error} If the corresponding simctl subcommand command
* returns non-zero return code.
* @throws {Error} If the `udid` instance property is unset
Expand Down
3 changes: 3 additions & 0 deletions lib/subcommands/bootstatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const commands = {};
* until Simulator booting is completed.
* The method is only available since Xcode8.
*
* @this {import('../simctl').Simctl}
* @param {BootMonitorOptions} [opts={}] - Monitoring options.
* @returns {Promise<import('teen_process').SubProcess>} The instance of the corresponding monitoring process.
* @throws {Error} If the Simulator fails to finish booting within the given timeout and onFinished
Expand All @@ -47,6 +48,8 @@ commands.startBootMonitor = async function startBootMonitor (opts = {}) {
if (shouldPreboot) {
args.push('-b');
}
/** @type {import('teen_process').SubProcess} */
// @ts-ignore The returned type is ok
const bootMonitor = await this.exec('bootstatus', {
args,
asynchronous: true,
Expand Down
3 changes: 3 additions & 0 deletions lib/subcommands/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const commands = {};
* Create Simulator device with given name for the particular
* platform type and version.
*
* @this {import('../simctl').Simctl}
* @param {string} name - The device name to be created.
* @param {string} deviceTypeId - Device type, for example 'iPhone 6'.
* @param {string} platformVersion - Platform version, for example '10.3'.
Expand Down Expand Up @@ -75,6 +76,8 @@ commands.createDevice = async function createDevice (name, deviceTypeId, platfor
log.debug(LOG_PREFIX,
`Creating simulator with name '${name}', device type id '${deviceTypeId}' and runtime id '${runtimeId}'`);
try {
/** @type {import('teen_process').TeenProcessExecResult} */
// @ts-ignore The returned type is ok
const {stdout} = await this.exec('create', {
args: [name, deviceTypeId, runtimeId]
});
Expand Down
1 change: 1 addition & 0 deletions lib/subcommands/delete.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const commands = {};
/**
* Delete the particular Simulator from available devices list.
*
* @this {import('../simctl').Simctl}
* @throws {Error} If the corresponding simctl subcommand command
* returns non-zero return code.
* @throws {Error} If the `udid` instance property is unset
Expand Down
1 change: 1 addition & 0 deletions lib/subcommands/erase.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const commands = {};
* Reset the content and settings of the particular Simulator.
* It is required that Simulator is in _shutdown_ state.
*
* @this {import('../simctl').Simctl}
* @param {number} [timeout=10000] - The maximum number of milliseconds to wait
* unit device reset is completed.
* @throws {Error} If the corresponding simctl subcommand command
Expand Down
2 changes: 2 additions & 0 deletions lib/subcommands/get_app_container.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const commands = {};
* like 'com.apple.springboard'.
* It is required that Simulator is in _booted_ state.
*
* @this {import('../simctl').Simctl}
* @param {string} bundleId - Bundle identifier of an application.
* @param {string?} [containerType=null] - Which container type to return. Possible values
* are 'app', 'data', 'groups', '<A specific App Group container>'.
Expand All @@ -22,6 +23,7 @@ commands.getAppContainer = async function getAppContainer (bundleId, containerTy
if (containerType) {
args.push(containerType);
}
// @ts-ignore The returned type is ok
const {stdout} = await this.exec('get_app_container', {args});
return (stdout || '').trim();
};
Expand Down
3 changes: 3 additions & 0 deletions lib/subcommands/getenv.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ const commands = {};
/**
* Retrieves the value of a Simulator environment variable
*
* @this {import('../simctl').Simctl}
* @param {string} varName - The name of the variable to be retrieved
* @returns {Promise<string|null>} The value of the variable or null if the given variable
* is not present in the Simulator environment
* @throws {Error} If there was an error while running the command
* @throws {Error} If the `udid` instance property is unset
*/
commands.getEnv = async function getEnv (varName) {
/** @type {import('teen_process').TeenProcessExecResult} */
// @ts-ignore the returned type is ok
const {stdout, stderr} = await this.exec('getenv', {
args: [this.requireUdid('getenv'), varName],
logErrors: false,
Expand Down
56 changes: 0 additions & 56 deletions lib/subcommands/index.js

This file was deleted.

1 change: 1 addition & 0 deletions lib/subcommands/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const commands = {};
* Install the particular application package on Simulator.
* It is required that Simulator is in _booted_ state.
*
* @this {import('../simctl').Simctl}
* @param {string} appPath - Full path to .app package, which is
* going to be installed.
* @throws {Error} If the corresponding simctl subcommand command
Expand Down
1 change: 1 addition & 0 deletions lib/subcommands/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const commands = {};
* Gets base64 screenshot for device
* It is required that Simulator is in _booted_ state.
*
* @this {import('../simctl').Simctl}
* @since Xcode SDK 8.1
* @return {Promise<string>} Base64-encoded Simulator screenshot.
* @throws {Error} If the corresponding simctl subcommand command
Expand Down
10 changes: 9 additions & 1 deletion lib/subcommands/keychain.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import { rimraf } from 'rimraf';

const commands = {};

/**
*
* @param {string|Buffer} payload
* @param {(filePath: string) => Promise<any>} onPayloadStored
*/
async function handleRawPayload (payload, onPayloadStored) {
const filePath = path.resolve(os.tmpdir(), `${uuidV4()}.pem`);
try {
Expand All @@ -33,6 +38,7 @@ async function handleRawPayload (payload, onPayloadStored) {
* Adds the given certificate to the Trusted Root Store on the simulator
*
* @since Xcode 11.4 SDK
* @this {import('../simctl').Simctl}
* @param {string} cert the full path to a valid .cert file containing
* the certificate content or the certificate content itself, depending on
* options
Expand All @@ -45,7 +51,7 @@ commands.addRootCertificate = async function addRootCertificate (cert, opts = {}
const {
raw = false,
} = opts;
const execMethod = async (certPath) => await this.exec('keychain', {
const execMethod = async (/** @type {string} */certPath) => await this.exec('keychain', {
args: [this.requireUdid('keychain add-root-cert'), 'add-root-cert', certPath],
});
if (raw) {
Expand All @@ -59,6 +65,7 @@ commands.addRootCertificate = async function addRootCertificate (cert, opts = {}
* Adds the given certificate to the Keychain Store on the simulator
*
* @since Xcode 11.4 SDK
* @this {import('../simctl').Simctl}
* @param {string} cert the full path to a valid .cert file containing
* the certificate content or the certificate content itself, depending on
* options
Expand All @@ -85,6 +92,7 @@ commands.addCertificate = async function addCertificate (cert, opts = {}) {
* Resets the simulator keychain
*
* @since Xcode 11.4 SDK
* @this {import('../simctl').Simctl}
* @throws {Error} if the current SDK version does not support the command
* or there was an error while resetting the keychain
* @throws {Error} If the `udid` instance property is unset
Expand Down
3 changes: 3 additions & 0 deletions lib/subcommands/launch.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const commands = {};
* It is required that Simulator is in _booted_ state and
* the application with given bundle identifier is already installed.
*
* @this {import('../simctl').Simctl}
* @param {string} bundleId - Bundle identifier of the application,
* which is going to be removed.
* @param {number} [tries=5] - The maximum number of retries before
Expand All @@ -20,6 +21,8 @@ const commands = {};
commands.launchApp = async function launchApp (bundleId, tries = 5) {
// @ts-ignore A string will always be returned
return await retryInterval(tries, 1000, async () => {
/** @type {import('teen_process').TeenProcessExecResult} */
// @ts-ignore the returned type is ok
const {stdout} = await this.exec('launch', {
args: [this.requireUdid('launch'), bundleId],
});
Expand Down
Loading

0 comments on commit c691f20

Please # to comment.