Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion lib/commands/device-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import iphoneSimulatorLibPath = require("./../iphone-simulator");

export class Command implements ICommand {
public execute(args: string[]): void {
public execute(args: string[]): Promise<void> {
var iphoneSimulator = new iphoneSimulatorLibPath.iPhoneSimulator();
return iphoneSimulator.printDeviceTypes();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import iphoneSimulatorLibPath = require("./../iphone-simulator");
import options = require("../options");

export class Command implements ICommand {
public execute(args: string[]): string {
public execute(args: string[]): Promise<string> {
var iphoneSimulator = new iphoneSimulatorLibPath.iPhoneSimulator();
return iphoneSimulator.run(args[0], args[1], options);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/notify-post.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import iphoneSimulatorLibPath = require("./../iphone-simulator");

export class Command implements ICommand {
public execute(args: string[]): void {
public execute(args: string[]): Promise<void> {
var iphoneSimulator = new iphoneSimulatorLibPath.iPhoneSimulator();
return iphoneSimulator.sendNotification(args[0], args[1]);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/sdks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import iphoneSimulatorLibPath = require("./../iphone-simulator");

export class Command implements ICommand {
public execute(args: string[]): void {
public execute(args: string[]): Promise<void> {
var iphoneSimulator = new iphoneSimulatorLibPath.iPhoneSimulator();
return iphoneSimulator.printSDKS();
}
Expand Down
46 changes: 23 additions & 23 deletions lib/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"use strict";

interface IiPhoneSimulator {
run(applicationPath: string, applicationIdentifier: string, options: IOptions): string;
printDeviceTypes(): void;
printSDKS(): void;
sendNotification(notification: string, deviceId: string): void;
run(applicationPath: string, applicationIdentifier: string, options: IOptions): Promise<string>;
printDeviceTypes(): Promise<void>;
printSDKS(): Promise<void>;
sendNotification(notification: string, deviceId: string): Promise<void>;
createSimulator(): ISimulator;
}

Expand All @@ -27,34 +27,34 @@ interface IDevice {
}

interface ISimctl {
launch(deviceId: string, applicationIdentifier: string, options: IOptions): string;
boot(deviceId: string): void;
terminate(deviceId: string, appIdentifier: string): string;
install(deviceId: string, applicationPath: string): void;
uninstall(deviceId: string, applicationIdentifier: string, opts?: any): void;
notifyPost(deviceId: string, notification: string): void;
getDevices(): IDevice[];
launch(deviceId: string, applicationIdentifier: string, options: IOptions): Promise<string>;
boot(deviceId: string): Promise<void>;
terminate(deviceId: string, appIdentifier: string): Promise<string>;
install(deviceId: string, applicationPath: string): Promise<void>;
uninstall(deviceId: string, applicationIdentifier: string, opts?: any): Promise<void>;
notifyPost(deviceId: string, notification: string): Promise<void>;
getDevices(): Promise<IDevice[]>;
getLog(deviceId: string, predicate?: string): any;
getAppContainer(deviceId: string, applicationIdentifier: string): string;
getAppContainer(deviceId: string, applicationIdentifier: string): Promise<string>;
}

interface IDictionary<T> {
[key: string]: T;
}

interface ISimulator extends INameGetter {
getDevices(): IDevice[];
getSdks(): ISdk[];
run(applicationPath: string, applicationIdentifier: string, options: IOptions): string;
sendNotification(notification: string, deviceId: string): void;
getApplicationPath(deviceId: string, applicationIdentifier: string): string;
getDevices(): Promise<IDevice[]>;
getSdks(): Promise<ISdk[]>;
run(applicationPath: string, applicationIdentifier: string, options: IOptions): Promise<string>;
sendNotification(notification: string, deviceId: string): Promise<void>;
getApplicationPath(deviceId: string, applicationIdentifier: string): Promise<string>;
getInstalledApplications(deviceId: string): IApplication[];
installApplication(deviceId: string, applicationPath: string): void;
uninstallApplication(deviceId: string, appIdentifier: string): void;
startApplication(deviceId: string, appIdentifier: string, options: IOptions): string;
stopApplication(deviceId: string, appIdentifier: string, bundleExecutable: string): string;
getDeviceLogProcess(deviceId: string): any;
startSimulator(options: IOptions, device?: IDevice): void;
installApplication(deviceId: string, applicationPath: string): Promise<void>;
uninstallApplication(deviceId: string, appIdentifier: string): Promise<void>;
startApplication(deviceId: string, appIdentifier: string, options: IOptions): Promise<string>;
stopApplication(deviceId: string, appIdentifier: string, bundleExecutable: string): Promise<string>;
getDeviceLogProcess(deviceId: string): Promise<any>;
startSimulator(options: IOptions, device?: IDevice): Promise<void>;
}

interface INameGetter {
Expand Down
15 changes: 7 additions & 8 deletions lib/ios-sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ Object.defineProperty(publicApi, "getRunningSimulators", {
return (...args: any[]) => {
let isResolved = false;

return new Promise<any>((resolve, reject) => {
return new Promise<any>(async (resolve, reject) => {
const libraryPath = require("./iphone-simulator-xcode-simctl");
const simulator = new libraryPath.XCodeSimctlSimulator();

const tryGetBootedDevices = () => {
const tryGetBootedDevices = async () => {
try {
return simulator.getBootedDevices.apply(simulator, args);
return await simulator.getBootedDevices.apply(simulator, args);
} catch (err) {
if (!isResolved) {
isResolved = true;
Expand All @@ -67,17 +67,16 @@ Object.defineProperty(publicApi, "getRunningSimulators", {
}
}

let result = tryGetBootedDevices();
let result = await tryGetBootedDevices();
if (result && result.length) {
isResolved = true;
resolve(result);
return;
}

if (!isResolved && (!result || !result.length)) {
const timer = setTimeout(() => {
result = tryGetBootedDevices();

const timer = setTimeout(async () => {
result = await tryGetBootedDevices();
if (!isResolved) {
isResolved = true;
resolve(result);
Expand Down
65 changes: 33 additions & 32 deletions lib/iphone-simulator-xcode-simctl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
this.simctl = new Simctl();
}

public getDevices(): IDevice[] {
public getDevices(): Promise<IDevice[]> {
return this.simctl.getDevices();
}

public getSdks(): ISdk[] {
let devices = this.simctl.getDevices();
public async getSdks(): Promise<ISdk[]> {
let devices = await this.simctl.getDevices();
return _.map(devices, device => {
return {
displayName: `iOS ${device.runtimeVersion}`,
Expand All @@ -44,8 +44,8 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
});
}

public run(applicationPath: string, applicationIdentifier: string, options: IOptions): string {
const device = this.getDeviceToRun(options);
public async run(applicationPath: string, applicationIdentifier: string, options: IOptions): Promise<string> {
const device = await this.getDeviceToRun(options);

this.startSimulator(options, device);
if (!options.skipInstall) {
Expand All @@ -55,40 +55,41 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
return this.simctl.launch(device.id, applicationIdentifier, options);
}

public sendNotification(notification: string, deviceId: string): void {
public sendNotification(notification: string, deviceId: string): Promise<void> {
let device = this.getDeviceFromIdentifier(deviceId);

if (!device) {
errors.fail("Could not find device.");
}

this.simctl.notifyPost(deviceId, notification);
return this.simctl.notifyPost(deviceId, notification);
}

public getApplicationPath(deviceId: string, applicationIdentifier: string): string {
public getApplicationPath(deviceId: string, applicationIdentifier: string): Promise<string> {
return this.simctl.getAppContainer(deviceId, applicationIdentifier);
}

public getInstalledApplications(deviceId: string): IApplication[] {
return common.getInstalledApplications(deviceId);
}

public installApplication(deviceId: string, applicationPath: string): void {
public installApplication(deviceId: string, applicationPath: string): Promise<void> {
return this.simctl.install(deviceId, applicationPath);
}

public uninstallApplication(deviceId: string, appIdentifier: string): void {
public uninstallApplication(deviceId: string, appIdentifier: string): Promise<void> {
return this.simctl.uninstall(deviceId, appIdentifier, { skipError: true });
}

public startApplication(deviceId: string, appIdentifier: string, options: IOptions): string {
public async startApplication(deviceId: string, appIdentifier: string, options: IOptions): Promise<string> {
// simctl launch command does not launch the process immediately and we have to wait a little bit,
// just to ensure all related processes and services are alive.
const launchResult = this.simctl.launch(deviceId, appIdentifier, options);
const launchResult = await this.simctl.launch(deviceId, appIdentifier, options);
utils.sleep(0.5);
return launchResult;
}

public stopApplication(deviceId: string, appIdentifier: string, bundleExecutable: string): string {
public async stopApplication(deviceId: string, appIdentifier: string, bundleExecutable: string): Promise<string> {
try {
let xcodeMajorVersion: number = null;
try {
Expand All @@ -103,7 +104,7 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
// Xcode 7.x does not have support for `xcrun simctl terminate` command
resultOfTermination = childProcess.execSync(`killall ${bundleExecutable}`, { skipError: true });
} else {
resultOfTermination = this.simctl.terminate(deviceId, appIdentifier);
resultOfTermination = await this.simctl.terminate(deviceId, appIdentifier);
}

// killall command does not terminate the processes immediately and we have to wait a little bit,
Expand All @@ -116,9 +117,9 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
}
}

public getDeviceLogProcess(deviceId: string, predicate?: string): child_process.ChildProcess {
public async getDeviceLogProcess(deviceId: string, predicate?: string): Promise<child_process.ChildProcess> {
if (!this.isDeviceLogOperationStarted) {
const device = this.getDeviceFromIdentifier(deviceId);
const device = await this.getDeviceFromIdentifier(deviceId);
const deviceVersion = device ? device.runtimeVersion : "";
const majorVersion = deviceVersion.split(".")[0];

Expand All @@ -135,8 +136,8 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
return this.deviceLogChildProcess;
}

private getDeviceToRun(options: IOptions, device?: any): IDevice {
let devices = _.sortBy(this.simctl.getDevices(), (device) => device.runtimeVersion),
private async getDeviceToRun(options: IOptions, device?: any): Promise<IDevice> {
let devices = _.sortBy(await this.simctl.getDevices(), (device) => device.runtimeVersion),
sdkVersion = options.sdkVersion || options.sdk,
deviceIdOrName = options.device;

Expand Down Expand Up @@ -181,30 +182,30 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
return device.state === 'Booted';
}

private getBootedDevice(): IDevice {
let devices = this.simctl.getDevices();
private async getBootedDevice(): Promise<IDevice> {
let devices = await this.simctl.getDevices();
return _.find(devices, device => this.isDeviceBooted(device));
}

private getBootedDevices(): IDevice[] {
const devices = this.simctl.getDevices();
private async getBootedDevices(): Promise<IDevice[]> {
const devices = await this.simctl.getDevices();
return _.filter(devices, device => this.isDeviceBooted(device));
}

public startSimulator(options: IOptions, device?: IDevice): void {
public async startSimulator(options: IOptions, device?: IDevice): Promise<void> {
if (!device && options.device) {
this.verifyDevice(options.device);
}

device = device || this.getDeviceToRun(options);
device = device || await this.getDeviceToRun(options);

// In case the id is undefined, skip verification - we'll start default simulator.
if (device && device.id) {
this.verifyDevice(device);
}

if (!device || !device.runtimeVersion || !device.fullId) {
device = this.getDeviceToRun(options, device);
device = await this.getDeviceToRun(options, device);
}

if (!this.isDeviceBooted(device)) {
Expand All @@ -214,7 +215,7 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
if (isSimulatorAppRunning) {
// In case user closes simulator window but simulator app is still alive
if (!haveBootedDevices) {
device = this.getDeviceToRun(options);
device = await this.getDeviceToRun(options);
}
this.simctl.boot(device.id);
} else {
Expand All @@ -229,8 +230,8 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
}
}

private haveBootedDevices(): boolean {
const bootedDevices = this.getBootedDevices();
private async haveBootedDevices(): Promise<boolean> {
const bootedDevices = await this.getBootedDevices();
return bootedDevices && bootedDevices.length > 0;
}

Expand All @@ -245,16 +246,16 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
}
}

private verifyDevice(device: IDevice | string): void {
const availableDevices = this.getDevices();
private async verifyDevice(device: IDevice | string): Promise<void> {
const availableDevices = await this.getDevices();
const deviceId = (<IDevice>device).id || device;
if (!_.find(availableDevices, { id: deviceId }) && !_.find(availableDevices, { name: deviceId })) {
errors.fail(`No simulator image available for device identifier '${deviceId}'.`);
}
}

private getDeviceFromIdentifier(deviceId: string) {
const availableDevices = this.getDevices();
private async getDeviceFromIdentifier(deviceId: string) {
const availableDevices = await this.getDevices();

return _.find(availableDevices, { id: deviceId });
}
Expand Down
16 changes: 8 additions & 8 deletions lib/iphone-simulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ export class iPhoneSimulator implements IiPhoneSimulator {
this.simulator = this.createSimulator();
}

public run(applicationPath: string, applicationIdentifier: string, options: IOptions): string {
public async run(applicationPath: string, applicationIdentifier: string, options: IOptions): Promise<string> {
if (!fs.existsSync(applicationPath)) {
errors.fail("Path does not exist ", applicationPath);
}

if (options.device) {
const hasSuchDevice = _.find(this.simulator.getDevices(), device => device.name === options.device || device.id === options.device);
const hasSuchDevice = _.find(await this.simulator.getDevices(), device => device.name === options.device || device.id === options.device);
if (!hasSuchDevice) {
errors.fail(`Unable to find device ${options.device}.`);
}
}

let sdkVersion = options.sdkVersion || options.sdk;
if (sdkVersion) {
let runtimeVersions = _.unique(_.map(this.simulator.getDevices(), (device: IDevice) => device.runtimeVersion));
let runtimeVersions = _.unique(_.map(await this.simulator.getDevices(), (device: IDevice) => device.runtimeVersion));
if (!_.contains(runtimeVersions, sdkVersion)) {
errors.fail(`Unable to find sdk ${sdkVersion}. The valid runtime versions are ${runtimeVersions.join(", ")}`);
}
Expand All @@ -41,13 +41,13 @@ export class iPhoneSimulator implements IiPhoneSimulator {
return this.simulator.run(applicationPath, applicationIdentifier, options);
}

public printDeviceTypes(): void {
let devices = this.simulator.getDevices();
public async printDeviceTypes(): Promise<void> {
let devices = await this.simulator.getDevices();
_.each(devices, device => console.log(`Device Identifier: ${device.fullId}. ${os.EOL}Runtime version: ${device.runtimeVersion} ${os.EOL}`));
}

public printSDKS(): void {
let sdks = this.simulator.getSdks();
public async printSDKS(): Promise<void> {
let sdks = await this.simulator.getSdks();
_.each(sdks, (sdk) => {
let output = ` Display Name: ${sdk.displayName} ${os.EOL} Version: ${sdk.version} ${os.EOL}`;
if (sdk.rootPath) {
Expand All @@ -57,7 +57,7 @@ export class iPhoneSimulator implements IiPhoneSimulator {
});
}

public sendNotification(notification: string, deviceId: string): void {
public sendNotification(notification: string, deviceId: string): Promise<void> {
if (!notification) {
errors.fail("Notification required.");
}
Expand Down
Loading