mirror of
https://github.com/appium/appium.git
synced 2026-01-25 19:59:17 -06:00
Merge pull request #4250 from jlipps/new-simctl
use external simctl library
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var logger = require('../../server/logger.js').get('appium')
|
||||
, _ = require('underscore')
|
||||
, exec = require('child_process').exec
|
||||
, async = require('async');
|
||||
|
||||
var Simctl = function (opts) {
|
||||
var requiredOpts = [];
|
||||
_.each(requiredOpts, function (opt) {
|
||||
if (!_.has(opts, opt)) {
|
||||
throw new Error(opt + " is required");
|
||||
}
|
||||
this[opt] = opts[opt];
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Simctl.exec = function (cmd, timeout, args, cb) {
|
||||
if (typeof args === "function") {
|
||||
cb = args;
|
||||
args = [];
|
||||
}
|
||||
args = _.map(args, function (arg) {
|
||||
if (args.indexOf(" ") !== -1) {
|
||||
return '"' + arg + '"';
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
cmd = "xcrun simctl " + cmd + " " + args.join(' ');
|
||||
logger.debug("Executing: " + cmd);
|
||||
exec(cmd, {timeout: timeout}, cb);
|
||||
};
|
||||
|
||||
Simctl.delete = function (udid, cb) {
|
||||
Simctl.exec("delete", 0, [udid], cb);
|
||||
};
|
||||
|
||||
Simctl.erase = function (udid, cb) {
|
||||
// wait at least 2s for simctl to do its thing
|
||||
var cmdTimeout = 2000, cmdRetry = 5;
|
||||
|
||||
var erase = function (callback) {
|
||||
var ms = Date.now();
|
||||
Simctl.exec("erase", cmdTimeout, [udid], function (err, stdout, stderr) {
|
||||
if (err) {
|
||||
err.message += " // stderr: " + stderr;
|
||||
setTimeout(callback.bind(null, err), Math.max(cmdTimeout - (Date.now() - ms), 1));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async.retry(cmdRetry, erase, cb);
|
||||
};
|
||||
|
||||
Simctl.getDevices = function (forSdk, cb) {
|
||||
if (typeof forSdk === "function") {
|
||||
cb = forSdk;
|
||||
forSdk = null;
|
||||
}
|
||||
Simctl.exec("list", 0, ["devices"], function (err, stdout) {
|
||||
if (err) return cb(err);
|
||||
var deviceSecRe = /-- iOS (.+) --(\n .+)*/mg;
|
||||
var matches = [];
|
||||
var devices = {};
|
||||
var match = deviceSecRe.exec(stdout);
|
||||
while (match !== null) {
|
||||
matches.push(match);
|
||||
match = deviceSecRe.exec(stdout);
|
||||
}
|
||||
if (matches.length < 1) {
|
||||
return cb(new Error("Could not find device section"));
|
||||
}
|
||||
_.each(matches, function (match) {
|
||||
var sdk = match[1];
|
||||
devices[sdk] = [];
|
||||
_.each(match[0].split("\n").slice(1), function (line) {
|
||||
var lineRe = /^ (.+) \((.+)\) \((.+)\)/;
|
||||
var match = lineRe.exec(line);
|
||||
if (match === null) {
|
||||
throw new Error("Couldn't match line");
|
||||
}
|
||||
var device = {};
|
||||
device.name = match[1];
|
||||
device.udid = match[2];
|
||||
device.state = match[3];
|
||||
devices[sdk].push(device);
|
||||
});
|
||||
});
|
||||
if (forSdk) {
|
||||
if (!_.has(devices, forSdk)) {
|
||||
cb(new Error("Sdk " + forSdk + " was not in list of simctl sdks"));
|
||||
} else {
|
||||
cb(null, devices[forSdk]);
|
||||
}
|
||||
} else {
|
||||
cb(null, devices);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = Simctl;
|
||||
@@ -9,7 +9,7 @@ var logger = require('../../server/logger.js').get('appium')
|
||||
, ncp = require('ncp')
|
||||
, mkdirp = require('mkdirp')
|
||||
, xcode = require('./xcode.js')
|
||||
, Simctl = require('./simctl.js')
|
||||
, simctl = require('../../future').simctl
|
||||
, multiResolve = require('../../helpers.js').multiResolve
|
||||
, rimraf = require('rimraf')
|
||||
, xmlplist = require('plist')
|
||||
@@ -380,7 +380,7 @@ Simulator.prototype.cleanSim = function (keepKeychains, tempDir, cb) {
|
||||
], cb);
|
||||
};
|
||||
|
||||
var cleanSim = _.partial(Simctl.erase, this.udid);
|
||||
var cleanSim = _.partial(simctl.eraseDevice, this.udid);
|
||||
|
||||
if (keepKeychains) {
|
||||
logger.debug("Resetting simulator and saving Keychains");
|
||||
@@ -505,7 +505,7 @@ Simulator.prototype.deleteSim = function (cb) {
|
||||
|
||||
var deleteSimVEight = function (cb) {
|
||||
logger.debug('Resetting Content and Settings for Simulator');
|
||||
Simctl.erase(this.udid, cb);
|
||||
simctl.eraseDevice(this.udid, cb);
|
||||
}.bind(this);
|
||||
|
||||
var deleteSimLessThanVEight = function (cb) {
|
||||
@@ -569,7 +569,7 @@ Simulator.getSimAppPrefsFile = function () {
|
||||
|
||||
Simulator.prototype.deleteOtherSims = function (cb) {
|
||||
logger.debug("Isolating the requested simulator by deleting all others");
|
||||
Simctl.getDevices(function (err, devices) {
|
||||
simctl.getDevices(function (err, devices) {
|
||||
if (err) return cb(err);
|
||||
var udids = [];
|
||||
var deleteCalls = [];
|
||||
@@ -577,7 +577,7 @@ Simulator.prototype.deleteOtherSims = function (cb) {
|
||||
udids = udids.concat(_.pluck(sdkDevices, 'udid'));
|
||||
});
|
||||
_.each(_.without(udids, this.udid), function (udid) {
|
||||
deleteCalls.push(_.partial(Simctl.delete, udid));
|
||||
deleteCalls.push(_.partial(simctl.deleteDevice, udid));
|
||||
});
|
||||
async.series(deleteCalls, cb);
|
||||
}.bind(this));
|
||||
|
||||
28
lib/future.js
Normal file
28
lib/future.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('underscore')
|
||||
, Q = require('q')
|
||||
, simctl = require("node-simctl");
|
||||
|
||||
var nodeify = function (obj) {
|
||||
if (typeof obj !== "function") {
|
||||
var nodeified = {};
|
||||
_.each(Object.getOwnPropertyNames(obj), function (name) {
|
||||
if (name !== "__esModule") {
|
||||
nodeified[name] = nodeify(obj[name]);
|
||||
}
|
||||
});
|
||||
return nodeified;
|
||||
}
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
var cb = args[args.length - 1];
|
||||
args = args.slice(0, -1);
|
||||
return new Q(obj.apply(null, args)).nodeify(cb);
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
simctl: nodeify(simctl),
|
||||
nodeify: nodeify
|
||||
};
|
||||
@@ -1,5 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
// set up distributed logging before everything else
|
||||
var npmlog = global._global_npmlog = require('npmlog');
|
||||
// npmlog is used only for emitting, we use winston for output
|
||||
npmlog.level = "silent";
|
||||
|
||||
var winston = require('winston'),
|
||||
fs = require('fs');
|
||||
require('date-utils');
|
||||
@@ -19,9 +24,28 @@ var colors = {
|
||||
, error: 'red'
|
||||
};
|
||||
|
||||
var npmToWinstonLevels = {
|
||||
silly: 'debug'
|
||||
, verbose: 'debug'
|
||||
, info: 'info'
|
||||
, http: 'info'
|
||||
, warn: 'warn'
|
||||
, error: 'error'
|
||||
};
|
||||
|
||||
var logger = null;
|
||||
var timeZone = null;
|
||||
|
||||
// capture any logs emitted by other packages using our global distributed
|
||||
// logger and pass them through winston
|
||||
npmlog.on('log', function (logObj) {
|
||||
var winstonLevel = npmToWinstonLevels[logObj.level] || 'info';
|
||||
var msg = logObj.message && logObj.prefix ?
|
||||
(logObj.prefix + ": " + logObj.message) :
|
||||
(logObj.prefix || logObj.message);
|
||||
logger[winstonLevel](msg);
|
||||
});
|
||||
|
||||
var timestamp = function () {
|
||||
var date = new Date();
|
||||
if (!timeZone) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var parser = require('./parser.js')()
|
||||
, logFactory = require('./logger.js')
|
||||
, logger = null
|
||||
|
||||
@@ -70,7 +70,9 @@
|
||||
"namp": "0.2.25",
|
||||
"ncp": "~0.5.1",
|
||||
"node-idevice": "~0.1.2",
|
||||
"node-simctl": "~1.0.9",
|
||||
"node-uuid": "~1.4.1",
|
||||
"npmlog": "~0.1.1",
|
||||
"path": "~0.4.9",
|
||||
"plist": "~1.0.0",
|
||||
"prompt": "~0.2.13",
|
||||
|
||||
Reference in New Issue
Block a user