appium-uiautomator
Version:
Appium Android UI Automator interface
172 lines (133 loc) • 15.1 kB
JavaScript
// transpile :mocha
;
var _regeneratorRuntime = require('babel-runtime/regenerator')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
var _interopRequireWildcard = require('babel-runtime/helpers/interop-require-wildcard')['default'];
var _chai = require('chai');
var _chai2 = _interopRequireDefault(_chai);
var _chaiAsPromised = require('chai-as-promised');
var _chaiAsPromised2 = _interopRequireDefault(_chaiAsPromised);
var _sinon = require('sinon');
var _sinon2 = _interopRequireDefault(_sinon);
var _ = require('../..');
var _2 = _interopRequireDefault(_);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _appiumAdb = require('appium-adb');
var _appiumAdb2 = _interopRequireDefault(_appiumAdb);
var _appiumTestSupport = require('appium-test-support');
var _teen_process = require('teen_process');
var teen_process = _interopRequireWildcard(_teen_process);
var _events = require('events');
var _events2 = _interopRequireDefault(_events);
_chai2['default'].should();
_chai2['default'].use(_chaiAsPromised2['default']);
describe('UiAutomator', function () {
var uiAutomator = undefined,
adb = new _appiumAdb2['default']();
var rootDir = _path2['default'].resolve(__dirname, process.env.NO_PRECOMPILE ? '../..' : '../../..');
var bootstrapJar = _path2['default'].resolve(rootDir, 'test', 'fixtures', 'AppiumBootstrap.jar'),
bootstrapClassName = 'io.appium.android.bootstrap.Bootstrap';
before(function () {
uiAutomator = new _2['default'](adb);
});
it('should throw an error if adb is not passed', function () {
(function () {
new _2['default']();
}).should['throw'](/adb is required/);
});
it("parseJarNameFromPath should parse jarName from path and windows path", function () {
uiAutomator.parseJarNameFromPath(bootstrapJar).should.equal('AppiumBootstrap.jar');
var windowsJarName = 'C:\\\\appium\\bar.jar';
uiAutomator.parseJarNameFromPath(windowsJarName).should.equal('bar.jar');
});
it("parseJarNameFromPath should throw error for invalid path", 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:
(function () {
uiAutomator.parseJarNameFromPath('foo/bar');
}).should['throw'](/Unable to parse/);
case 1:
case 'end':
return context$2$0.stop();
}
}, null, this);
});
describe("start", (0, _appiumTestSupport.withSandbox)({ mocks: { adb: adb, teen_process: teen_process } }, function (S) {
it("should return a subProcess", function callee$2$0() {
var conn, args;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
conn = new _events2['default'].EventEmitter();
conn.start = function () {};
args = ["-P", 5037, "shell", "uiautomator", "runtest", 'AppiumBootstrap.jar', "-c", bootstrapClassName];
S.mocks.adb.expects('push').once().withExactArgs(bootstrapJar, "/data/local/tmp/").returns('');
S.mocks.adb.expects('getAdbPath').once().returns('adbPath');
S.mocks.teen_process.expects("SubProcess").once().withExactArgs('adbPath', args).returns(conn);
context$3$0.next = 8;
return _regeneratorRuntime.awrap(uiAutomator.start(bootstrapJar, bootstrapClassName));
case 8:
uiAutomator.state.should.equal('online');
S.verify();
case 10:
case 'end':
return context$3$0.stop();
}
}, null, this);
});
}));
describe("shutdown", (0, _appiumTestSupport.withSandbox)({ mocks: { adb: adb, teen_process: teen_process } }, function (S) {
it("should not fail if it is already stopped", function callee$2$0() {
var conn, mock;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
conn = new _events2['default'].EventEmitter();
conn.start = function () {};
conn.stop = function () {};
mock = _sinon2['default'].mock(conn);
// It should NOT stop the process when shutting down, because it is already stopped
mock.expects("stop").atMost(0);
uiAutomator.proc = conn;
// simulate uiAutomator unexpectedly terminates
uiAutomator.changeState('stopped');
context$3$0.next = 9;
return _regeneratorRuntime.awrap(uiAutomator.shutdown());
case 9:
uiAutomator.state.should.equal('stopped');
S.verify();
case 11:
case 'end':
return context$3$0.stop();
}
}, null, this);
});
it("should stop the uiautomator process", function callee$2$0() {
var conn, mock;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
conn = new _events2['default'].EventEmitter();
conn.start = function () {};
conn.stop = function () {};
mock = _sinon2['default'].mock(conn);
// It should stop the process when shutting down
mock.expects("stop").once();
uiAutomator.proc = conn;
uiAutomator.changeState('online');
context$3$0.next = 9;
return _regeneratorRuntime.awrap(uiAutomator.shutdown());
case 9:
uiAutomator.state.should.equal('stopped');
S.verify();
case 11:
case 'end':
return context$3$0.stop();
}
}, null, this);
});
}));
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvdW5pdC91aWF1dG9tYXRvci1zcGVjcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O29CQUVpQixNQUFNOzs7OzhCQUNJLGtCQUFrQjs7OztxQkFDM0IsT0FBTzs7OztnQkFDRCxPQUFPOzs7O29CQUNkLE1BQU07Ozs7eUJBQ1AsWUFBWTs7OztpQ0FDQSxxQkFBcUI7OzRCQUNuQixjQUFjOztJQUFoQyxZQUFZOztzQkFDTCxRQUFROzs7O0FBRzNCLGtCQUFLLE1BQU0sRUFBRSxDQUFDO0FBQ2Qsa0JBQUssR0FBRyw2QkFBZ0IsQ0FBQzs7QUFFekIsUUFBUSxDQUFDLGFBQWEsRUFBRSxZQUFZO0FBQ2xDLE1BQUksV0FBVyxZQUFBO01BQUUsR0FBRyxHQUFFLDRCQUFTLENBQUM7QUFDaEMsTUFBSSxPQUFPLEdBQUcsa0JBQUssT0FBTyxDQUFDLFNBQVMsRUFDVCxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsR0FBRyxPQUFPLEdBQUcsVUFBVSxDQUFDLENBQUM7QUFDN0UsTUFBTSxZQUFZLEdBQUcsa0JBQUssT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLHFCQUFxQixDQUFDO01BQy9FLGtCQUFrQixHQUFHLHVDQUF1QyxDQUFDO0FBQ25FLFFBQU0sQ0FBQyxZQUFZO0FBQ2pCLGVBQVcsR0FBRyxrQkFBZ0IsR0FBRyxDQUFDLENBQUM7R0FDcEMsQ0FBQyxDQUFDOztBQUVILElBQUUsQ0FBQyw0Q0FBNEMsRUFBRSxZQUFZO0FBQzNELEtBQUMsWUFBTTtBQUFFLHlCQUFpQixDQUFDO0tBQUUsQ0FBQSxDQUFFLE1BQU0sU0FBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7R0FDaEUsQ0FBQyxDQUFDO0FBQ0gsSUFBRSxDQUFDLHNFQUFzRSxFQUFFLFlBQVk7QUFDckYsZUFBVyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUNuRixR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Ozs7OztLQUNaLENBQUMsQ0FBQztBQUNILE1BQUUsQ0FBQyxxQ0FBcUMsRUFBRTtVQUNwQyxJQUFJLEVBR0osSUFBSTs7OztBQUhKLGdCQUFJLEdBQUcsSUFBSSxvQkFBTyxZQUFZLEVBQUU7O0FBQ3BDLGdCQUFJLENBQUMsS0FBSyxHQUFHLFlBQU0sRUFBRyxDQUFDO0FBQ3ZCLGdCQUFJLENBQUMsSUFBSSxHQUFHLFlBQU0sRUFBRyxDQUFDO0FBQ2xCLGdCQUFJLEdBQUcsbUJBQU0sSUFBSSxDQUFDLElBQUksQ0FBQzs7O0FBRTNCLGdCQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQzVCLHVCQUFXLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN4Qix1QkFBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7NkNBQzVCLFdBQVcsQ0FBQyxRQUFRLEVBQUU7OztBQUM1Qix1QkFBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzFDLGFBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQzs7Ozs7OztLQUNaLENBQUMsQ0FBQztHQUNKLENBQUMsQ0FBQyxDQUFDO0NBQ0wsQ0FBQyxDQUFDIiwiZmlsZSI6InRlc3QvdW5pdC91aWF1dG9tYXRvci1zcGVjcy5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRyYW5zcGlsZSA6bW9jaGFcblxuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgY2hhaUFzUHJvbWlzZWQgZnJvbSAnY2hhaS1hcy1wcm9taXNlZCc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IFVpQXV0b21hdG9yIGZyb20gJy4uLy4uJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IEFEQiBmcm9tICdhcHBpdW0tYWRiJztcbmltcG9ydCB7IHdpdGhTYW5kYm94IH0gZnJvbSAnYXBwaXVtLXRlc3Qtc3VwcG9ydCc7XG5pbXBvcnQgKiBhcyB0ZWVuX3Byb2Nlc3MgZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBldmVudHMgZnJvbSAnZXZlbnRzJztcblxuXG5jaGFpLnNob3VsZCgpO1xuY2hhaS51c2UoY2hhaUFzUHJvbWlzZWQpO1xuXG5kZXNjcmliZSgnVWlBdXRvbWF0b3InLCBmdW5jdGlvbiAoKSB7XG4gIGxldCB1aUF1dG9tYXRvciwgYWRiPSBuZXcgQURCKCk7XG4gIGxldCByb290RGlyID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5lbnYuTk9fUFJFQ09NUElMRSA/ICcuLi8uLicgOiAnLi4vLi4vLi4nKTtcbiAgY29uc3QgYm9vdHN0cmFwSmFyID0gcGF0aC5yZXNvbHZlKHJvb3REaXIsICd0ZXN0JywgJ2ZpeHR1cmVzJywgJ0FwcGl1bUJvb3RzdHJhcC5qYXInKSxcbiAgICAgICAgYm9vdHN0cmFwQ2xhc3NOYW1lID0gJ2lvLmFwcGl1bS5hbmRyb2lkLmJvb3RzdHJhcC5Cb290c3RyYXAnO1xuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIHVpQXV0b21hdG9yID0gbmV3IFVpQXV0b21hdG9yKGFkYik7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgYWRiIGlzIG5vdCBwYXNzZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgKCgpID0+IHsgbmV3IFVpQXV0b21hdG9yKCk7IH0pLnNob3VsZC50aHJvdygvYWRiIGlzIHJlcXVpcmVkLyk7XG4gIH0pO1xuICBpdChcInBhcnNlSmFyTmFtZUZyb21QYXRoIHNob3VsZCBwYXJzZSBqYXJOYW1lIGZyb20gcGF0aCBhbmQgd2luZG93cyBwYXRoXCIsIGZ1bmN0aW9uICgpIHtcbiAgICB1aUF1dG9tYXRvci5wYXJzZUphck5hbWVGcm9tUGF0aChib290c3RyYXBKYXIpLnNob3VsZC5lcXVhbCgnQXBwaXVtQm9vdHN0cmFwLmphcicpO1xuICAgIGxldCB3aW5kb3dzSmFyTmFtZSA9IGBDOlxcXFxcXFxcYXBwaXVtXFxcXGJhci5qYXJgO1xuICAgIHVpQXV0b21hdG9yLnBhcnNlSmFyTmFtZUZyb21QYXRoKHdpbmRvd3NKYXJOYW1lKS5zaG91bGQuZXF1YWwoJ2Jhci5qYXInKTtcbiAgfSk7XG4gIGl0KFwicGFyc2VKYXJOYW1lRnJvbVBhdGggc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIHBhdGhcIiwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICgoKSA9PiB7IHVpQXV0b21hdG9yLnBhcnNlSmFyTmFtZUZyb21QYXRoKCdmb28vYmFyJyk7IH0pLnNob3VsZC50aHJvdygvVW5hYmxlIHRvIHBhcnNlLyk7XG4gIH0pO1xuICBkZXNjcmliZShcInN0YXJ0XCIsIHdpdGhTYW5kYm94KHttb2Nrczoge2FkYiwgdGVlbl9wcm9jZXNzfX0sIChTKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIGEgc3ViUHJvY2Vzc1wiLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgY29ubiA9IG5ldyBldmVudHMuRXZlbnRFbWl0dGVyKCk7XG4gICAgICBjb25uLnN0YXJ0ID0gKCkgPT4geyB9O1xuICAgICAgbGV0IGFyZ3MgPSBbXCItUFwiLCA1MDM3LCBcInNoZWxsXCIsIFwidWlhdXRvbWF0b3JcIiwgXCJydW50ZXN0XCIsICdBcHBpdW1Cb290c3RyYXAuamFyJyxcbiAgICAgICAgICAgICAgICAgIFwiLWNcIiwgYm9vdHN0cmFwQ2xhc3NOYW1lXTtcbiAgICAgIFMubW9ja3MuYWRiLmV4cGVjdHMoJ3B1c2gnKS5vbmNlKClcbiAgICAgICAgLndpdGhFeGFjdEFyZ3MoYm9vdHN0cmFwSmFyLCBcIi9kYXRhL2xvY2FsL3RtcC9cIilcbiAgICAgICAgLnJldHVybnMoJycpO1xuICAgICAgUy5tb2Nrcy5hZGIuZXhwZWN0cygnZ2V0QWRiUGF0aCcpLm9uY2UoKVxuICAgICAgICAucmV0dXJucygnYWRiUGF0aCcpO1xuICAgICAgUy5tb2Nrcy50ZWVuX3Byb2Nlc3MuZXhwZWN0cyhcIlN1YlByb2Nlc3NcIilcbiAgICAgICAgLm9uY2UoKS53aXRoRXhhY3RBcmdzKCdhZGJQYXRoJywgYXJncylcbiAgICAgICAgLnJldHVybnMoY29ubik7XG4gICAgICBhd2FpdCB1aUF1dG9tYXRvci5zdGFydChib290c3RyYXBKYXIsIGJvb3RzdHJhcENsYXNzTmFtZSk7XG4gICAgICB1aUF1dG9tYXRvci5zdGF0ZS5zaG91bGQuZXF1YWwoJ29ubGluZScpO1xuICAgICAgUy52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSkpO1xuICBkZXNjcmliZShcInNodXRkb3duXCIsIHdpdGhTYW5kYm94KHttb2Nrczoge2FkYiwgdGVlbl9wcm9jZXNzfX0sIChTKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgbm90IGZhaWwgaWYgaXQgaXMgYWxyZWFkeSBzdG9wcGVkXCIsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBjb25uID0gbmV3IGV2ZW50cy5FdmVudEVtaXR0ZXIoKTtcbiAgICAgIGNvbm4uc3RhcnQgPSAoKSA9PiB7IH07XG4gICAgICBjb25uLnN0b3AgPSAoKSA9PiB7IH07XG4gICAgICBsZXQgbW9jayA9IHNpbm9uLm1vY2soY29ubik7XG4gICAgICAvLyBJdCBzaG91bGQgTk9UIHN0b3AgdGhlIHByb2Nlc3Mgd2hlbiBzaHV0dGluZyBkb3duLCBiZWNhdXNlIGl0IGlzIGFscmVhZHkgc3RvcHBlZFxuICAgICAgbW9jay5leHBlY3RzKFwic3RvcFwiKS5hdE1vc3QoMCk7XG4gICAgICB1aUF1dG9tYXRvci5wcm9jID0gY29ubjtcblxuICAgICAgLy8gc2ltdWxhdGUgdWlBdXRvbWF0b3IgdW5leHBlY3RlZGx5IHRlcm1pbmF0ZXNcbiAgICAgIHVpQXV0b21hdG9yLmNoYW5nZVN0YXRlKCdzdG9wcGVkJyk7XG4gICAgICBhd2FpdCB1aUF1dG9tYXRvci5zaHV0ZG93bigpO1xuICAgICAgdWlBdXRvbWF0b3Iuc3RhdGUuc2hvdWxkLmVxdWFsKCdzdG9wcGVkJyk7XG4gICAgICBTLnZlcmlmeSgpO1xuICAgIH0pO1xuICAgIGl0KFwic2hvdWxkIHN0b3AgdGhlIHVpYXV0b21hdG9yIHByb2Nlc3NcIiwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGNvbm4gPSBuZXcgZXZlbnRzLkV2ZW50RW1pdHRlcigpO1xuICAgICAgY29ubi5zdGFydCA9ICgpID0+IHsgfTtcbiAgICAgIGNvbm4uc3RvcCA9ICgpID0+IHsgfTtcbiAgICAgIGxldCBtb2NrID0gc2lub24ubW9jayhjb25uKTtcbiAgICAgIC8vIEl0IHNob3VsZCBzdG9wIHRoZSBwcm9jZXNzIHdoZW4gc2h1dHRpbmcgZG93blxuICAgICAgbW9jay5leHBlY3RzKFwic3RvcFwiKS5vbmNlKCk7XG4gICAgICB1aUF1dG9tYXRvci5wcm9jID0gY29ubjtcbiAgICAgIHVpQXV0b21hdG9yLmNoYW5nZVN0YXRlKCdvbmxpbmUnKTtcbiAgICAgIGF3YWl0IHVpQXV0b21hdG9yLnNodXRkb3duKCk7XG4gICAgICB1aUF1dG9tYXRvci5zdGF0ZS5zaG91bGQuZXF1YWwoJ3N0b3BwZWQnKTtcbiAgICAgIFMudmVyaWZ5KCk7XG4gICAgfSk7XG4gIH0pKTtcbn0pO1xuIl0sInNvdXJjZVJvb3QiOiIuLi8uLi8uLiJ9