appium-xcuitest-driver-conan
Version:
Appium driver for iOS using XCUITest for backend
1,404 lines (1,104 loc) • 138 kB
JavaScript
'use strict';
var _get = require('babel-runtime/helpers/get')['default'];
var _inherits = require('babel-runtime/helpers/inherits')['default'];
var _createClass = require('babel-runtime/helpers/create-class')['default'];
var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];
var _slicedToArray = require('babel-runtime/helpers/sliced-to-array')['default'];
var _getIterator = require('babel-runtime/core-js/get-iterator')['default'];
var _regeneratorRuntime = require('babel-runtime/regenerator')['default'];
var _Object$assign = require('babel-runtime/core-js/object/assign')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
Object.defineProperty(exports, '__esModule', {
value: true
});
var _appiumBaseDriver = require('appium-base-driver');
var _appiumSupport = require('appium-support');
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _nodeSimctl = require('node-simctl');
var _webdriveragent = require('./webdriveragent');
var _webdriveragent2 = _interopRequireDefault(_webdriveragent);
var _logger = require('./logger');
var _logger2 = _interopRequireDefault(_logger);
var _simulatorManagement = require('./simulator-management');
var _appiumIosSimulator = require('appium-ios-simulator');
var _asyncbox = require('asyncbox');
var _appiumIosDriver = require('appium-ios-driver');
var _desiredCaps = require('./desired-caps');
var _desiredCaps2 = _interopRequireDefault(_desiredCaps);
var _commandsIndex = require('./commands/index');
var _commandsIndex2 = _interopRequireDefault(_commandsIndex);
var _utils = require('./utils');
var _realDeviceManagement = require('./real-device-management');
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _packageJson = require('../../package.json');
// eslint-disable-line import/no-unresolved
var SAFARI_BUNDLE_ID = 'com.apple.mobilesafari';
var WDA_STARTUP_RETRIES = 2;
var DEFAULT_TIMEOUT_KEY = 'default';
var WDA_STARTUP_RETRY_INTERVAL = 10000;
var NO_PROXY_NATIVE_LIST = [['GET', /^\/session\/[^\/]+$/], ['GET', /context/], ['POST', /context/], ['GET', /window/], ['POST', /window/], ['DELETE', /window/], ['POST', /execute/], ['POST', /element$/], ['POST', /elements$/], ['POST', /timeouts/], ['GET', /alert_text/], ['POST', /alert_text/], ['POST', /accept_alert/], ['POST', /dismiss_alert/], ['GET', /source/], ['GET', /screenshot/], ['POST', /appium/], ['GET', /appium/], ['POST', /touch/], ['GET', /log/], ['POST', /log/], ['POST', /moveto/], ['POST', /receive_async_response/], // always, in case context switches while waiting
['GET', /location/], ['GET', /size/], ['POST', /value/], ['POST', /keys/], ['POST', /back/], ['POST', /session\/[^\/]+\/location/], // geo location, but not element location
['POST', /appium\/device\/lock/], ['POST', /shake/], ['POST', /clear/]];
var NO_PROXY_WEB_LIST = [['GET', /title/], ['GET', /url/], ['POST', /url/], ['POST', /element/], ['POST', /forward/], ['GET', /attribute/], ['GET', /text/], ['POST', /clear/], ['GET', /element/], ['POST', /click/], ['POST', /refresh/], ['GET', /cookie/], ['POST', /cookie/], ['DELETE', /cookie/], ['POST', /frame/], ['POST', /keys/]].concat(NO_PROXY_NATIVE_LIST);
function normalizeCommandTimeouts(value) {
// The value is normalized already
if (typeof value !== 'string') {
return value;
}
var result = {};
// Use as default timeout for all commands if a single integer value is provided
if (!isNaN(value)) {
result[DEFAULT_TIMEOUT_KEY] = _lodash2['default'].toInteger(value);
return result;
}
// JSON object has been provided. Let's parse it
try {
result = JSON.parse(value);
if (!_lodash2['default'].isPlainObject(result)) {
throw new Error();
}
} catch (err) {
_logger2['default'].errorAndThrow('"commandTimeouts" capability should be a valid JSON object. "' + value + '" was given instead');
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _getIterator(_lodash2['default'].toPairs(result)), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _step$value = _slicedToArray(_step.value, 2);
var cmd = _step$value[0];
var timeout = _step$value[1];
if (!_lodash2['default'].isInteger(timeout) || timeout <= 0) {
_logger2['default'].errorAndThrow('The timeout for "' + cmd + '" should be a valid natural number of milliseconds. "' + timeout + '" was given instead');
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result;
}
var XCUITestDriver = (function (_BaseDriver) {
_inherits(XCUITestDriver, _BaseDriver);
function XCUITestDriver() {
var opts = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var shouldValidateCaps = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
_classCallCheck(this, XCUITestDriver);
_get(Object.getPrototypeOf(XCUITestDriver.prototype), 'constructor', this).call(this, opts, shouldValidateCaps);
_logger2['default'].debug('XCUITestDriver version: ' + _packageJson.version);
this.desiredCapConstraints = _desiredCaps2['default'];
this.locatorStrategies = ['xpath', 'id', 'name', 'class name', '-ios predicate string', '-ios class chain', 'accessibility id'];
this.webLocatorStrategies = ['link text', 'css selector', 'tag name', 'link text', 'partial link text'];
this.resetIos();
}
_createClass(XCUITestDriver, [{
key: 'resetIos',
value: function resetIos() {
this.opts = this.opts || {};
this.wda = null;
this.opts.device = null;
this.jwpProxyActive = false;
this.proxyReqRes = null;
this.jwpProxyAvoid = [];
this.safari = false;
this.cachedWdaStatus = null;
// some things that commands imported from appium-ios-driver need
this.curWebFrames = [];
this.webElementIds = [];
this._currentUrl = null;
this.curContext = null;
this.xcodeVersion = null;
this.iosSdkVersion = null;
this.contexts = [];
this.implicitWaitMs = 0;
this.asynclibWaitMs = 0;
this.pageLoadMs = 6000;
}
}, {
key: 'getStatus',
value: function getStatus() {
var status;
return _regeneratorRuntime.async(function getStatus$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
if (!(typeof this.driverInfo === 'undefined')) {
context$2$0.next = 4;
break;
}
context$2$0.next = 3;
return _regeneratorRuntime.awrap((0, _utils.getDriverInfo)());
case 3:
this.driverInfo = context$2$0.sent;
case 4:
status = { build: { version: this.driverInfo.version } };
if (this.cachedWdaStatus) {
status.wda = this.cachedWdaStatus;
}
return context$2$0.abrupt('return', status);
case 7:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'createSession',
value: function createSession(caps) {
var _ref, _ref2, sessionId;
return _regeneratorRuntime.async(function createSession$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
this.lifecycleData = {}; // this is used for keeping track of the state we start so when we delete the session we can put things back
context$2$0.prev = 1;
context$2$0.next = 4;
return _regeneratorRuntime.awrap(_get(Object.getPrototypeOf(XCUITestDriver.prototype), 'createSession', this).call(this, caps));
case 4:
_ref = context$2$0.sent;
_ref2 = _slicedToArray(_ref, 1);
sessionId = _ref2[0];
this.opts.sessionId = sessionId;
context$2$0.next = 10;
return _regeneratorRuntime.awrap(this.start());
case 10:
// merge server capabilities + desired capabilities
caps = _Object$assign({}, _appiumIosDriver.defaultServerCaps, caps);
// update the udid with what is actually used
caps.udid = this.opts.udid;
return context$2$0.abrupt('return', [sessionId, caps]);
case 15:
context$2$0.prev = 15;
context$2$0.t0 = context$2$0['catch'](1);
_logger2['default'].error(context$2$0.t0);
context$2$0.next = 20;
return _regeneratorRuntime.awrap(this.deleteSession());
case 20:
throw context$2$0.t0;
case 21:
case 'end':
return context$2$0.stop();
}
}, null, this, [[1, 15]]);
}
}, {
key: 'start',
value: function start() {
var tools, _ref3, device, udid, realDevice, installAppPromise;
return _regeneratorRuntime.async(function start$(context$2$0) {
var _this2 = this;
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
this.opts.noReset = !!this.opts.noReset;
this.opts.fullReset = !!this.opts.fullReset;
if (this.xcodeVersion) {
context$2$0.next = 8;
break;
}
context$2$0.next = 5;
return _regeneratorRuntime.awrap((0, _utils.getAndCheckXcodeVersion)());
case 5:
this.xcodeVersion = context$2$0.sent;
tools = !this.xcodeVersion.toolsVersion ? '' : '(tools v' + this.xcodeVersion.toolsVersion + ')';
_logger2['default'].debug('Xcode version set to \'' + this.xcodeVersion.versionString + '\' ' + tools);
case 8:
context$2$0.next = 10;
return _regeneratorRuntime.awrap((0, _utils.getAndCheckIosSdkVersion)());
case 10:
this.iosSdkVersion = context$2$0.sent;
_logger2['default'].debug('iOS SDK Version set to \'' + this.iosSdkVersion + '\'');
if (!(this.opts.platformVersion && parseFloat(this.opts.platformVersion) < 9.0)) {
context$2$0.next = 14;
break;
}
throw Error('Platform version must be 9.0 or above. \'' + this.opts.platformVersion + '\' is not supported.');
case 14:
this.logEvent('xcodeDetailsRetrieved');
context$2$0.next = 17;
return _regeneratorRuntime.awrap(this.determineDevice());
case 17:
_ref3 = context$2$0.sent;
device = _ref3.device;
udid = _ref3.udid;
realDevice = _ref3.realDevice;
_logger2['default'].info('Determining device to run tests on: udid: \'' + udid + '\', real device: ' + realDevice);
this.opts.device = device;
this.opts.udid = udid;
this.opts.realDevice = realDevice;
if (!(this.isSimulator() && this.opts.customSSLCert)) {
context$2$0.next = 29;
break;
}
context$2$0.next = 28;
return _regeneratorRuntime.awrap((0, _appiumIosSimulator.installSSLCert)(this.opts.customSSLCert, this.opts.udid));
case 28:
this.logEvent('customCertInstalled');
case 29:
if (this.opts.platformVersion) {
context$2$0.next = 37;
break;
}
if (!(this.opts.device && _lodash2['default'].isFunction(this.opts.device.getPlatformVersion))) {
context$2$0.next = 37;
break;
}
context$2$0.next = 33;
return _regeneratorRuntime.awrap(this.opts.device.getPlatformVersion());
case 33:
this.opts.platformVersion = context$2$0.sent;
_logger2['default'].info('No platformVersion specified. Using device version: \'' + this.opts.platformVersion + '\'');
context$2$0.next = 37;
break;
case 37:
if (!((this.opts.browserName || '').toLowerCase() === 'safari')) {
context$2$0.next = 47;
break;
}
_logger2['default'].info('Safari test requested');
this.safari = true;
this.opts.app = undefined;
this.opts.processArguments = this.opts.processArguments || {};
this.opts.bundleId = SAFARI_BUNDLE_ID;
this._currentUrl = this.opts.safariInitialUrl || (this.isRealDevice() ? 'http://appium.io' : 'http://' + this.opts.address + ':' + this.opts.port + '/welcome');
this.opts.processArguments.args = ['-u', this._currentUrl];
context$2$0.next = 49;
break;
case 47:
context$2$0.next = 49;
return _regeneratorRuntime.awrap(this.configureApp());
case 49:
this.logEvent('appConfigured');
// fail very early if the app doesn't actually exist
// or if bundle id doesn't point to an installed app
if (!this.opts.app) {
context$2$0.next = 55;
break;
}
context$2$0.next = 53;
return _regeneratorRuntime.awrap((0, _utils.checkAppPresent)(this.opts.app));
case 53:
context$2$0.next = 60;
break;
case 55:
if (!(this.opts.bundleId && !this.safari)) {
context$2$0.next = 60;
break;
}
context$2$0.next = 58;
return _regeneratorRuntime.awrap(this.opts.device.isAppInstalled(this.opts.bundleId));
case 58:
if (context$2$0.sent) {
context$2$0.next = 60;
break;
}
_logger2['default'].errorAndThrow('App with bundle identifier \'' + this.opts.bundleId + '\' unknown');
case 60:
if (this.opts.bundleId) {
context$2$0.next = 64;
break;
}
context$2$0.next = 63;
return _regeneratorRuntime.awrap(this.extractBundleId(this.opts.app));
case 63:
this.opts.bundleId = context$2$0.sent;
case 64:
if (!this.opts.realDevice) {
if (typeof this.opts.scaleFactor !== 'undefined') {
_logger2['default'].info('Setting non-default Simulator scale factor to \'' + this.opts.scaleFactor + '\'');
device.setScaleFactor(this.opts.scaleFactor);
}
if (typeof this.opts.connectHardwareKeyboard !== 'undefined') {
_logger2['default'].info('Setting \'connectHardwareKeyboard\' Simulator option to \'' + (this.opts.connectHardwareKeyboard ? 'on' : 'off') + '\'');
device.setConnectHardwareKeyboard(this.opts.connectHardwareKeyboard);
}
}
context$2$0.next = 67;
return _regeneratorRuntime.awrap(this.runReset());
case 67:
context$2$0.next = 69;
return _regeneratorRuntime.awrap(this.startLogCapture());
case 69:
this.logEvent('logCaptureStarted');
_logger2['default'].info('Setting up ' + (this.isRealDevice() ? 'real device' : 'simulator'));
if (!this.isRealDevice()) {
context$2$0.next = 78;
break;
}
if (!this.opts.app) {
context$2$0.next = 76;
break;
}
context$2$0.next = 75;
return _regeneratorRuntime.awrap(this.installApp());
case 75:
this.logEvent('appInstalled');
case 76:
context$2$0.next = 98;
break;
case 78:
context$2$0.next = 80;
return _regeneratorRuntime.awrap(_appiumIosDriver.settings.setLocale(this.opts.device, this.opts, {}, this.isSafari()));
case 80:
this.localeConfig = context$2$0.sent;
context$2$0.next = 83;
return _regeneratorRuntime.awrap(_appiumIosDriver.settings.setPreferences(this.opts.device, this.opts, this.isSafari()));
case 83:
installAppPromise = null;
if (!this.opts.app) {
context$2$0.next = 92;
break;
}
context$2$0.next = 87;
return _regeneratorRuntime.awrap((0, _simulatorManagement.simBooted)(this.opts.device));
case 87:
if (!context$2$0.sent) {
context$2$0.next = 91;
break;
}
installAppPromise = this.installApp();
context$2$0.next = 92;
break;
case 91:
installAppPromise = new _bluebird2['default'](function callee$2$0(resolve, reject) {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
var _this = this;
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
this.opts.device.on(_appiumIosSimulator.BOOT_COMPLETED_EVENT, function callee$3$0() {
return _regeneratorRuntime.async(function callee$3$0$(context$4$0) {
while (1) switch (context$4$0.prev = context$4$0.next) {
case 0:
context$4$0.prev = 0;
context$4$0.next = 3;
return _regeneratorRuntime.awrap(this.installApp());
case 3:
resolve();
context$4$0.next = 9;
break;
case 6:
context$4$0.prev = 6;
context$4$0.t0 = context$4$0['catch'](0);
reject(context$4$0.t0);
case 9:
case 'end':
return context$4$0.stop();
}
}, null, _this, [[0, 6]]);
});
case 1:
case 'end':
return context$3$0.stop();
}
}, null, _this2);
});
case 92:
context$2$0.next = 94;
return _regeneratorRuntime.awrap(this.startSim());
case 94:
this.logEvent('simStarted');
context$2$0.next = 97;
return _regeneratorRuntime.awrap(installAppPromise);
case 97:
this.logEvent('appInstalled');
case 98:
context$2$0.next = 100;
return _regeneratorRuntime.awrap(this.startWda(this.opts.sessionId, realDevice));
case 100:
context$2$0.next = 102;
return _regeneratorRuntime.awrap(this.setInitialOrientation(this.opts.orientation));
case 102:
this.logEvent('orientationSet');
if (!(this.isRealDevice() && this.opts.startIWDP)) {
context$2$0.next = 113;
break;
}
context$2$0.prev = 104;
context$2$0.next = 107;
return _regeneratorRuntime.awrap(this.startIWDP());
case 107:
_logger2['default'].debug('Started ios_webkit_debug proxy server at: ' + this.iwdpServer.endpoint);
context$2$0.next = 113;
break;
case 110:
context$2$0.prev = 110;
context$2$0.t0 = context$2$0['catch'](104);
_logger2['default'].errorAndThrow('Could not start ios_webkit_debug_proxy server: ' + context$2$0.t0.message);
case 113:
if (!(this.isSafari() || this.opts.autoWebview)) {
context$2$0.next = 118;
break;
}
_logger2['default'].debug('Waiting for initial webview');
context$2$0.next = 117;
return _regeneratorRuntime.awrap(this.navToInitialWebview());
case 117:
this.logEvent('initialWebviewNavigated');
case 118:
if (this.isRealDevice()) {
context$2$0.next = 127;
break;
}
if (!this.opts.calendarAccessAuthorized) {
context$2$0.next = 124;
break;
}
context$2$0.next = 122;
return _regeneratorRuntime.awrap(this.opts.device.enableCalendarAccess(this.opts.bundleId));
case 122:
context$2$0.next = 127;
break;
case 124:
if (!(this.opts.calendarAccessAuthorized === false)) {
context$2$0.next = 127;
break;
}
context$2$0.next = 127;
return _regeneratorRuntime.awrap(this.opts.device.disableCalendarAccess(this.opts.bundleId));
case 127:
case 'end':
return context$2$0.stop();
}
}, null, this, [[104, 110]]);
}
}, {
key: 'startWda',
value: function startWda(sessionId, realDevice) {
var startupRetries, startupRetryInterval;
return _regeneratorRuntime.async(function startWda$(context$2$0) {
var _this4 = this;
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
startupRetries = this.opts.wdaStartupRetries || WDA_STARTUP_RETRIES;
startupRetryInterval = this.opts.wdaStartupRetryInterval || WDA_STARTUP_RETRY_INTERVAL;
context$2$0.next = 4;
return _regeneratorRuntime.awrap((0, _asyncbox.retryInterval)(startupRetries, startupRetryInterval, function callee$2$0() {
var quitAndUninstall, wdaStatus;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
var _this3 = this;
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
this.logEvent('wdaStartAttempted');
this.wda = new _webdriveragent2['default'](this.xcodeVersion, this.opts);
if (!this.opts.useNewWDA) {
context$3$0.next = 7;
break;
}
_logger2['default'].debug('Capability \'useNewWDA\' set, so uninstalling WDA before proceeding');
context$3$0.next = 6;
return _regeneratorRuntime.awrap(this.wda.uninstall());
case 6:
this.logEvent('wdaUninstalled');
case 7:
quitAndUninstall = function quitAndUninstall(msg) {
return _regeneratorRuntime.async(function quitAndUninstall$(context$4$0) {
while (1) switch (context$4$0.prev = context$4$0.next) {
case 0:
_logger2['default'].debug(msg);
_logger2['default'].debug('Quitting and uninstalling WebDriverAgent, then retrying');
context$4$0.next = 4;
return _regeneratorRuntime.awrap(this.wda.quit());
case 4:
context$4$0.next = 6;
return _regeneratorRuntime.awrap(this.wda.uninstall());
case 6:
throw new Error(msg);
case 7:
case 'end':
return context$4$0.stop();
}
}, null, _this3);
};
wdaStatus = null;
context$3$0.prev = 9;
context$3$0.next = 12;
return _regeneratorRuntime.awrap(this.wda.launch(sessionId, realDevice));
case 12:
wdaStatus = context$3$0.sent;
context$3$0.next = 20;
break;
case 15:
context$3$0.prev = 15;
context$3$0.t0 = context$3$0['catch'](9);
this.logEvent('wdaStartFailed');
context$3$0.next = 20;
return _regeneratorRuntime.awrap(quitAndUninstall('Unable to launch WebDriverAgent because of xcodebuild failure: ' + context$3$0.t0.message));
case 20:
this.proxyReqRes = this.wda.proxyReqRes.bind(this.wda);
this.jwpProxyActive = true;
context$3$0.prev = 22;
context$3$0.next = 25;
return _regeneratorRuntime.awrap((0, _asyncbox.retryInterval)(15, 1000, function callee$3$0() {
return _regeneratorRuntime.async(function callee$3$0$(context$4$0) {
while (1) switch (context$4$0.prev = context$4$0.next) {
case 0:
this.logEvent('wdaSessionAttempted');
_logger2['default'].debug('Sending createSession command to WDA');
context$4$0.prev = 2;
if (!wdaStatus) {
context$4$0.next = 7;
break;
}
this.cachedWdaStatus = wdaStatus;
context$4$0.next = 9;
break;
case 7:
context$4$0.next = 9;
return _regeneratorRuntime.awrap(this.proxyCommand('/status', 'GET'));
case 9:
context$4$0.next = 11;
return _regeneratorRuntime.awrap(this.startWdaSession(this.opts.bundleId, this.opts.processArguments));
case 11:
context$4$0.next = 17;
break;
case 13:
context$4$0.prev = 13;
context$4$0.t0 = context$4$0['catch'](2);
_logger2['default'].debug('Failed to create WDA session. Retrying...');
throw context$4$0.t0;
case 17:
case 'end':
return context$4$0.stop();
}
}, null, _this3, [[2, 13]]);
}));
case 25:
this.logEvent('wdaSessionStarted');
context$3$0.next = 33;
break;
case 28:
context$3$0.prev = 28;
context$3$0.t1 = context$3$0['catch'](22);
context$3$0.next = 32;
return _regeneratorRuntime.awrap(quitAndUninstall('Unable to start WebDriverAgent session: ' + context$3$0.t1.message));
case 32:
return context$3$0.abrupt('return', context$3$0.sent);
case 33:
this.opts.preventWDAAttachments = !_appiumSupport.util.hasValue(this.opts.preventWDAAttachments) || this.opts.preventWDAAttachments;
context$3$0.next = 36;
return _regeneratorRuntime.awrap((0, _utils.adjustWDAAttachmentsPermissions)(this.opts.preventWDAAttachments ? '555' : '755'));
case 36:
this.logEvent('wdaPermsAdjusted');
// we expect certain socket errors until this point, but now
// mark things as fully working
this.wda.fullyStarted = true;
this.logEvent('wdaStarted');
case 39:
case 'end':
return context$3$0.stop();
}
}, null, _this4, [[9, 15], [22, 28]]);
}));
case 4:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
// create an alias so we can actually unit test createSession by stubbing
// this
}, {
key: 'extractBundleId',
value: function extractBundleId(app) {
return _regeneratorRuntime.async(function extractBundleId$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return _regeneratorRuntime.awrap(_appiumIosDriver.appUtils.extractBundleId(app));
case 2:
return context$2$0.abrupt('return', context$2$0.sent);
case 3:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'runReset',
value: function runReset() {
var opts = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
return _regeneratorRuntime.async(function runReset$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
this.logEvent('resetStarted');
if (!this.isRealDevice()) {
context$2$0.next = 6;
break;
}
context$2$0.next = 4;
return _regeneratorRuntime.awrap((0, _realDeviceManagement.runRealDeviceReset)(this.opts.device, opts || this.opts));
case 4:
context$2$0.next = 8;
break;
case 6:
context$2$0.next = 8;
return _regeneratorRuntime.awrap((0, _simulatorManagement.runSimulatorReset)(this.opts.device, opts || this.opts));
case 8:
this.logEvent('resetComplete');
case 9:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'deleteSession',
value: function deleteSession() {
return _regeneratorRuntime.async(function deleteSession$(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.stop());
case 2:
if (!this.opts.preventWDAAttachments) {
context$2$0.next = 5;
break;
}
context$2$0.next = 5;
return _regeneratorRuntime.awrap((0, _utils.adjustWDAAttachmentsPermissions)('755'));
case 5:
if (!this.opts.clearSystemFiles) {
context$2$0.next = 10;
break;
}
context$2$0.next = 8;
return _regeneratorRuntime.awrap((0, _utils.clearSystemFiles)(this.wda, !!this.opts.showXcodeLog));
case 8:
context$2$0.next = 11;
break;
case 10:
_logger2['default'].debug('Not clearing log files. Use `clearSystemFiles` capability to turn on.');
case 11:
if (!this.isWebContext()) {
context$2$0.next = 15;
break;
}
_logger2['default'].debug('In a web session. Removing remote debugger');
context$2$0.next = 15;
return _regeneratorRuntime.awrap(this.stopRemote());
case 15:
if (!(this.opts.resetOnSessionStartOnly === false)) {
context$2$0.next = 18;
break;
}
context$2$0.next = 18;
return _regeneratorRuntime.awrap(this.runReset());
case 18:
if (!(this.isSimulator() && this.opts.udid && this.opts.customSSLCert)) {
context$2$0.next = 21;
break;
}
context$2$0.next = 21;
return _regeneratorRuntime.awrap((0, _appiumIosSimulator.uninstallSSLCert)(this.opts.customSSLCert, this.opts.udid));
case 21:
if (!(this.isSimulator() && !this.opts.noReset && !!this.opts.device)) {
context$2$0.next = 28;
break;
}
if (!this.lifecycleData.createSim) {
context$2$0.next = 28;
break;
}
_logger2['default'].debug('Deleting simulator created for this run');
context$2$0.next = 26;
return _regeneratorRuntime.awrap(this.opts.device.shutdown());
case 26:
context$2$0.next = 28;
return _regeneratorRuntime.awrap(this.opts.device['delete']());
case 28:
if (!_lodash2['default'].isEmpty(this.logs)) {
this.logs.syslog.stopCapture();
this.logs = {};
}
if (this.iwdpServer) {
this.stopIWDP();
}
this.resetIos();
context$2$0.next = 33;
return _regeneratorRuntime.awrap(_get(Object.getPrototypeOf(XCUITestDriver.prototype), 'deleteSession', this).call(this));
case 33:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'stop',
value: function stop() {
return _regeneratorRuntime.async(function stop$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
this.jwpProxyActive = false;
this.proxyReqRes = null;
if (!(this.wda && this.wda.fullyStarted)) {
context$2$0.next = 14;
break;
}
if (!this.wda.jwproxy) {
context$2$0.next = 12;
break;
}
context$2$0.prev = 4;
context$2$0.next = 7;
return _regeneratorRuntime.awrap(this.proxyCommand('/session/' + this.sessionId, 'DELETE'));
case 7:
context$2$0.next = 12;
break;
case 9:
context$2$0.prev = 9;
context$2$0.t0 = context$2$0['catch'](4);
// an error here should not short-circuit the rest of clean up
_logger2['default'].debug('Unable to DELETE session on WDA: \'' + context$2$0.t0.message + '\'. Continuing shutdown.');
case 12:
context$2$0.next = 14;
return _regeneratorRuntime.awrap(this.wda.quit());
case 14:
case 'end':
return context$2$0.stop();
}
}, null, this, [[4, 9]]);
}
}, {
key: 'executeCommand',
value: function executeCommand(cmd) {
var _get2;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return _regeneratorRuntime.async(function executeCommand$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
_logger2['default'].debug('Executing command \'' + cmd + '\'');
if (!(cmd === 'receiveAsyncResponse')) {
context$2$0.next = 5;
break;
}
context$2$0.next = 4;
return _regeneratorRuntime.awrap(this.receiveAsyncResponse.apply(this, args));
case 4:
return context$2$0.abrupt('return', context$2$0.sent);
case 5:
if (!(cmd === 'getStatus')) {
context$2$0.next = 9;
break;
}
context$2$0.next = 8;
return _regeneratorRuntime.awrap(this.getStatus());
case 8:
return context$2$0.abrupt('return', context$2$0.sent);
case 9:
context$2$0.next = 11;
return _regeneratorRuntime.awrap((_get2 = _get(Object.getPrototypeOf(XCUITestDriver.prototype), 'executeCommand', this)).call.apply(_get2, [this, cmd].concat(args)));
case 11:
return context$2$0.abrupt('return', context$2$0.sent);
case 12:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'configureApp',
value: function configureApp() {
var appIsPackageOrBundle;
return _regeneratorRuntime.async(function configureApp$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
appIsPackageOrBundle = function appIsPackageOrBundle(app) {
return (/^([a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+)+$/.test(app)
);
};
// the app name is a bundleId assign it to the bundleId property
if (!this.opts.bundleId && appIsPackageOrBundle(this.opts.app)) {
this.opts.bundleId = this.opts.app;
this.opts.app = '';
}
// we have a bundle ID, but no app, or app is also a bundle
if (!(this.opts.bundleId && appIsPackageOrBundle(this.opts.bundleId) && (this.opts.app === '' || appIsPackageOrBundle(this.opts.app)))) {
context$2$0.next = 5;
break;
}
_logger2['default'].debug('App is an iOS bundle, will attempt to run as pre-existing');
return context$2$0.abrupt('return');
case 5:
if (!(this.opts.app && this.opts.app.toLowerCase() === 'settings')) {
context$2$0.next = 11;
break;
}
this.opts.bundleId = 'com.apple.Preferences';
this.opts.app = null;
return context$2$0.abrupt('return');
case 11:
if (!(this.opts.app && this.opts.app.toLowerCase() === 'calendar')) {
context$2$0.next = 15;
break;
}
this.opts.bundleId = 'com.apple.mobilecal';
this.opts.app = null;
return context$2$0.abrupt('return');
case 15:
context$2$0.prev = 15;
context$2$0.next = 18;
return _regeneratorRuntime.awrap(this.helpers.configureApp(this.opts.app, '.app', this.opts.mountRoot, this.opts.windowsShareUserName, this.opts.windowsSharePassword));
case 18:
this.opts.app = context$2$0.sent;
context$2$0.next = 25;
break;
case 21:
context$2$0.prev = 21;
context$2$0.t0 = context$2$0['catch'](15);
_logger2['default'].error(context$2$0.t0);
throw new Error('Bad app: ' + this.opts.app + '. App paths need to be absolute, or relative to the appium ' + 'server install dir, or a URL to compressed file, or a special app name.');
case 25:
case 'end':
return context$2$0.stop();
}
}, null, this, [[15, 21]]);
}
}, {
key: 'determineDevice',
value: function determineDevice() {
var _device, devices, _device2, device;
return _regeneratorRuntime.async(function determineDevice$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
// in the one case where we create a sim, we will set this state
this.lifecycleData.createSim = false;
// if we get generic names, translate them
this.opts.deviceName = (function translateDeviceName() {
var dn = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];
var deviceName = dn;
if (dn.toLowerCase() === 'iphone simulator') {
deviceName = 'iPhone 6';
} else if (dn.toLowerCase() === 'ipad simulator') {
deviceName = 'iPad Retina';
}
if (deviceName !== dn) {
_logger2['default'].debug('Changing deviceName from \'' + dn + '\' to \'' + deviceName + '\'');
}
return deviceName;
})(this.opts.deviceName);
// check for a particular simulator
context$2$0.t0 = this.opts.udid;
if (!context$2$0.t0) {
context$2$0.next = 7;
break;
}
context$2$0.next = 6;
return _regeneratorRuntime.awrap((0, _appiumIosSimulator.simExists)(this.opts.udid));
case 6:
context$2$0.t0 = context$2$0.sent;
case 7:
if (!context$2$0.t0) {
context$2$0.next = 12;
break;
}
context$2$0.next = 10;
return _regeneratorRuntime.awrap((0, _appiumIosSimulator.getSimulator)(this.opts.udid));
case 10:
_device = context$2$0.sent;
return context$2$0.abrupt('return', { device: _device, realDevice: false, udid: this.opts.udid });
case 12:
if (!this.opts.udid) {
context$2$0.next = 29;
break;
}
if (!(this.opts.udid.toLowerCase() === 'auto')) {
context$2$0.next = 19;
break;
}
context$2$0.next = 16;
return _regeneratorRuntime.awrap((0, _utils.detectUdid)());
case 16:
this.opts.udid = context$2$0.sent;
context$2$0.next = 25;
break;
case 19:
context$2$0.next = 21;
return _regeneratorRuntime.awrap((0, _realDeviceManagement.getConnectedDevices)());
case 21:
devices = context$2$0.sent;
_logger2['default'].debug('Available devices: ' + devices.join(', '));
if (!(devices.indexOf(this.opts.udid) === -1)) {
context$2$0.next = 25;
break;
}
throw new Error('Unknown device or simulator UDID: \'' + this.opts.udid + '\'');
case 25:
context$2$0.next = 27;
return _regeneratorRuntime.awrap((0, _realDeviceManagement.getRealDeviceObj)(this.opts.udid));
case 27:
_device2 = context$2$0.sent;
return context$2$0.abrupt('return', { device: _device2, realDevice: true, udid: this.opts.udid });
case 29:
context$2$0.next = 31;
return _regeneratorRuntime.awrap((0, _simulatorManagement.getExistingSim)(this.opts.deviceName, this.opts.platformVersion));
case 31:
device = context$2$0.sent;
if (!device) {
context$2$0.next = 34;
break;
}
return context$2$0.abrupt('return', { device: device, realDevice: false, udid: device.udid });
case 34:
// no device of this type exists, so create one
_logger2['default'].info('Simulator udid not provided, using desired caps to create a new simulator');
if (!this.opts.platformVersion) {
_logger2['default'].info('No platformVersion specified. Using latest version Xcode supports: \'' + this.iosSdkVersion + '\' ' + 'This may cause problems if a simulator does not exist for this platform version.');
this.opts.platformVersion = this.iosSdkVersion;
}
context$2$0.next = 38;
return _regeneratorRuntime.awrap(this.createSim());
case 38:
device = context$2$0.sent;
return context$2$0.abrupt('return', { device: device, realDevice: false, udid: device.udid });
case 40:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'startSim',
value: function startSim() {
return _regeneratorRuntime.async(function startSim$(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, _simulatorManagement.simBooted)(this.opts.device));
case 2:
if (!context$2$0.sent) {
context$2$0.next = 5;
break;
}
_logger2['default'].info('Simulator with udid \'' + this.opts.udid + '\' already booted');
return context$2$0.abrupt('return');
case 5:
_logger2['default'].info('Simulator with udid \'' + this.opts.udid + '\' not booted. Booting up now');
context$2$0.next = 8;
return _regeneratorRuntime.awrap((0, _appiumIosSimulator.killAllSimulators)());
case 8:
context$2$0.next = 10;
return _regeneratorRuntime.awrap(this.opts.device.run(undefined, this.opts.allowTouchIdEnroll));
case 10:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'createSim',
value: function createSim() {
var sim;
return _regeneratorRuntime.async(function createSim$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
this.lifecycleData.createSim = true;
// create sim for caps
context$2$0.next = 3;
return _regeneratorRuntime.awrap((0, _simulatorManagement.createSim)(this.opts, this.sessionId));
case 3:
sim = context$2$0.sent;
_logger2['default'].info('Created simulator with udid \'' + sim.udid + '\'.');
return context$2$0.abrupt('return', sim);
case 6:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'launchApp',
value: function launchApp() {
var APP_LAUNCH_TIMEOUT, checkStatus, retries;
return _regeneratorRuntime.async(function launchApp$(context$2$0) {
var _this5 = this;
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
APP_LAUNCH_TIMEOUT = 20 * 1000;
this.logEvent('appLaunchAttempted');
context$2$0.next = 4;
return _regeneratorRuntime.awrap((0, _nodeSimctl.launch)(this.opts.device.udid, this.opts.bundleId));
case 4:
checkStatus = function checkStatus() {
var response, currentApp;
return _regeneratorRuntime.async(function checkStatus$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
context$3$0.next = 2;
return _regeneratorRuntime.awrap(this.proxyCommand('/status', 'GET'));
case 2:
response = context$3$0.sent;
currentApp = response.currentApp.bundleID;
if (!(currentApp !== this.opts.bundleId)) {
context$3$0.next = 6;
break;
}
throw new Error(this.opts.bundleId + ' not in foreground. ' + currentApp + ' is in foreground');
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this5);
};
_logger2['default'].info('Waiting for \'' + this.opts.bundleId + '\' to be in foreground');
retries = parseInt(APP_LAUNCH_TIMEOUT / 200, 10);
context$2$0.next = 9;
return _regeneratorRuntime.awrap((0, _asyncbox.retryInterval)(retries, 200, checkStatus));
case 9:
_logger2['default'].info(this.opts.bundleId + ' is in foreground');
this.logEvent('appLaunched');
case 11:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'startWdaSession',
value: function startWdaSession(bundleId, processArguments) {
var args, env, shouldWaitForQuiescence, maxTypingFrequency, shouldUseSingletonTestManager, shouldUseTestManagerForVisibilityDetection, desired;
return _regeneratorRuntime.async(function startWdaSession$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
args = processArguments ? processArguments.args : [];
env = processArguments ? processArguments.env : {};
shouldWaitForQuiescence = _appiumSupport.util.hasValue(this.opts.waitForQuiescence) ? this.opts.waitForQuiescence : true;
maxTypingFrequency = _appiumSupport.util.hasValue(this.opts.maxTypingFrequency) ? this.opts.maxTypingFrequency : 60;
shouldUseSingletonTestManager = _appiumSupport.util.hasValue(this.opts.shouldUseSingletonTestManager) ? this.opts.shouldUseSingletonTestManager : true;
shouldUseTestManagerForVisibilityDetection = false;
if (_appiumSupport.util.hasValue(this.opts.simpleIsVisibleCheck)) {
shouldUseTestManagerForVisibilityDetection = this.opts.simpleIsVisibleCheck;
}
if ((this.opts.platformVersion || '').indexOf('9') === 0) {
shouldUseTestManagerForVisibilityDetection = true;
}
desired = {
desiredCapabilities: {
bundleId: bundleId,
arguments: args,
environment: env,
shouldWaitForQuiescence: shouldWaitForQuiescence,
shouldUseTestManagerForVisibilityDetection: shouldUseTestManagerForVisibilityDetection,
maxTypingFrequency: maxTypingFrequency,
shouldUseSingletonTestManager: shouldUseSingletonTestManager
}
};
context$2$0.next = 11;
return _regeneratorRuntime.awrap(this.proxyCommand('/session', 'POST', desired));
case 11:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
// Override Proxy methods