appium-xcuitest-driver-conan
Version:
Appium driver for iOS using XCUITest for backend
227 lines (174 loc) • 16.1 kB
JavaScript
;
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 _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _appiumBaseDriver = require('appium-base-driver');
var _appiumSupport = require('appium-support');
var _logger = require('../logger');
var _logger2 = _interopRequireDefault(_logger);
var helpers = {},
commands = {},
extensions = {};
helpers.findElOrEls = function callee$0$0(strategy, selector, mult, context) {
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.isWebview()) {
context$1$0.next = 6;
break;
}
context$1$0.next = 3;
return _regeneratorRuntime.awrap(this.findWebElementOrElements(strategy, selector, mult, context));
case 3:
return context$1$0.abrupt('return', context$1$0.sent);
case 6:
context$1$0.next = 8;
return _regeneratorRuntime.awrap(this.findNativeElementOrElements(strategy, selector, mult, context));
case 8:
return context$1$0.abrupt('return', context$1$0.sent);
case 9:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
helpers.findNativeElementOrElements = function callee$0$0(strategy, selector, mult, context) {
var initSelector, rewroteSelector, stripViewFromSelector, endpoint, body, method, els;
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:
stripViewFromSelector = function stripViewFromSelector(selector) {
// Don't strip it out if it's one of these 4 element types
// (see https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBElementTypeTransformer.m for reference)
var keepView = ['XCUIElementTypeScrollView', 'XCUIElementTypeCollectionView', 'XCUIElementTypeTextView', 'XCUIElementTypeWebView'].indexOf(selector) >= 0;
if (!keepView && selector.indexOf('View') === selector.length - 4) {
return selector.substr(0, selector.length - 4);
} else {
return selector;
}
};
initSelector = selector;
rewroteSelector = false;
if (strategy === '-ios predicate string') {
// WebDriverAgent uses 'predicate string'
strategy = 'predicate string';
} else if (strategy === '-ios class chain') {
// WebDriverAgent uses 'class chain'
strategy = 'class chain';
}
// Check if the word 'View' is appended to selector and if it is, strip it out
if (strategy === 'class name') {
// XCUITest classes have `XCUIElementType` prepended
// first check if there is the old `UIA` prefix
if (selector.indexOf('UIA') === 0) {
selector = selector.substring(3);
}
// now check if we need to add `XCUIElementType`
if (selector.indexOf('XCUIElementType') !== 0) {
selector = stripViewFromSelector('XCUIElementType' + selector);
rewroteSelector = true;
}
}
if (strategy === 'xpath') {
// Replace UIA if it comes after a forward slash or is at the beginning of the string
selector = selector.replace(/(^|\/)(UIA)([^\[\/]+)/g, function (str, g1, g2, g3) {
rewroteSelector = true;
return g1 + stripViewFromSelector('XCUIElementType' + g3);
});
}
if (rewroteSelector) {
_logger2['default'].info('Rewrote incoming selector from \'' + initSelector + '\' to ' + ('\'' + selector + '\' to match XCUI type. You should consider ') + 'updating your tests to use the new selectors directly');
}
context = _appiumSupport.util.unwrapElement(context);
endpoint = undefined;
/* jshint ignore:start */
endpoint = '/element' + (context ? '/' + context + '/element' : '') + (mult ? 's' : '');
/* jshint ignore:end */
body = {
using: strategy,
value: selector
};
method = 'POST';
els = undefined;
context$1$0.prev = 13;
context$1$0.next = 16;
return _regeneratorRuntime.awrap(this.implicitWaitForCondition(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.proxyCommand(endpoint, method, body));
case 3:
els = context$2$0.sent;
if (!mult) {
context$2$0.next = 8;
break;
}
return context$2$0.abrupt('return', els && els.length);
case 8:
return context$2$0.abrupt('return', !els.status || els.status === 0);
case 9:
context$2$0.next = 15;
break;
case 11:
context$2$0.prev = 11;
context$2$0.t0 = context$2$0['catch'](0);
els = undefined;
return context$2$0.abrupt('return', false);
case 15:
case 'end':
return context$2$0.stop();
}
}, null, _this, [[0, 11]]);
}));
case 16:
context$1$0.next = 25;
break;
case 18:
context$1$0.prev = 18;
context$1$0.t0 = context$1$0['catch'](13);
if (!(context$1$0.t0.message && context$1$0.t0.message.match(/Condition unmet/))) {
context$1$0.next = 24;
break;
}
// condition was not met setting res to empty array
els = [];
context$1$0.next = 25;
break;
case 24:
throw context$1$0.t0;
case 25:
if (!mult) {
context$1$0.next = 29;
break;
}
return context$1$0.abrupt('return', els);
case 29:
if (!(!els || _lodash2['default'].size(els) === 0)) {
context$1$0.next = 31;
break;
}
throw new _appiumBaseDriver.errors.NoSuchElementError();
case 31:
return context$1$0.abrupt('return', els);
case 32:
case 'end':
return context$1$0.stop();
}
}, null, this, [[13, 18]]);
};
_Object$assign(extensions, commands, helpers);
exports.commands = commands;
exports.helpers = helpers;
exports['default'] = extensions;
// jshint ignore:line
// we succeed if we get some elements
// we may not get any status, which means success
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9jb21tYW5kcy9maW5kLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztzQkFBYyxRQUFROzs7O2dDQUNDLG9CQUFvQjs7NkJBQ3RCLGdCQUFnQjs7c0JBQ3JCLFdBQVc7Ozs7QUFHM0IsSUFBSSxPQUFPLEdBQUcsRUFBRTtJQUFFLFFBQVEsR0FBRyxFQUFFO0lBQUUsVUFBVSxHQUFHLEVBQUUsQ0FBQzs7QUFFakQsT0FBTyxDQUFDLFdBQVcsR0FBRyxvQkFBZ0IsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTzs7OzthQUNqRSxJQUFJLENBQUMsU0FBUyxFQUFFOzs7Ozs7eUNBQ0wsSUFBSSxDQUFDLHdCQUF3QixDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQzs7Ozs7Ozt5Q0FFaEUsSUFBSSxDQUFDLDJCQUEyQixDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQzs7Ozs7Ozs7OztDQUVuRixDQUFDOztBQUVGLE9BQU8sQ0FBQywyQkFBMkIsR0FBRyxvQkFBZ0IsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTztNQUMvRSxZQUFZLEVBQ2QsZUFBZSxFQVVWLHFCQUFxQixFQThDMUIsUUFBUSxFQUtSLElBQUksRUFLSixNQUFNLEVBRU4sR0FBRzs7Ozs7O0FBMURFLDZCQUFxQixZQUFyQixxQkFBcUIsQ0FBRSxRQUFRLEVBQUU7OztBQUd4QyxjQUFJLFFBQVEsR0FBRyxDQUNiLDJCQUEyQixFQUMzQiwrQkFBK0IsRUFDL0IseUJBQXlCLEVBQ3pCLHdCQUF3QixDQUN6QixDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7O0FBRXpCLGNBQUksQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNqRSxtQkFBTyxRQUFRLENB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aW5kLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGVycm9ycyB9IGZyb20gJ2FwcGl1bS1iYXNlLWRyaXZlcic7XG5pbXBvcnQgeyB1dGlsIH0gZnJvbSAnYXBwaXVtLXN1cHBvcnQnO1xuaW1wb3J0IGxvZyBmcm9tICcuLi9sb2dnZXInO1xuXG5cbmxldCBoZWxwZXJzID0ge30sIGNvbW1hbmRzID0ge30sIGV4dGVuc2lvbnMgPSB7fTtcblxuaGVscGVycy5maW5kRWxPckVscyA9IGFzeW5jIGZ1bmN0aW9uIChzdHJhdGVneSwgc2VsZWN0b3IsIG11bHQsIGNvbnRleHQpIHtcbiAgaWYgKHRoaXMuaXNXZWJ2aWV3KCkpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5maW5kV2ViRWxlbWVudE9yRWxlbWVudHMoc3RyYXRlZ3ksIHNlbGVjdG9yLCBtdWx0LCBjb250ZXh0KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5maW5kTmF0aXZlRWxlbWVudE9yRWxlbWVudHMoc3RyYXRlZ3ksIHNlbGVjdG9yLCBtdWx0LCBjb250ZXh0KTtcbiAgfVxufTtcblxuaGVscGVycy5maW5kTmF0aXZlRWxlbWVudE9yRWxlbWVudHMgPSBhc3luYyBmdW5jdGlvbiAoc3RyYXRlZ3ksIHNlbGVjdG9yLCBtdWx0LCBjb250ZXh0KSB7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuICBjb25zdCBpbml0U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgbGV0IHJld3JvdGVTZWxlY3RvciA9IGZhbHNlO1xuICBpZiAoc3RyYXRlZ3kgPT09ICctaW9zIHByZWRpY2F0ZSBzdHJpbmcnKSB7XG4gICAgLy8gV2ViRHJpdmVyQWdlbnQgdXNlcyAncHJlZGljYXRlIHN0cmluZydcbiAgICBzdHJhdGVneSA9ICdwcmVkaWNhdGUgc3RyaW5nJztcbiAgfSBlbHNlIGlmIChzdHJhdGVneSA9PT0gJy1pb3MgY2xhc3MgY2hhaW4nKSB7XG4gICAgLy8gV2ViRHJpdmVyQWdlbnQgdXNlcyAnY2xhc3MgY2hhaW4nXG4gICAgc3RyYXRlZ3kgPSAnY2xhc3MgY2hhaW4nO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgdGhlIHdvcmQgJ1ZpZXcnIGlzIGFwcGVuZGVkIHRvIHNlbGVjdG9yIGFuZCBpZiBpdCBpcywgc3RyaXAgaXQgb3V0XG4gIGZ1bmN0aW9uIHN0cmlwVmlld0Zyb21TZWxlY3RvciAoc2VsZWN0b3IpIHtcbiAgICAvLyBEb24ndCBzdHJpcCBpdCBvdXQgaWYgaXQncyBvbmUgb2YgdGhlc2UgNCBlbGVtZW50IHR5cGVzXG4gICAgLy8gKHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svV2ViRHJpdmVyQWdlbnQvYmxvYi9tYXN0ZXIvV2ViRHJpdmVyQWdlbnRMaWIvVXRpbGl0aWVzL0ZCRWxlbWVudFR5cGVUcmFuc2Zvcm1lci5tIGZvciByZWZlcmVuY2UpXG4gICAgbGV0IGtlZXBWaWV3ID0gW1xuICAgICAgJ1hDVUlFbGVtZW50VHlwZVNjcm9sbFZpZXcnLFxuICAgICAgJ1hDVUlFbGVtZW50VHlwZUNvbGxlY3Rpb25WaWV3JyxcbiAgICAgICdYQ1VJRWxlbWVudFR5cGVUZXh0VmlldycsXG4gICAgICAnWENVSUVsZW1lbnRUeXBlV2ViVmlldycsXG4gICAgXS5pbmRleE9mKHNlbGVjdG9yKSA+PSAwO1xuXG4gICAgaWYgKCFrZWVwVmlldyAmJiBzZWxlY3Rvci5pbmRleE9mKCdWaWV3JykgPT09IHNlbGVjdG9yLmxlbmd0aCAtIDQpIHtcbiAgICAgIHJldHVybiBzZWxlY3Rvci5zdWJzdHIoMCwgc2VsZWN0b3IubGVuZ3RoIC0gNCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzZWxlY3RvcjtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RyYXRlZ3kgPT09ICdjbGFzcyBuYW1lJykge1xuICAgIC8vIFhDVUlUZXN0IGNsYXNzZXMgaGF2ZSBgWENVSUVsZW1lbnRUeXBlYCBwcmVwZW5kZWRcbiAgICAvLyBmaXJzdCBjaGVjayBpZiB0aGVyZSBpcyB0aGUgb2xkIGBVSUFgIHByZWZpeFxuICAgIGlmIChzZWxlY3Rvci5pbmRleE9mKCdVSUEnKSA9PT0gMCkge1xuICAgICAgc2VsZWN0b3IgPSBzZWxlY3Rvci5zdWJzdHJpbmcoMyk7XG4gICAgfVxuICAgIC8vIG5vdyBjaGVjayBpZiB3ZSBuZWVkIHRvIGFkZCBgWENVSUVsZW1lbnRUeXBlYFxuICAgIGlmIChzZWxlY3Rvci5pbmRleE9mKCdYQ1VJRWxlbWVudFR5cGUnKSAhPT0gMCkge1xuICAgICAgc2VsZWN0b3IgPSBzdHJpcFZpZXdGcm9tU2VsZWN0b3IoYFhDVUlFbGVtZW50VHlwZSR7c2VsZWN0b3J9YCk7XG4gICAgICByZXdyb3RlU2VsZWN0b3IgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdHJhdGVneSA9PT0gJ3hwYXRoJykge1xuICAgIC8vIFJlcGxhY2UgVUlBIGlmIGl0IGNvbWVzIGFmdGVyIGEgZm9yd2FyZCBzbGFzaCBvciBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmdcbiAgICBzZWxlY3RvciA9IHNlbGVjdG9yLnJlcGxhY2UoLyhefFxcLykoVUlBKShbXlxcW1xcL10rKS9nLCAoc3RyLCBnMSwgZzIsIGczKSA9PiB7XG4gICAgICByZXdyb3RlU2VsZWN0b3IgPSB0cnVlO1xuICAgICAgcmV0dXJuIGcxICsgc3RyaXBWaWV3RnJvbVNlbGVjdG9yKGBYQ1VJRWxlbWVudFR5cGUke2czfWApO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHJld3JvdGVTZWxlY3Rvcikge1xuICAgIGxvZy5pbmZvKGBSZXdyb3RlIGluY29taW5nIHNlbGVjdG9yIGZyb20gJyR7aW5pdFNlbGVjdG9yfScgdG8gYCArXG4gICAgICAgICAgICAgYCcke3NlbGVjdG9yfScgdG8gbWF0Y2ggWENVSSB0eXBlLiBZb3Ugc2hvdWxkIGNvbnNpZGVyIGAgK1xuICAgICAgICAgICAgIGB1cGRhdGluZyB5b3VyIHRlc3RzIHRvIHVzZSB0aGUgbmV3IHNlbGVjdG9ycyBkaXJlY3RseWApO1xuICB9XG5cbiAgY29udGV4dCA9IHV0aWwudW53cmFwRWxlbWVudChjb250ZXh0KTtcblxuICBsZXQgZW5kcG9pbnQ7XG4gIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgZW5kcG9pbnQgPSBgL2VsZW1lbnQke2NvbnRleHQgPyBgLyR7Y29udGV4dH0vZWxlbWVudGAgOiAnJ30ke211bHQgPyAncycgOiAnJ31gO1xuICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gIGxldCBib2R5ID0ge1xuICAgIHVzaW5nOiBzdHJhdGVneSxcbiAgICB2YWx1ZTogc2VsZWN0b3JcbiAgfTtcblxuICBsZXQgbWV0aG9kID0gJ1BPU1QnO1xuXG4gIGxldCBlbHM7XG4gIHRyeSB7XG4gICAgYXdhaXQgdGhpcy5pbXBsaWNpdFdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZWxzID0gYXdhaXQgdGhpcy5wcm94eUNvbW1hbmQoZW5kcG9pbnQsIG1ldGhvZCwgYm9keSk7XG4gICAgICAgIGlmIChtdWx0KSB7XG4gICAgICAgICAgLy8gd2Ugc3VjY2VlZCBpZiB3ZSBnZXQgc29tZSBlbGVtZW50c1xuICAgICAgICAgIHJldHVybiBlbHMgJiYgZWxzLmxlbmd0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB3ZSBtYXkgbm90IGdldCBhbnkgc3RhdHVzLCB3aGljaCBtZWFucyBzdWNjZXNzXG4gICAgICAgICAgcmV0dXJuICFlbHMuc3RhdHVzIHx8IGVscy5zdGF0dXMgPT09IDA7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBlbHMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGVyci5tZXNzYWdlICYmIGVyci5tZXNzYWdlLm1hdGNoKC9Db25kaXRpb24gdW5tZXQvKSkge1xuICAgICAgLy8gY29uZGl0aW9uIHdhcyBub3QgbWV0IHNldHRpbmcgcmVzIHRvIGVtcHR5IGFycmF5XG4gICAgICBlbHMgPSBbXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuICBpZiAobXVsdCkge1xuICAgIHJldHVybiBlbHM7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFlbHMgfHwgXy5zaXplKGVscykgPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuTm9TdWNoRWxlbWVudEVycm9yKCk7XG4gICAgfVxuICAgIHJldHVybiBlbHM7XG4gIH1cbn07XG5cblxuT2JqZWN0LmFzc2lnbihleHRlbnNpb25zLCBjb21tYW5kcywgaGVscGVycyk7XG5leHBvcnQgeyBjb21tYW5kcywgaGVscGVyc307XG5leHBvcnQgZGVmYXVsdCBleHRlbnNpb25zO1xuIl0sInNvdXJjZVJvb3QiOiIuLi8uLi8uLiJ9