appium-adb-test
Version:
Android Debug Bridge interface
1,380 lines (1,080 loc) • 85.5 kB
JavaScript
'use strict';
var _regeneratorRuntime = require('babel-runtime/regenerator')['default'];
var _getIterator = require('babel-runtime/core-js/get-iterator')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
Object.defineProperty(exports, '__esModule', {
value: true
});
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _loggerJs = require('../logger.js');
var _loggerJs2 = _interopRequireDefault(_loggerJs);
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _appiumSupport = require('appium-support');
var _helpers = require('../helpers');
var _teen_process = require('teen_process');
var _asyncbox = require('asyncbox');
var systemCallMethods = {};
var DEFAULT_ADB_EXEC_TIMEOUT = 20000; // in milliseconds
systemCallMethods.getSdkBinaryPath = function callee$0$0(binaryName) {
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_loggerJs2['default'].info('Checking whether ' + binaryName + ' is present');
if (!this.sdkRoot) {
context$1$0.next = 5;
break;
}
return context$1$0.abrupt('return', this.getBinaryFromSdkRoot(binaryName));
case 5:
_loggerJs2['default'].warn('The ANDROID_HOME environment variable is not set to the Android SDK ' + 'root directory path. ANDROID_HOME is required for compatibility ' + ('with SDK 23+. Checking along PATH for ' + binaryName + '.'));
context$1$0.next = 8;
return _regeneratorRuntime.awrap(this.getBinaryFromPath(binaryName));
case 8:
return context$1$0.abrupt('return', context$1$0.sent);
case 9:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.getCommandForOS = function () {
var cmd = "which";
if (_appiumSupport.system.isWindows()) {
cmd = "where";
}
return cmd;
};
systemCallMethods.getBinaryNameForOS = function (binaryName) {
if (_appiumSupport.system.isWindows()) {
if (binaryName === "android") {
binaryName += ".bat";
} else {
if (binaryName.indexOf(".exe", binaryName.length - 4) === -1) {
binaryName += ".exe";
}
}
}
return binaryName;
};
systemCallMethods.getBinaryFromSdkRoot = function callee$0$0(binaryName) {
var binaryLoc, binaryLocs, buildToolDirs, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionDir, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, loc, flag;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
binaryLoc = null;
binaryName = this.getBinaryNameForOS(binaryName);
binaryLocs = [_path2['default'].resolve(this.sdkRoot, "platform-tools", binaryName), _path2['default'].resolve(this.sdkRoot, "tools", binaryName)];
buildToolDirs = [];
context$1$0.next = 6;
return _regeneratorRuntime.awrap((0, _helpers.getDirectories)(_path2['default'].resolve(this.sdkRoot, "build-tools")));
case 6:
buildToolDirs = context$1$0.sent;
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
context$1$0.prev = 10;
for (_iterator = _getIterator(buildToolDirs); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
versionDir = _step.value;
binaryLocs.push(_path2['default'].resolve(this.sdkRoot, "build-tools", versionDir, binaryName));
}
context$1$0.next = 18;
break;
case 14:
context$1$0.prev = 14;
context$1$0.t0 = context$1$0['catch'](10);
_didIteratorError = true;
_iteratorError = context$1$0.t0;
case 18:
context$1$0.prev = 18;
context$1$0.prev = 19;
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
case 21:
context$1$0.prev = 21;
if (!_didIteratorError) {
context$1$0.next = 24;
break;
}
throw _iteratorError;
case 24:
return context$1$0.finish(21);
case 25:
return context$1$0.finish(18);
case 26:
_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
context$1$0.prev = 29;
_iterator2 = _getIterator(binaryLocs);
case 31:
if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
context$1$0.next = 40;
break;
}
loc = _step2.value;
context$1$0.next = 35;
return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(loc));
case 35:
flag = context$1$0.sent;
if (flag) {
binaryLoc = loc;
}
case 37:
_iteratorNormalCompletion2 = true;
context$1$0.next = 31;
break;
case 40:
context$1$0.next = 46;
break;
case 42:
context$1$0.prev = 42;
context$1$0.t1 = context$1$0['catch'](29);
_didIteratorError2 = true;
_iteratorError2 = context$1$0.t1;
case 46:
context$1$0.prev = 46;
context$1$0.prev = 47;
if (!_iteratorNormalCompletion2 && _iterator2['return']) {
_iterator2['return']();
}
case 49:
context$1$0.prev = 49;
if (!_didIteratorError2) {
context$1$0.next = 52;
break;
}
throw _iteratorError2;
case 52:
return context$1$0.finish(49);
case 53:
return context$1$0.finish(46);
case 54:
if (!(binaryLoc === null)) {
context$1$0.next = 56;
break;
}
throw new Error('Could not find ' + binaryName + ' in tools, platform-tools, ' + ('or supported build-tools under ' + this.sdkRoot + ' ') + 'do you have the Android SDK installed at this location?');
case 56:
binaryLoc = binaryLoc.trim();
_loggerJs2['default'].info('Using ' + binaryName + ' from ' + binaryLoc);
return context$1$0.abrupt('return', binaryLoc);
case 59:
case 'end':
return context$1$0.stop();
}
}, null, this, [[10, 14, 18, 26], [19,, 21, 25], [29, 42, 46, 54], [47,, 49, 53]]);
};
systemCallMethods.getBinaryFromPath = function callee$0$0(binaryName) {
var binaryLoc, cmd, _ref, stdout;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
binaryLoc = null;
cmd = this.getCommandForOS();
context$1$0.prev = 2;
context$1$0.next = 5;
return _regeneratorRuntime.awrap((0, _teen_process.exec)(cmd, [binaryName]));
case 5:
_ref = context$1$0.sent;
stdout = _ref.stdout;
_loggerJs2['default'].info('Using ' + binaryName + ' from ' + stdout);
// TODO write a test for binaries with spaces.
binaryLoc = stdout.trim();
return context$1$0.abrupt('return', binaryLoc);
case 12:
context$1$0.prev = 12;
context$1$0.t0 = context$1$0['catch'](2);
_loggerJs2['default'].errorAndThrow('Could not find ' + binaryName + ' Please set the ANDROID_HOME ' + 'environment variable with the Android SDK root directory path.');
case 15:
case 'end':
return context$1$0.stop();
}
}, null, this, [[2, 12]]);
};
systemCallMethods.getConnectedDevices = function callee$0$0() {
var _ref2, stdout, startingIndex, devices, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, line, lineInfo;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_loggerJs2['default'].debug("Getting connected devices...");
context$1$0.prev = 1;
context$1$0.next = 4;
return _regeneratorRuntime.awrap((0, _teen_process.exec)(this.executable.path, ['devices']));
case 4:
_ref2 = context$1$0.sent;
stdout = _ref2.stdout;
startingIndex = stdout.indexOf("List of devices");
if (!(startingIndex === -1)) {
context$1$0.next = 11;
break;
}
throw new Error('Unexpected output while trying to get devices. output was: ' + stdout);
case 11:
// slicing ouput we care about.
stdout = stdout.slice(startingIndex);
devices = [];
_iteratorNormalCompletion3 = true;
_didIteratorError3 = false;
_iteratorError3 = undefined;
context$1$0.prev = 16;
for (_iterator3 = _getIterator(stdout.split("\n")); !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
line = _step3.value;
if (line.trim() !== "" && line.indexOf("List of devices") === -1 && line.indexOf("* daemon") === -1 && line.indexOf("offline") === -1) {
lineInfo = line.split("\t");
// state is either "device" or "offline", afaict
devices.push({ udid: lineInfo[0], state: lineInfo[1] });
}
}
context$1$0.next = 24;
break;
case 20:
context$1$0.prev = 20;
context$1$0.t0 = context$1$0['catch'](16);
_didIteratorError3 = true;
_iteratorError3 = context$1$0.t0;
case 24:
context$1$0.prev = 24;
context$1$0.prev = 25;
if (!_iteratorNormalCompletion3 && _iterator3['return']) {
_iterator3['return']();
}
case 27:
context$1$0.prev = 27;
if (!_didIteratorError3) {
context$1$0.next = 30;
break;
}
throw _iteratorError3;
case 30:
return context$1$0.finish(27);
case 31:
return context$1$0.finish(24);
case 32:
_loggerJs2['default'].debug(devices.length + ' device(s) connected');
return context$1$0.abrupt('return', devices);
case 34:
context$1$0.next = 39;
break;
case 36:
context$1$0.prev = 36;
context$1$0.t1 = context$1$0['catch'](1);
_loggerJs2['default'].errorAndThrow('Error while getting connected devices. Original error: ' + context$1$0.t1.message);
case 39:
case 'end':
return context$1$0.stop();
}
}, null, this, [[1, 36], [16, 20, 24, 32], [25,, 27, 31]]);
};
systemCallMethods.getDevicesWithRetry = function callee$0$0() {
var timeoutMs = arguments.length <= 0 || arguments[0] === undefined ? 20000 : arguments[0];
var start, getDevices;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
var _this = this;
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
start = Date.now();
_loggerJs2['default'].debug("Trying to find a connected android device");
getDevices = function getDevices() {
var devices;
return _regeneratorRuntime.async(function getDevices$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
if (!(Date.now() - start > timeoutMs)) {
context$2$0.next = 2;
break;
}
throw new Error("Could not find a connected Android device.");
case 2:
context$2$0.prev = 2;
context$2$0.next = 5;
return _regeneratorRuntime.awrap(this.getConnectedDevices());
case 5:
devices = context$2$0.sent;
if (!(devices.length < 1)) {
context$2$0.next = 15;
break;
}
_loggerJs2['default'].debug("Could not find devices, restarting adb server...");
context$2$0.next = 10;
return _regeneratorRuntime.awrap(this.restartAdb());
case 10:
context$2$0.next = 12;
return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(200));
case 12:
context$2$0.next = 14;
return _regeneratorRuntime.awrap(getDevices());
case 14:
return context$2$0.abrupt('return', context$2$0.sent);
case 15:
return context$2$0.abrupt('return', devices);
case 18:
context$2$0.prev = 18;
context$2$0.t0 = context$2$0['catch'](2);
_loggerJs2['default'].debug("Could not find devices, restarting adb server...");
context$2$0.next = 23;
return _regeneratorRuntime.awrap(this.restartAdb());
case 23:
context$2$0.next = 25;
return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(200));
case 25:
context$2$0.next = 27;
return _regeneratorRuntime.awrap(getDevices());
case 27:
return context$2$0.abrupt('return', context$2$0.sent);
case 28:
case 'end':
return context$2$0.stop();
}
}, null, _this, [[2, 18]]);
};
context$1$0.next = 5;
return _regeneratorRuntime.awrap(getDevices());
case 5:
return context$1$0.abrupt('return', context$1$0.sent);
case 6:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.restartAdb = function callee$0$0() {
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
if (this.suppressKillServer) {
context$1$0.next = 10;
break;
}
_loggerJs2['default'].debug('Restarting adb');
context$1$0.prev = 2;
context$1$0.next = 5;
return _regeneratorRuntime.awrap((0, _teen_process.exec)(this.executable.path, ['kill-server']));
case 5:
context$1$0.next = 10;
break;
case 7:
context$1$0.prev = 7;
context$1$0.t0 = context$1$0['catch'](2);
_loggerJs2['default'].error("Error killing ADB server, going to see if it's online anyway");
case 10:
case 'end':
return context$1$0.stop();
}
}, null, this, [[2, 7]]);
};
systemCallMethods.adbExec = function callee$0$0(cmd) {
var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var execFunc;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
var _this2 = this;
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
if (cmd) {
context$1$0.next = 2;
break;
}
throw new Error("You need to pass in a command to adbExec()");
case 2:
// setting default timeout for each command to prevent infinite wait.
opts.timeout = opts.timeout || DEFAULT_ADB_EXEC_TIMEOUT;
execFunc = function execFunc() {
var linkerWarningRe, args, _ref3, stdout, protocolFaultError, deviceNotFoundError;
return _regeneratorRuntime.async(function execFunc$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
linkerWarningRe = /^WARNING: linker.+$/m;
context$2$0.prev = 1;
if (!(cmd instanceof Array)) {
cmd = [cmd];
}
args = this.executable.defaultArgs.concat(cmd);
_loggerJs2['default'].debug('Running \'' + this.executable.path + '\' with args: ' + ('' + JSON.stringify(args)));
context$2$0.next = 7;
return _regeneratorRuntime.awrap((0, _teen_process.exec)(this.executable.path, args, opts));
case 7:
_ref3 = context$2$0.sent;
stdout = _ref3.stdout;
// sometimes ADB prints out stupid stdout warnings that we don't want
// to include in any of the response data, so let's strip it out
stdout = stdout.replace(linkerWarningRe, '').trim();
return context$2$0.abrupt('return', stdout);
case 13:
context$2$0.prev = 13;
context$2$0.t0 = context$2$0['catch'](1);
protocolFaultError = new RegExp("protocol fault \\(no status\\)", "i").test(context$2$0.t0);
deviceNotFoundError = new RegExp("error: device ('.+' )?not found", "i").test(context$2$0.t0);
if (!(protocolFaultError || deviceNotFoundError)) {
context$2$0.next = 23;
break;
}
_loggerJs2['default'].info('Error sending command, reconnecting device and retrying: ' + cmd);
context$2$0.next = 21;
return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(1000));
case 21:
context$2$0.next = 23;
return _regeneratorRuntime.awrap(this.getDevicesWithRetry());
case 23:
if (!context$2$0.t0.stdout) {
context$2$0.next = 27;
break;
}
stdout = context$2$0.t0.stdout;
stdout = stdout.replace(linkerWarningRe, '').trim();
return context$2$0.abrupt('return', stdout);
case 27:
throw new Error('Error executing adbExec. Original error: \'' + context$2$0.t0.message + '\'; ' + ('Stderr: \'' + (context$2$0.t0.stderr || '').trim() + '\'; Code: \'' + context$2$0.t0.code + '\''));
case 28:
case 'end':
return context$2$0.stop();
}
}, null, _this2, [[1, 13]]);
};
context$1$0.next = 6;
return _regeneratorRuntime.awrap((0, _asyncbox.retry)(2, execFunc));
case 6:
return context$1$0.abrupt('return', context$1$0.sent);
case 7:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.shell = function callee$0$0(cmd) {
var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var execCmd;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.next = 2;
return _regeneratorRuntime.awrap(this.isDeviceConnected());
case 2:
if (context$1$0.sent) {
context$1$0.next = 4;
break;
}
throw new Error('No device connected, cannot run adb shell command \'' + cmd.join(' ') + '\'');
case 4:
execCmd = ['shell'];
if (cmd instanceof Array) {
execCmd = execCmd.concat(cmd);
} else {
execCmd.push(cmd);
}
context$1$0.next = 8;
return _regeneratorRuntime.awrap(this.adbExec(execCmd, opts));
case 8:
return context$1$0.abrupt('return', context$1$0.sent);
case 9:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.createSubProcess = function () {
var args = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
// add the default arguments
args = this.executable.defaultArgs.concat(args);
_loggerJs2['default'].debug('Creating ADB subprocess with args: ' + JSON.stringify(args));
return new _teen_process.SubProcess(this.getAdbPath(), args);
};
// TODO can probably deprecate this now that the logic is just to read
// this.adbPort
systemCallMethods.getAdbServerPort = function () {
return this.adbPort;
};
systemCallMethods.getEmulatorPort = function callee$0$0() {
var devices, port;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_loggerJs2['default'].debug("Getting running emulator port");
if (!(this.emulatorPort !== null)) {
context$1$0.next = 3;
break;
}
return context$1$0.abrupt('return', this.emulatorPort);
case 3:
context$1$0.prev = 3;
context$1$0.next = 6;
return _regeneratorRuntime.awrap(this.getConnectedDevices());
case 6:
devices = context$1$0.sent;
port = this.getPortFromEmulatorString(devices[0].udid);
if (!port) {
context$1$0.next = 12;
break;
}
return context$1$0.abrupt('return', port);
case 12:
throw new Error('Emulator port not found');
case 13:
context$1$0.next = 18;
break;
case 15:
context$1$0.prev = 15;
context$1$0.t0 = context$1$0['catch'](3);
_loggerJs2['default'].errorAndThrow('No devices connected. Original error: ' + context$1$0.t0.message);
case 18:
case 'end':
return context$1$0.stop();
}
}, null, this, [[3, 15]]);
};
systemCallMethods.getPortFromEmulatorString = function (emStr) {
var portPattern = /emulator-(\d+)/;
if (portPattern.test(emStr)) {
return parseInt(portPattern.exec(emStr)[1], 10);
}
return false;
};
systemCallMethods.getConnectedEmulators = function callee$0$0() {
var devices, emulators, _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, device, port;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.prev = 0;
_loggerJs2['default'].debug("Getting connected emulators");
context$1$0.next = 4;
return _regeneratorRuntime.awrap(this.getConnectedDevices());
case 4:
devices = context$1$0.sent;
emulators = [];
_iteratorNormalCompletion4 = true;
_didIteratorError4 = false;
_iteratorError4 = undefined;
context$1$0.prev = 9;
for (_iterator4 = _getIterator(devices); !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
device = _step4.value;
port = this.getPortFromEmulatorString(device.udid);
if (port) {
device.port = port;
emulators.push(device);
}
}
context$1$0.next = 17;
break;
case 13:
context$1$0.prev = 13;
context$1$0.t0 = context$1$0['catch'](9);
_didIteratorError4 = true;
_iteratorError4 = context$1$0.t0;
case 17:
context$1$0.prev = 17;
context$1$0.prev = 18;
if (!_iteratorNormalCompletion4 && _iterator4['return']) {
_iterator4['return']();
}
case 20:
context$1$0.prev = 20;
if (!_didIteratorError4) {
context$1$0.next = 23;
break;
}
throw _iteratorError4;
case 23:
return context$1$0.finish(20);
case 24:
return context$1$0.finish(17);
case 25:
_loggerJs2['default'].debug(emulators.length + ' emulator(s) connected');
return context$1$0.abrupt('return', emulators);
case 29:
context$1$0.prev = 29;
context$1$0.t1 = context$1$0['catch'](0);
_loggerJs2['default'].errorAndThrow('Error getting emulators. Original error: ' + context$1$0.t1.message);
case 32:
case 'end':
return context$1$0.stop();
}
}, null, this, [[0, 29], [9, 13, 17, 25], [18,, 20, 24]]);
};
systemCallMethods.setEmulatorPort = function (emPort) {
this.emulatorPort = emPort;
};
systemCallMethods.setDeviceId = function (deviceId) {
_loggerJs2['default'].debug('Setting device id to ' + deviceId);
this.curDeviceId = deviceId;
var argsHasDevice = this.executable.defaultArgs.indexOf('-s');
if (argsHasDevice !== -1) {
// remove the old device id from the arguments
this.executable.defaultArgs.splice(argsHasDevice, 2);
}
this.executable.defaultArgs.push('-s', deviceId);
};
systemCallMethods.setDevice = function (deviceObj) {
var deviceId = deviceObj.udid;
var emPort = this.getPortFromEmulatorString(deviceId);
this.setEmulatorPort(emPort);
this.setDeviceId(deviceId);
};
systemCallMethods.getRunningAVD = function callee$0$0(avdName) {
var emulators, _iteratorNormalCompletion5, _didIteratorError5, _iteratorError5, _iterator5, _step5, emulator, runningAVDName;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.prev = 0;
_loggerJs2['default'].debug('Trying to find ' + avdName + ' emulator');
context$1$0.next = 4;
return _regeneratorRuntime.awrap(this.getConnectedEmulators());
case 4:
emulators = context$1$0.sent;
_iteratorNormalCompletion5 = true;
_didIteratorError5 = false;
_iteratorError5 = undefined;
context$1$0.prev = 8;
_iterator5 = _getIterator(emulators);
case 10:
if (_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done) {
context$1$0.next = 23;
break;
}
emulator = _step5.value;
this.setEmulatorPort(emulator.port);
context$1$0.next = 15;
return _regeneratorRuntime.awrap(this.sendTelnetCommand("avd name"));
case 15:
runningAVDName = context$1$0.sent;
if (!(avdName === runningAVDName)) {
context$1$0.next = 20;
break;
}
_loggerJs2['default'].debug('Found emulator ' + avdName + ' in port ' + emulator.port);
this.setDeviceId(emulator.udid);
return context$1$0.abrupt('return', emulator);
case 20:
_iteratorNormalCompletion5 = true;
context$1$0.next = 10;
break;
case 23:
context$1$0.next = 29;
break;
case 25:
context$1$0.prev = 25;
context$1$0.t0 = context$1$0['catch'](8);
_didIteratorError5 = true;
_iteratorError5 = context$1$0.t0;
case 29:
context$1$0.prev = 29;
context$1$0.prev = 30;
if (!_iteratorNormalCompletion5 && _iterator5['return']) {
_iterator5['return']();
}
case 32:
context$1$0.prev = 32;
if (!_didIteratorError5) {
context$1$0.next = 35;
break;
}
throw _iteratorError5;
case 35:
return context$1$0.finish(32);
case 36:
return context$1$0.finish(29);
case 37:
_loggerJs2['default'].debug('Emulator ' + avdName + ' not running');
return context$1$0.abrupt('return', null);
case 41:
context$1$0.prev = 41;
context$1$0.t1 = context$1$0['catch'](0);
_loggerJs2['default'].errorAndThrow('Error getting AVD. Original error: ' + context$1$0.t1.message);
case 44:
case 'end':
return context$1$0.stop();
}
}, null, this, [[0, 41], [8, 25, 29, 37], [30,, 32, 36]]);
};
systemCallMethods.getRunningAVDWithRetry = function callee$0$0(avdName) {
var timeoutMs = arguments.length <= 1 || arguments[1] === undefined ? 20000 : arguments[1];
var start, runningAVD;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.prev = 0;
start = Date.now();
case 2:
if (!(Date.now() - start < timeoutMs)) {
context$1$0.next = 18;
break;
}
context$1$0.prev = 3;
context$1$0.next = 6;
return _regeneratorRuntime.awrap(this.getRunningAVD(avdName.replace('@', '')));
case 6:
runningAVD = context$1$0.sent;
if (!runningAVD) {
context$1$0.next = 9;
break;
}
return context$1$0.abrupt('return', runningAVD);
case 9:
context$1$0.next = 14;
break;
case 11:
context$1$0.prev = 11;
context$1$0.t0 = context$1$0['catch'](3);
// Do nothing.
_loggerJs2['default'].info('Couldn\'t get running AVD, will retry. Error was: ' + context$1$0.t0.message);
case 14:
context$1$0.next = 16;
return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(200));
case 16:
context$1$0.next = 2;
break;
case 18:
_loggerJs2['default'].errorAndThrow('Could not find ' + avdName + ' emulator.');
context$1$0.next = 24;
break;
case 21:
context$1$0.prev = 21;
context$1$0.t1 = context$1$0['catch'](0);
_loggerJs2['default'].errorAndThrow('Error getting AVD with retry. Original error: ' + context$1$0.t1.message);
case 24:
case 'end':
return context$1$0.stop();
}
}, null, this, [[0, 21], [3, 11]]);
};
systemCallMethods.killAllEmulators = function callee$0$0() {
var cmd, args;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
cmd = undefined, args = undefined;
if (_appiumSupport.system.isWindows()) {
cmd = 'TASKKILL';
args = ['TASKKILL', '/IM', 'emulator.exe'];
} else {
cmd = '/usr/bin/killall';
args = ['-m', 'emulator*'];
}
context$1$0.prev = 2;
context$1$0.next = 5;
return _regeneratorRuntime.awrap((0, _teen_process.exec)(cmd, args));
case 5:
context$1$0.next = 10;
break;
case 7:
context$1$0.prev = 7;
context$1$0.t0 = context$1$0['catch'](2);
_loggerJs2['default'].errorAndThrow('Error killing emulators. Original error: ' + context$1$0.t0.message);
case 10:
case 'end':
return context$1$0.stop();
}
}, null, this, [[2, 7]]);
};
systemCallMethods.killEmulator = function callee$0$0(avdName) {
var device;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_loggerJs2['default'].debug('killing avd \'' + avdName + '\'');
context$1$0.next = 3;
return _regeneratorRuntime.awrap(this.getRunningAVD(avdName));
case 3:
device = context$1$0.sent;
if (!device) {
context$1$0.next = 10;
break;
}
context$1$0.next = 7;
return _regeneratorRuntime.awrap(this.adbExec(['emu', 'kill']));
case 7:
_loggerJs2['default'].info('successfully killed emulator \'' + avdName + '\'');
context$1$0.next = 11;
break;
case 10:
_loggerJs2['default'].info('no avd with name \'' + avdName + '\' running. skipping kill step.');
case 11:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.launchAVD = function callee$0$0(avdName, avdArgs, language, country) {
var avdLaunchTimeout = arguments.length <= 4 || arguments[4] === undefined ? 60000 : arguments[4];
var avdReadyTimeout = arguments.length <= 5 || arguments[5] === undefined ? 60000 : arguments[5];
var retryTimes = arguments.length <= 6 || arguments[6] === undefined ? 1 : arguments[6];
var emulatorBinaryPath, launchArgs, locale, proc;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_loggerJs2['default'].debug('Launching Emulator with AVD ' + avdName + ', launchTimeout' + (avdLaunchTimeout + ' ms and readyTimeout ' + avdReadyTimeout + ' ms'));
context$1$0.next = 3;
return _regeneratorRuntime.awrap(this.getSdkBinaryPath("emulator"));
case 3:
emulatorBinaryPath = context$1$0.sent;
if (avdName[0] === "@") {
avdName = avdName.substr(1);
}
context$1$0.next = 7;
return _regeneratorRuntime.awrap(this.checkAvdExist(avdName));
case 7:
launchArgs = ["-avd", avdName];
if (typeof language === "string") {
_loggerJs2['default'].debug('Setting Android Device Language to ' + language);
launchArgs.push("-prop", 'persist.sys.language=' + language.toLowerCase());
}
if (typeof country === "string") {
_loggerJs2['default'].debug('Setting Android Device Country to ' + country);
launchArgs.push("-prop", 'persist.sys.country=' + country.toUpperCase());
}
locale = undefined;
if (typeof language === "string" && typeof country === "string") {
locale = language.toLowerCase() + "-" + country.toUpperCase();
} else if (typeof language === "string") {
locale = language.toLowerCase();
} else if (typeof country === "string") {
locale = country;
}
if (typeof locale === "string") {
_loggerJs2['default'].debug('Setting Android Device Locale to ' + locale);
launchArgs.push("-prop", 'persist.sys.locale=' + locale);
}
if (typeof avdArgs === "string") {
avdArgs = avdArgs.split(" ");
launchArgs = launchArgs.concat(avdArgs);
}
proc = new _teen_process.SubProcess(emulatorBinaryPath, launchArgs);
context$1$0.next = 17;
return _regeneratorRuntime.awrap(proc.start(0));
case 17:
proc.on('output', function (stdout, stderr) {
_loggerJs2['default'].info('[AVD OUTPUT] ' + (stdout || stderr));
});
context$1$0.next = 20;
return _regeneratorRuntime.awrap((0, _asyncbox.retry)(retryTimes, this.getRunningAVDWithRetry.bind(this), avdName, avdLaunchTimeout));
case 20:
context$1$0.next = 22;
return _regeneratorRuntime.awrap(this.waitForEmulatorReady(avdReadyTimeout));
case 22:
return context$1$0.abrupt('return', proc);
case 23:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.checkAvdExist = function callee$0$0(avdName) {
var cmd, args, _ref4, stdout, existings;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.next = 2;
return _regeneratorRuntime.awrap(this.getSdkBinaryPath('android'));
case 2:
cmd = context$1$0.sent;
args = ['list', 'avd', '-c'];
context$1$0.next = 6;
return _regeneratorRuntime.awrap((0, _teen_process.exec)(cmd, args));
case 6:
_ref4 = context$1$0.sent;
stdout = _ref4.stdout;
if (stdout.indexOf(avdName) === -1) {
existings = '(' + stdout.trim().replace(/[\n]/g, '), (') + ')';
_loggerJs2['default'].errorAndThrow('Avd \'' + avdName + '\' is not available. please select your avd name from one of these: \'' + existings + '\'');
}
case 9:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.waitForEmulatorReady = function callee$0$0() {
var timeoutMs = arguments.length <= 0 || arguments[0] === undefined ? 20000 : arguments[0];
var start, stdout;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
start = Date.now();
_loggerJs2['default'].debug("Waiting until emulator is ready");
case 2:
if (!(Date.now() - start < timeoutMs)) {
context$1$0.next = 17;
break;
}
context$1$0.prev = 3;
context$1$0.next = 6;
return _regeneratorRuntime.awrap(this.shell(["getprop", "init.svc.bootanim"]));
case 6:
stdout = context$1$0.sent;
if (!(stdout.indexOf('stopped') > -1)) {
context$1$0.next = 9;
break;
}
return context$1$0.abrupt('return');
case 9:
context$1$0.next = 13;
break;
case 11:
context$1$0.prev = 11;
context$1$0.t0 = context$1$0['catch'](3);
case 13:
context$1$0.next = 15;
return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(3000));
case 15:
context$1$0.next = 2;
break;
case 17:
_loggerJs2['default'].errorAndThrow('Emulator not ready');
case 18:
case 'end':
return context$1$0.stop();
}
}, null, this, [[3, 11]]);
};
systemCallMethods.waitForDevice = function callee$0$0() {
var appDeviceReadyTimeout = arguments.length <= 0 || arguments[0] === undefined ? 30 : arguments[0];
var retries, timeout;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
var _this3 = this;
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
this.appDeviceReadyTimeout = appDeviceReadyTimeout;
retries = 3;
timeout = parseInt(this.appDeviceReadyTimeout, 10) / retries * 1000;
context$1$0.next = 5;
return _regeneratorRuntime.awrap((0, _asyncbox.retry)(retries, function callee$1$0() {
return _regeneratorRuntime.async(function callee$1$0$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.prev = 0;
context$2$0.next = 3;
return _regeneratorRuntime.awrap(this.adbExec('wait-for-device', { timeout: timeout }));
case 3:
context$2$0.next = 5;
return _regeneratorRuntime.awrap(this.ping());
case 5:
context$2$0.next = 14;
break;
case 7:
context$2$0.prev = 7;
context$2$0.t0 = context$2$0['catch'](0);
context$2$0.next = 11;
return _regeneratorRuntime.awrap(this.restartAdb());
case 11:
context$2$0.next = 13;
return _regeneratorRuntime.awrap(this.getConnectedDevices());
case 13:
_loggerJs2['default'].errorAndThrow('Error in waiting for device. Original error: \'' + context$2$0.t0.message + '\'. ' + 'Retrying by restarting ADB');
case 14:
case 'end':
return context$2$0.stop();
}
}, null, _this3, [[0, 7]]);
}));
case 5:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.reboot = function callee$0$0() {
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
var _this4 = this;
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.next = 2;
return _regeneratorRuntime.awrap(this.shell(['stop']));
case 2:
context$1$0.next = 4;
return _regeneratorRuntime.awrap(_bluebird2['default'].delay(2000));
case 4:
context$1$0.next = 6;
return _regeneratorRuntime.awrap(this.setDeviceProperty('sys.boot_completed', 0));
case 6:
context$1$0.next = 8;
return _regeneratorRuntime.awrap(this.shell(['start']));
case 8:
context$1$0.next = 10;
return _regeneratorRuntime.awrap((0, _asyncbox.retryInterval)(90, 1000, function callee$1$0() {
var booted;
return _regeneratorRuntime.async(function callee$1$0$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return _regeneratorRuntime.awrap(this.getDeviceProperty('sys.boot_completed'));
case 2:
booted = context$2$0.sent;
if (!(booted === '1')) {
context$2$0.next = 7;
break;
}
return context$2$0.abrupt('return');
case 7:
_loggerJs2['default'].errorAndThrow('Waiting for reboot this takes time');
case 8:
case 'end':
return context$2$0.stop();
}
}, null, _this4);
}));
case 10:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.fileExists = function callee$0$0(remotePath) {
var files;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.next = 2;
return _regeneratorRuntime.awrap(this.ls(remotePath));
case 2:
files = context$1$0.sent;
return context$1$0.abrupt('return', files.length > 0);
case 4:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
systemCallMethods.ls = function callee$0$0(remotePath) {
var stdout, lines;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.prev = 0;
context$1$0.next = 3;
return _regeneratorRuntime.awrap(this.shell(['ls', remotePath]));
case 3:
stdout = context$1$0.sent;
lines = stdout.split("\n");
return context$1$0.abrupt('return', lines.map(function (l) {
return l.trim();
}).filter(Boolean).filter(function (l) {
return l.indexOf("No such file") === -1;
}));
case 8:
context$1$0.prev = 8;
context$1$0.t0 = context$1$0['catch'](0);
if (!(context$1$0.t0.message.indexOf('No such file or directory') === -1)) {
context$1$0.next = 12;
break;
}
throw context$1$0.t0;
case 12:
return context$1$0.abrupt('return', []);
case 13:
case 'end':
return context$1$0.stop();
}
}, null, this, [[0, 8]]);
};
exports['default'] = systemCallMethods;
module.exports = exports['default'];
// get subpaths for currently installed build tool directories
// expecting adb devices to return output as
// List of devices attached
// emulator-5554 device
// cool down
// cool down
// cool down
// do nothing
// let the emu finish stopping;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90b29scy9zeXN0ZW0tY2FsbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O29CQUFpQixNQUFNOzs7O3dCQUNQLGNBQWM7Ozs7d0JBQ2hCLFVBQVU7Ozs7NkJBQ0csZ0JBQWdCOzt1QkFDWixZQUFZOzs0QkFDVixjQUFjOzt3QkFDSCxVQUFVOztBQUd0RCxJQUFJLGlCQUFpQixHQUFHLEVBQUUsQ0FBQzs7QUFFM0IsSUFBTSx3QkFBd0IsR0FBRyxLQUFLLENBQUM7O0FBRXZDLGlCQUFpQixDQUFDLGdCQUFnQixHQUFHLG9CQUFnQixVQUFVOzs7O0FBQzdELDhCQUFJLElBQUksdUJBQXFCLFVBQVUsaUJBQWMsQ0FBQzs7YUFDbEQsSUFBSSxDQUFDLE9BQU87Ozs7OzRDQUNQLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUM7OztBQUU1Qyw4QkFBSSxJQUFJLENBQUMsMklBQ2tFLCtDQUN6QixVQUFVLE9BQUcsQ0FBQyxDQUFDOzt5Q0FDcEQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQzs7Ozs7Ozs7OztDQUdsRCxDQUFDOztBQUVGLGlCQUFpQixDQUFDLGVBQWUsR0FBRyxZQUFZO0FBQzlDLE1BQUksR0FBRyxHQUFHLE9BQU8sQ0FBQztBQUNsQixNQUFJLHNCQUFPLFNBQVMsRUFBRSxFQUFFO0FBQ3RCLE9BQUcsR0FBRyxPQUFPLENBQUM7R0FDZjtBQUNELFNBQU8sR0FBRyxDQUFDO0NBQ1osQ0FBQzs7QUFFRixpQkFBaUIsQ0FBQyxrQkFBa0IsR0FBRyxVQUFVLFVBQVUsRUFBRTtBQUMzRCxNQUFJLHNCQUFPLFNBQVMsRUFBRSxFQUFFO0FBQ3RCLFFBQUksVUFBVSxLQUFLLFNBQVMsRUFBRTtBQUM1QixnQkFBVSxJQUFJLE1BQU0sQ0FBQztLQUN0QixNQUFNO0FBQ0wsVUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMs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