UNPKG

appium-ios-simulator

Version:
284 lines (219 loc) 16.6 kB
'use strict'; var _regeneratorRuntime = require('babel-runtime/regenerator')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _logger = require('./logger'); var _logger2 = _interopRequireDefault(_logger); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _teen_process = require('teen_process'); var _asyncbox = require('asyncbox'); var _appiumXcode = require('appium-xcode'); var _nodeSimctl = require('node-simctl'); var _appiumSupport = require('appium-support'); function killAllSimulators() { var appName, xcodeVersion, allSimsAreShutDown; return _regeneratorRuntime.async(function killAllSimulators$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: allSimsAreShutDown = function allSimsAreShutDown() { var devices; return _regeneratorRuntime.async(function allSimsAreShutDown$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: context$2$0.next = 2; return _regeneratorRuntime.awrap((0, _nodeSimctl.getDevices)()); case 2: devices = context$2$0.sent; devices = _lodash2['default'].flatten(_lodash2['default'].values(devices)); return context$2$0.abrupt('return', _lodash2['default'].every(devices, function (sim) { return sim.state === 'Shutdown'; })); case 5: case 'end': return context$2$0.stop(); } }, null, this); }; _logger2['default'].debug('Killing all iOS Simulators'); appName = undefined; context$1$0.next = 5; return _regeneratorRuntime.awrap((0, _appiumXcode.getVersion)(true)); case 5: xcodeVersion = context$1$0.sent; if (xcodeVersion.major === 7) { appName = 'Simulator'; } else { appName = 'iOS Simulator'; } context$1$0.prev = 7; context$1$0.next = 10; return _regeneratorRuntime.awrap((0, _teen_process.exec)('osascript', ['-e', 'quit app "' + appName + '"'])); case 10: context$1$0.next = 16; break; case 12: context$1$0.prev = 12; context$1$0.t0 = context$1$0['catch'](7); _logger2['default'].error(JSON.stringify(context$1$0.t0)); throw context$1$0.t0; case 16: context$1$0.next = 18; return _regeneratorRuntime.awrap((0, _asyncbox.waitForCondition)(allSimsAreShutDown, { waitMs: 60 * 1000, intervalMs: 200 })); case 18: case 'end': return context$1$0.stop(); } }, null, this, [[7, 12]]); } function endAllSimulatorDaemons() { var _arr, _i, servicePattern, launchCtlCommand, stopCmd, removeCmd; return _regeneratorRuntime.async(function endAllSimulatorDaemons$(context$1$0) { var _this = this; while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _logger2['default'].debug('Ending all simulator daemons'); _arr = ['com.apple.iphonesimulator', 'com.apple.CoreSimulator']; _i = 0; case 3: if (!(_i < _arr.length)) { context$1$0.next = 28; break; } servicePattern = _arr[_i]; _logger2['default'].debug('Killing any other ' + servicePattern + ' daemons'); launchCtlCommand = 'launchctl list | grep ' + servicePattern + ' | cut -f 3 | xargs -n 1 launchctl'; context$1$0.prev = 7; stopCmd = launchCtlCommand + ' stop'; context$1$0.next = 11; return _regeneratorRuntime.awrap((0, _teen_process.exec)('bash', ['-c', stopCmd])); case 11: context$1$0.next = 16; break; case 13: context$1$0.prev = 13; context$1$0.t0 = context$1$0['catch'](7); _logger2['default'].warn('Could not stop ' + servicePattern + ' daemons, carrying on anyway!'); case 16: context$1$0.prev = 16; removeCmd = launchCtlCommand + ' remove'; context$1$0.next = 20; return _regeneratorRuntime.awrap((0, _teen_process.exec)('bash', ['-c', removeCmd])); case 20: context$1$0.next = 25; break; case 22: context$1$0.prev = 22; context$1$0.t1 = context$1$0['catch'](16); _logger2['default'].warn('Could not remove ' + servicePattern + ' daemons, carrying on anyway!'); case 25: _i++; context$1$0.next = 3; break; case 28: context$1$0.prev = 28; context$1$0.next = 31; return _regeneratorRuntime.awrap((0, _asyncbox.waitForCondition)(function callee$1$0() { var _ref, stdout; 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((0, _teen_process.exec)('bash', ['-c', 'ps -e | grep launchd_sim | grep -v bash | grep -v grep | awk {\'print$1\'}'])); case 2: _ref = context$2$0.sent; stdout = _ref.stdout; return context$2$0.abrupt('return', stdout.trim().length === 0); case 5: case 'end': return context$2$0.stop(); } }, null, _this); }, { waitMs: 5000, intervalMs: 500 })); case 31: context$1$0.next = 36; break; case 33: context$1$0.prev = 33; context$1$0.t2 = context$1$0['catch'](28); _logger2['default'].warn('Could not end all simulator daemons, carrying on!'); case 36: _logger2['default'].debug('Finishing ending all simulator daemons'); case 37: case 'end': return context$1$0.stop(); } }, null, this, [[7, 13], [16, 22], [28, 33]]); } function simExists(udid) { var devices; return _regeneratorRuntime.async(function simExists$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap((0, _nodeSimctl.getDevices)()); case 2: devices = context$1$0.sent; devices = _lodash2['default'].pairs(devices).map(function (pair) { return pair[1]; }).reduce(function (a, b) { return a.concat(b); }, []); return context$1$0.abrupt('return', !!_lodash2['default'].find(devices, function (sim) { return sim.udid === udid; })); case 5: case 'end': return context$1$0.stop(); } }, null, this); } function safeRimRaf(delPath) { var tryNum = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; return _regeneratorRuntime.async(function safeRimRaf$(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(_appiumSupport.fs.rimraf(delPath)); case 3: context$1$0.next = 16; break; case 5: context$1$0.prev = 5; context$1$0.t0 = context$1$0['catch'](0); if (!(tryNum < 20)) { context$1$0.next = 16; break; } if (!(context$1$0.t0.message.indexOf('ENOTEMPTY') !== -1)) { context$1$0.next = 13; break; } _logger2['default'].debug('Path \'' + delPath + '\' was not empty during delete; retrying'); return context$1$0.abrupt('return', safeRimRaf(delPath, tryNum + 1)); case 13: if (!(context$1$0.t0.message.indexOf('ENOENT') !== -1)) { context$1$0.next = 16; break; } _logger2['default'].debug('Path \'' + delPath + '\'\' did not exist when we tried to delete, ignoring'); return context$1$0.abrupt('return', safeRimRaf(delPath, tryNum + 1)); case 16: case 'end': return context$1$0.stop(); } }, null, this, [[0, 5]]); } exports.killAllSimulators = killAllSimulators; exports.endAllSimulatorDaemons = endAllSimulatorDaemons; exports.safeRimRaf = safeRimRaf; exports.simExists = simExists; // waiting until the simulator service has died. // see the README for github.com/appium/node-simctl for example output of getDevices() //# sourceMappingURL=data:application/json;base64,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bG9nZ2VyJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCB7IHdhaXRGb3JDb25kaXRpb24gfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgeyBnZXRWZXJzaW9uIH0gZnJvbSAnYXBwaXVtLXhjb2RlJztcbmltcG9ydCB7IGdldERldmljZXMgfSBmcm9tICdub2RlLXNpbWN0bCc7XG5pbXBvcnQgeyBmcyB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcblxuXG5hc3luYyBmdW5jdGlvbiBraWxsQWxsU2ltdWxhdG9ycyAoKSB7XG4gIGxvZy5kZWJ1ZygnS2lsbGluZyBhbGwgaU9TIFNpbXVsYXRvcnMnKTtcblxuICBsZXQgYXBwTmFtZTtcbiAgbGV0IHhjb2RlVmVyc2lvbiA9IGF3YWl0IGdldFZlcnNpb24odHJ1ZSk7XG4gIGlmICh4Y29kZVZlcnNpb24ubWFqb3IgPT09IDcpIHtcbiAgICBhcHBOYW1lID0gJ1NpbXVsYXRvcic7XG4gIH0gZWxzZSB7XG4gICAgYXBwTmFtZSA9ICdpT1MgU2ltdWxhdG9yJztcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgZXhlYygnb3Nhc2NyaXB0JywgWyctZScsIGBxdWl0IGFwcCBcIiR7YXBwTmFtZX1cImBdKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZy5lcnJvcihKU09OLnN0cmluZ2lmeShlKSk7XG4gICAgdGhyb3cgZTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGFsbFNpbXNBcmVTaHV0RG93biAoKSB7XG4gICAgbGV0IGRldmljZXMgPSBhd2FpdCBnZXREZXZpY2VzKCk7XG4gICAgZGV2aWNlcyA9IF8uZmxhdHRlbihfLnZhbHVlcyhkZXZpY2VzKSk7XG4gICAgcmV0dXJuIF8uZXZlcnkoZGV2aWNlcywgKHNpbSkgPT4ge1xuICAgICAgcmV0dXJuIHNpbS5zdGF0ZSA9PT0gJ1NodXRkb3duJztcbiAgICB9KTtcbiAgfVxuXG4gIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYWxsU2ltc0FyZVNodXREb3duLCB7XG4gICAgd2FpdE1zOiA2MCAqIDEwMDAsXG4gICAgaW50ZXJ2YWxNczogMjAwXG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBlbmRBbGxTaW11bGF0b3JEYWVtb25zICgpIHtcbiAgbG9nLmRlYnVnKCdFbmRpbmcgYWxsIHNpbXVsYXRvciBkYWVtb25zJyk7XG4gIGZvciAobGV0IHNlcnZpY2VQYXR0ZXJuIG9mIFsnY29tLmFwcGxlLmlwaG9uZXNpbXVsYXRvcicsICdjb20uYXBwbGUuQ29yZVNpbXVsYXRvciddKSB7XG4gICAgbG9nLmRlYnVnKGBLaWxsaW5nIGFueSBvdGhlciAke3NlcnZpY2VQYXR0ZXJufSBkYWVtb25zYCk7XG4gICAgbGV0IGxhdW5jaEN0bENvbW1hbmQgPSBgbGF1bmNoY3RsIGxpc3QgfCBncmVwICR7c2VydmljZVBhdHRlcm59IHwgY3V0IC1mIDMgfCB4YXJncyAtbiAxIGxhdW5jaGN0bGA7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBzdG9wQ21kID0gYCR7bGF1bmNoQ3RsQ29tbWFuZH0gc3RvcGA7XG4gICAgICBhd2FpdCBleGVjKCdiYXNoJywgWyctYycsIHN0b3BDbWRdKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZy53YXJuKGBDb3VsZCBub3Qgc3RvcCAke3NlcnZpY2VQYXR0ZXJufSBkYWVtb25zLCBjYXJyeWluZyBvbiBhbnl3YXkhYCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBsZXQgcmVtb3ZlQ21kID0gYCR7bGF1bmNoQ3RsQ29tbWFuZH0gcmVtb3ZlYDtcbiAgICAgIGF3YWl0IGV4ZWMoJ2Jhc2gnLCBbJy1jJywgcmVtb3ZlQ21kXSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2cud2FybihgQ291bGQgbm90IHJlbW92ZSAke3NlcnZpY2VQYXR0ZXJufSBkYWVtb25zLCBjYXJyeWluZyBvbiBhbnl3YXkhYCk7XG4gICAgfVxuICB9XG4gIC8vIHdhaXRpbmcgdW50aWwgdGhlIHNpbXVsYXRvciBzZXJ2aWNlIGhhcyBkaWVkLlxuICB0cnkge1xuICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYygnYmFzaCcsIFsnLWMnLFxuICAgICAgICBgcHMgLWUgIHwgZ3JlcCBsYXVuY2hkX3NpbSB8IGdyZXAgLXYgYmFzaCB8IGdyZXAgLXYgZ3JlcCB8IGF3ayB7J3ByaW50JDEnfWBdKTtcbiAgICAgIHJldHVybiBzdGRvdXQudHJpbSgpLmxlbmd0aCA9PT0gMDtcbiAgICB9LCB7d2FpdE1zOiA1MDAwLCBpbnRlcnZhbE1zOiA1MDB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nLndhcm4oYENvdWxkIG5vdCBlbmQgYWxsIHNpbXVsYXRvciBkYWVtb25zLCBjYXJyeWluZyBvbiFgKTtcbiAgfVxuICBsb2cuZGVidWcoJ0ZpbmlzaGluZyBlbmRpbmcgYWxsIHNpbXVsYXRvciBkYWVtb25zJyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNpbUV4aXN0cyAodWRpZCkge1xuICAvLyBzZWUgdGhlIFJFQURNRSBmb3IgZ2l0aHViLmNvbS9hcHBpdW0vbm9kZS1zaW1jdGwgZm9yIGV4YW1wbGUgb3V0cHV0IG9mIGdldERldmljZXMoKVxuICBsZXQgZGV2aWNlcyA9IGF3YWl0IGdldERldmljZXMoKTtcblxuICBkZXZpY2VzID0gXy5wYWlycyhkZXZpY2VzKS5tYXAoKHBhaXIpID0+IHtcbiAgICByZXR1cm4gcGFpclsxXTtcbiAgfSkucmVkdWNlKChhLCBiKSA9PiB7XG4gICAgcmV0dXJuIGEuY29uY2F0KGIpO1xuICB9LCBbXSk7XG4gIHJldHVybiAhIV8uZmluZChkZXZpY2VzLCAoc2ltKSA9PiB7XG4gICAgcmV0dXJuIHNpbS51ZGlkID09PSB1ZGlkO1xuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2FmZVJpbVJhZiAoZGVsUGF0aCwgdHJ5TnVtID0gMCkge1xuICB0cnkge1xuICAgIGF3YWl0IGZzLnJpbXJhZihkZWxQYXRoKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKHRyeU51bSA8IDIwKSB7XG4gICAgICBpZiAoZXJyLm1lc3NhZ2UuaW5kZXhPZignRU5PVEVNUFRZJykgIT09IC0xKSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhgUGF0aCAnJHtkZWxQYXRofScgd2FzIG5vdCBlbXB0eSBkdXJpbmcgZGVsZXRlOyByZXRyeWluZ2ApO1xuICAgICAgICByZXR1cm4gc2FmZVJpbVJhZihkZWxQYXRoLCB0cnlOdW0gKyAxKTtcbiAgICAgIH0gZWxzZSBpZiAoZXJyLm1lc3NhZ2UuaW5kZXhPZignRU5PRU5UJykgIT09IC0xKSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhgUGF0aCAnJHtkZWxQYXRofScnIGRpZCBub3QgZXhpc3Qgd2hlbiB3ZSB0cmllZCB0byBkZWxldGUsIGlnbm9yaW5nYCk7XG4gICAgICAgIHJldHVybiBzYWZlUmltUmFmKGRlbFBhdGgsIHRyeU51bSArIDEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgeyBraWxsQWxsU2ltdWxhdG9ycywgZW5kQWxsU2ltdWxhdG9yRGFlbW9ucywgc2FmZVJpbVJhZiwgc2ltRXhpc3RzIH07XG4iXX0=