Skip to content

Commit 3d3959a

Browse files
authored
merge updates from upstream to master (#1)
* Add eslint and fix problems * Add androidInstallTimeout capability. Replace REMOTE_INSTALL_TIMEOUT with androidInstallTimeout capability. * 1.10.11 * Use correct capability arguments installApkRemotely to parse correct capabilities from opts * Honor reset without the app capability Fixes appium#157 * 1.10.12
1 parent 53fa62e commit 3d3959a

18 files changed

+109
-53
lines changed

Diff for: .eslintrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "appium"
3+
}

Diff for: .travis.yml

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
language: node_js
22
node_js:
33
- "0.12"
4+
script:
5+
- gulp eslint
6+
- gulp once
47
after_success:
58
- gulp coveralls

Diff for: lib/android-helpers.js

+16-17
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ helpers.ensureDeviceLocale = async function (adb, language, country) {
6363
return;
6464
}
6565
let changed = false;
66-
if (await adb.getApiLevel() < 23)
67-
{
66+
if (await adb.getApiLevel() < 23) {
6867
let curLanguage = await adb.getDeviceLanguage();
6968
let curCountry = await adb.getDeviceCountry();
7069
if (haveLanguage && language !== curLanguage) {
@@ -124,9 +123,9 @@ helpers.getDeviceInfoFromCaps = async function (opts = {}) {
124123
`of connected devices`);
125124
}
126125
emPort = adb.getPortFromEmulatorString(udid);
127-
} else if (!!opts.platformVersion) {
126+
} else if (opts.platformVersion) {
128127
// a platform version was given. lets try to find a device with the same os
129-
logger.info(`Looking for a device with Android ${opts.platformVersion}`);
128+
logger.info(`Looking for a device with Android '${opts.platformVersion}'`);
130129

131130
// in case we fail to find something, give the user a useful log that has
132131
// the device udids and os versions so they know what's available
@@ -215,7 +214,7 @@ helpers.getRemoteApkPath = function (localApkMd5) {
215214
return remotePath;
216215
};
217216

218-
helpers.resetApp = async function (adb, localApkPath, pkg, fastReset) {
217+
helpers.resetApp = async function (adb, localApkPath, pkg, fastReset, androidInstallTimeout = REMOTE_INSTALL_TIMEOUT) {
219218
if (fastReset) {
220219
logger.debug("Running fast reset (stop and clear)");
221220
await adb.stopAndClear(pkg);
@@ -226,12 +225,12 @@ helpers.resetApp = async function (adb, localApkPath, pkg, fastReset) {
226225
if (!await adb.fileExists(remotePath)) {
227226
throw new Error("Can't run slow reset without a remote apk!");
228227
}
229-
await helpers.reinstallRemoteApk(adb, localApkPath, pkg, remotePath);
228+
await helpers.reinstallRemoteApk(adb, localApkPath, pkg, remotePath, androidInstallTimeout);
230229
}
231230
};
232231

233232
helpers.reinstallRemoteApk = async function (adb, localApkPath, pkg,
234-
remotePath, tries = 2) {
233+
remotePath, androidInstallTimeout, tries = 2) {
235234
await retry(tries, async () => {
236235
try {
237236
// first do an uninstall of the package to make sure it's not there
@@ -240,7 +239,7 @@ helpers.reinstallRemoteApk = async function (adb, localApkPath, pkg,
240239
logger.warn("Uninstalling remote APK failed, maybe it wasn't installed");
241240
}
242241
try {
243-
await adb.installFromDevicePath(remotePath, {timeout: 90000});
242+
await adb.installFromDevicePath(remotePath, {timeout: androidInstallTimeout});
244243
} catch (e) {
245244
logger.warn("Installing remote APK failed, going to uninstall and try " +
246245
"again");
@@ -253,18 +252,18 @@ helpers.reinstallRemoteApk = async function (adb, localApkPath, pkg,
253252
});
254253
};
255254

256-
helpers.installApkRemotely = async function (adb, localApkPath, pkg, fastReset) {
257-
let installTimeout = REMOTE_INSTALL_TIMEOUT;
255+
helpers.installApkRemotely = async function (adb, opts) {
256+
let {app, appPackage, fastReset, androidInstallTimeout} = opts;
258257

259-
let apkMd5 = await fs.md5(localApkPath);
260-
let remotePath = await helpers.getRemoteApkPath(apkMd5, localApkPath);
258+
let apkMd5 = await fs.md5(app);
259+
let remotePath = await helpers.getRemoteApkPath(apkMd5, app);
261260
let remoteApkExists = await adb.fileExists(remotePath);
262261
logger.debug("Checking if app is installed");
263-
let installed = await adb.isAppInstalled(pkg);
262+
let installed = await adb.isAppInstalled(appPackage);
264263

265264
if (installed && remoteApkExists && fastReset) {
266265
logger.info("Apk is already on remote and installed, resetting");
267-
await helpers.resetApp(adb, localApkPath, pkg, fastReset);
266+
await helpers.resetApp(adb, app, appPackage, fastReset, androidInstallTimeout);
268267
} else if (!installed || (!remoteApkExists && fastReset)) {
269268
if (!installed) {
270269
logger.info("Apk is not yet installed");
@@ -277,14 +276,14 @@ helpers.installApkRemotely = async function (adb, localApkPath, pkg, fastReset)
277276
await helpers.removeRemoteApks(adb, [apkMd5]);
278277
if (!remoteApkExists) {
279278
// push from local to remote
280-
logger.info(`Pushing ${pkg} to device. Will wait up to ${installTimeout} ` +
279+
logger.info(`Pushing ${appPackage} to device. Will wait up to ${androidInstallTimeout} ` +
281280
`milliseconds before aborting`);
282-
await adb.push(localApkPath, remotePath, {timeout: installTimeout});
281+
await adb.push(app, remotePath, {timeout: androidInstallTimeout});
283282
}
284283

285284
// Next, install from the remote path. This can be flakey. If it doesn't
286285
// work, clear out any cached apks, re-push from local, and try again
287-
await helpers.reinstallRemoteApk(adb, localApkPath, pkg, remotePath);
286+
await helpers.reinstallRemoteApk(adb, app, appPackage, remotePath, androidInstallTimeout);
288287
}
289288
};
290289

Diff for: lib/commands/network.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ commands.toggleFlightMode = async function () {
7878
};
7979

8080
commands.setGeoLocation = async function (location) {
81-
let cmd = ['am', 'startservice', '-e', 'longitude', location.longitude,
82-
'-e', 'latitude', location.latitude, 'io.appium.settings/.LocationService'];
83-
return await this.adb.shell(cmd);
81+
let cmd = ['am', 'startservice', '-e', 'longitude', location.longitude,
82+
'-e', 'latitude', location.latitude, 'io.appium.settings/.LocationService'];
83+
return await this.adb.shell(cmd);
8484
};
8585

8686
commands.toggleLocationServices = async function () {

Diff for: lib/desired-caps.js

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ let commonCapConstraints = {
3131
androidDeviceSocket: {
3232
isString: true
3333
},
34+
androidInstallTimeout: {
35+
isNumber: true
36+
},
3437
adbPort: {
3538
isNumber: true
3639
},

Diff for: lib/driver.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class AndroidDriver extends BaseDriver {
171171
// unlock the device
172172
await helpers.unlock(this.adb);
173173
// If the user sets autoLaunch to false, they are responsible for initAUT() and startAUT()
174-
if (!this.appOnDevice && this.opts.autoLaunch) {
174+
if (this.opts.autoLaunch) {
175175
// set up app under test
176176
await this.initAUT();
177177
}
@@ -225,15 +225,21 @@ class AndroidDriver extends BaseDriver {
225225
let launchInfo = await helpers.getLaunchInfo(this.adb, this.opts);
226226
Object.assign(this.opts, launchInfo);
227227
Object.assign(this.caps, launchInfo);
228-
if (!this.opts.skipUninstall) {
229-
await this.adb.uninstallApk(this.opts.appPackage);
230-
}
231228
// install app
232229
if (!this.opts.app) {
230+
if (this.opts.fullReset) {
231+
log.errorAndThrow('Full reset requires an app capability, use fastReset if app is not provided');
232+
}
233233
log.debug('No app capability. Assuming it is already on the device');
234+
if (this.opts.fastReset) {
235+
await helpers.resetApp(this.adb, this.opts.app, this.opts.appPackage, this.opts.fastReset);
236+
}
234237
return;
235238
}
236-
await helpers.installApkRemotely(this.adb, this.opts.app, this.opts.appPackage, this.opts.fastReset);
239+
if (!this.opts.skipUninstall) {
240+
await this.adb.uninstallApk(this.opts.appPackage);
241+
}
242+
await helpers.installApkRemotely(this.adb, this.opts);
237243
this.apkStrings[this.opts.language] = await helpers.pushStrings(
238244
this.opts.language, this.adb, this.opts);
239245
}

Diff for: package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"mobile",
1010
"mobile testing"
1111
],
12-
"version": "1.10.10",
12+
"version": "1.10.12",
1313
"author": "appium",
1414
"license": "Apache-2.0",
1515
"repository": {
@@ -55,8 +55,14 @@
5555
"devDependencies": {
5656
"appium-gulp-plugins": "^1.3.12",
5757
"appium-test-support": "0.0.5",
58+
"babel-eslint": "^6.1.0",
5859
"chai": "^3.0.0",
5960
"chai-as-promised": "^5.1.0",
61+
"eslint": "^2.13.1",
62+
"eslint-config-appium": "0.0.6",
63+
"eslint-plugin-babel": "^3.3.0",
64+
"eslint-plugin-import": "^1.9.2",
65+
"eslint-plugin-mocha": "^3.0.0",
6066
"gulp": "^3.8.11",
6167
"sample-apps": "2.0.4",
6268
"sinon": "^1.16.1",

Diff for: test/functional/android-helper-e2e-specs.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import helpers from '../../lib/android-helpers';
44
import sampleApps from 'sample-apps';
55
import ADB from 'appium-adb';
66

7-
let apiDemos = sampleApps('ApiDemos-debug');
8-
let appPackage = 'io.appium.android.apis';
7+
let opts = {
8+
app : sampleApps('ApiDemos-debug'),
9+
appPackage : 'io.appium.android.apis',
10+
androidInstallTimeout : 90000
11+
};
912

1013
chai.should();
1114
chai.use(chaiAsPromised);
@@ -15,10 +18,10 @@ describe('android-helpers e2e', () => {
1518
it('installs an apk by pushing it to the device then installing it from within', async function () {
1619
this.timeout(15000);
1720
var adb = await ADB.createADB();
18-
await adb.uninstallApk(appPackage);
19-
await adb.isAppInstalled(appPackage).should.eventually.be.false;
20-
await helpers.installApkRemotely(adb, apiDemos, appPackage);
21-
await adb.isAppInstalled(appPackage).should.eventually.be.true;
21+
await adb.uninstallApk(opts.appPackage);
22+
await adb.isAppInstalled(opts.appPackage).should.eventually.be.false;
23+
await helpers.installApkRemotely(adb, opts);
24+
await adb.isAppInstalled(opts.appPackage).should.eventually.be.true;
2225
});
2326
});
2427
describe('ensureDeviceLocale', () => {

Diff for: test/functional/commands/find/by-accessibility-id-e2e-specs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let defaultCaps = {
1313
platformName: 'Android'
1414
};
1515

16-
describe('Find - accessibility ID', function(){
16+
describe('Find - accessibility ID', function () {
1717
before(async () => {
1818
driver = new AndroidDriver();
1919
await driver.createSession(defaultCaps);

Diff for: test/functional/commands/find/by-id-e2e-specs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let defaultCaps = {
1313
platformName: 'Android'
1414
};
1515

16-
describe('Find - ID', function(){
16+
describe('Find - ID', function () {
1717
before(async () => {
1818
driver = new AndroidDriver();
1919
await driver.createSession(defaultCaps);

Diff for: test/functional/commands/geo-location-e2e-specs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import chai from 'chai';
22
import chaiAsPromised from 'chai-as-promised';
33
import { retryInterval } from 'asyncbox';
4-
import { AndroidDriver } from '../../../..';
4+
import AndroidDriver from '../../..';
55
import sampleApps from 'sample-apps';
66

77

Diff for: test/functional/commands/keyboard-e2e-specs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ describe('keyboard', () => {
138138
// sometimes the default ime is not what we are using
139139
let engines = await driver.availableIMEEngines();
140140
let selectedEngine = _.first(engines);
141-
for(let engine of engines) {
141+
for (let engine of engines) {
142142
// it seems that the latin ime has `android.inputmethod` in its package name
143143
if (engine.indexOf('android.inputmethod') !== -1) {
144144
selectedEngine = engine;

Diff for: test/functional/commands/localization/language-e2e-specs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe('Localization - language and country @skip-ci @skip-real-device', funct
3131
});
3232
});
3333

34-
describe('Localization - locale @skip-ci @skip-real-device', function() {
34+
describe('Localization - locale @skip-ci @skip-real-device', function () {
3535
// Stalls on API 23, works in CI
3636
beforeEach(async () => {
3737
driver = new AndroidDriver();

Diff for: test/functional/commands/url-e2e-specs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let defaultCaps = {
1313
platformName: 'Android'
1414
};
1515

16-
describe('setUrl', function(){
16+
describe('setUrl', function (){
1717
before(async () => {
1818
driver = new AndroidDriver();
1919
await driver.createSession(defaultCaps);

Diff for: test/functional/driver-e2e-specs.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ let driver;
1010
let defaultCaps = {
1111
app: sampleApps('ApiDemos-debug'),
1212
deviceName: 'Android',
13-
platformName: 'Android'
13+
platformName: 'Android',
14+
androidInstallTimeout: '90000'
1415
};
1516

1617
describe('createSession', function () {

Diff for: test/unit/android-helper-specs.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,12 @@ describe('Android Helpers', () => {
271271
describe('resetApp', withMocks({adb, fs, helpers}, (mocks) => {
272272
const localApkPath = 'local';
273273
const pkg = 'pkg';
274+
const androidInstallTimeout = 90000;
274275
it('should throw error if remote file does not exist', async () => {
275276
mocks.fs.expects('md5').withExactArgs(localApkPath).returns('apkmd5');
276277
mocks.adb.expects('fileExists').returns(false);
277278
mocks.helpers.expects('reinstallRemoteApk').never();
278-
await helpers.resetApp(adb, localApkPath, pkg, false).should.eventually
279+
await helpers.resetApp(adb, localApkPath, pkg, false, androidInstallTimeout).should.eventually
279280
.be.rejectedWith('slow');
280281
mocks.adb.verify();
281282
mocks.fs.verify();
@@ -285,7 +286,7 @@ describe('Android Helpers', () => {
285286
mocks.fs.expects('md5').withExactArgs(localApkPath).returns('apkmd5');
286287
mocks.adb.expects('fileExists').returns(true);
287288
mocks.helpers.expects('reinstallRemoteApk').once().returns('');
288-
await helpers.resetApp(adb, localApkPath, pkg, false);
289+
await helpers.resetApp(adb, localApkPath, pkg, false, androidInstallTimeout);
289290
mocks.adb.verify();
290291
mocks.fs.verify();
291292
mocks.helpers.verify();
@@ -296,39 +297,45 @@ describe('Android Helpers', () => {
296297
const localApkPath = 'local';
297298
const pkg = 'pkg';
298299
const remotePath = 'remote';
300+
const androidInstallTimeout = 90000;
299301
it('should throw error if remote file does not exist', async () => {
300302
mocks.adb.expects('uninstallApk').withExactArgs(pkg).returns('');
301303
// install remote is not defines do we mean installApkRemotely?
302304
mocks.adb.expects('installRemote').withExactArgs(remotePath)
303305
.returns('');
304-
await helpers.reinstallRemoteApk(adb, localApkPath, pkg, remotePath);
306+
await helpers.reinstallRemoteApk(adb, localApkPath, pkg, remotePath, androidInstallTimeout);
305307
mocks.adb.verify();
306308
});
307309
}));
308310
describe('installApkRemotely', withMocks({adb, fs, helpers}, (mocks) => {
309-
const localApkPath = 'local';
310-
const pkg = 'pkg';
311+
//use mock appium capabilities for this test
312+
const opts = {
313+
app : 'local',
314+
appPackage : 'pkg',
315+
fastReset : true,
316+
androidInstallTimeout : 90000
317+
};
311318
it('should reset app if already installed', async () => {
312-
mocks.fs.expects('md5').withExactArgs(localApkPath).returns('apkmd5');
319+
mocks.fs.expects('md5').withExactArgs(opts.app).returns('apkmd5');
313320
mocks.helpers.expects('getRemoteApkPath').returns(false);
314321
mocks.adb.expects('fileExists').returns(true);
315322
mocks.adb.expects('isAppInstalled').returns(true);
316323
mocks.helpers.expects('resetApp').once().returns("");
317-
await helpers.installApkRemotely(adb, localApkPath, pkg, true);
324+
await helpers.installApkRemotely(adb, opts);
318325
mocks.adb.verify();
319326
mocks.fs.verify();
320327
mocks.helpers.verify();
321328
});
322329
it.skip('should push and reinstall apk when apk is not installed', async () => {
323-
mocks.fs.expects('md5').withExactArgs(localApkPath).returns('apkmd5');
330+
mocks.fs.expects('md5').withExactArgs(opts.app).returns('apkmd5');
324331
mocks.helpers.expects('getRemoteApkPath').returns(true);
325332
mocks.adb.expects('fileExists').returns(true);
326333
mocks.adb.expects('isAppInstalled').returns(true);
327334
mocks.helpers.expects('resetApp').once().returns("");
328335
mocks.helpers.expects('reinstallRemoteApk').once().returns("");
329336
mocks.helpers.expects('removeTempApks').once().returns(true);
330337
mocks.adb.expects('mkdir').once().returns("");
331-
await helpers.installApkRemotely(adb, localApkPath, pkg, true);
338+
await helpers.installApkRemotely(adb, opts);
332339
mocks.adb.verify();
333340
mocks.fs.verify();
334341
mocks.helpers.verify();

Diff for: test/unit/commands/context-specs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('Context', () => {
2929
describe('setContext', () => {
3030
beforeEach(() => {
3131
driver = new AndroidDriver();
32-
sandbox.stub(driver, 'getContexts', function(){ return ['CHROMIUM', 'ANOTHER']; });
32+
sandbox.stub(driver, 'getContexts', () => { return ['CHROMIUM', 'ANOTHER']; });
3333
});
3434
afterEach(() => {
3535
sandbox.restore();

0 commit comments

Comments
 (0)