Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 15fe2c8

Browse files
author
Andrey Dubov
authored
Update tests (#632)
1 parent b36a291 commit 15fe2c8

File tree

8 files changed

+491
-319
lines changed

8 files changed

+491
-319
lines changed

package-lock.json

Lines changed: 187 additions & 119 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"mocha": "^6.1.4",
4949
"mocha-junit-reporter": "^1.23.1",
5050
"q": "^1.5.1",
51-
"replace": "^1.1.0",
51+
"replace": "^1.2.0",
5252
"run-sequence": "^2.2.1",
5353
"tslint": "^5.18.0",
5454
"typescript": "^3.5.3"

test/platform.ts

Lines changed: 77 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,24 @@ export interface IPlatform {
1515
* Gets the Cordova specific platform name. (e.g. "android" for the Android platform).
1616
*/
1717
getCordovaName(): string;
18-
18+
1919
/**
2020
* Gets the server url used for testing.
2121
*/
2222
getServerUrl(): string;
23-
23+
2424
/**
2525
* Gets the root of the platform www folder used for creating update packages.
2626
*/
2727
getPlatformWwwPath(projectDirectory: string): string;
28-
28+
2929
/**
3030
* Gets an optional IEmulatorManager for platforms for which "cordova run --nobuild" rebuilds the application for this platform anyway.
3131
* IOS needs special handling here, since ios-sim touches the app every time and changes the app timestamp.
3232
* This challenges the tests since we rely on the app timestamp in our logic for finding out if the application was updated through the app store.
3333
*/
3434
getEmulatorManager(): IEmulatorManager;
35-
35+
3636
/**
3737
* Gets the default deployment key.
3838
*/
@@ -47,32 +47,32 @@ export interface IEmulatorManager {
4747
* Boots the target emulator.
4848
*/
4949
bootEmulator(restartEmulators: boolean): Q.Promise<string>;
50-
50+
5151
/**
5252
* Launches an already installed application by app id.
5353
*/
5454
launchInstalledApplication(appId: string): Q.Promise<string>;
55-
55+
5656
/**
5757
* Ends a running application given its app id.
5858
*/
5959
endRunningApplication(appId: string): Q.Promise<string>;
60-
60+
6161
/**
6262
* Restarts an already installed application by app id.
6363
*/
6464
restartApplication(appId: string): Q.Promise<string>;
65-
65+
6666
/**
6767
* Navigates away from the current app, waits for a delay (defaults to 1 second), then navigates to the specified app.
6868
*/
6969
resumeApplication(appId: string, delayBeforeResumingMs: number): Q.Promise<string>;
70-
70+
7171
/**
7272
* Prepares the emulator for a test.
7373
*/
7474
prepareEmulatorForTest(appId: string): Q.Promise<string>;
75-
75+
7676
/**
7777
* Uninstalls the app from the emulator.
7878
*/
@@ -86,7 +86,7 @@ export class Android implements IPlatform {
8686
private static instance: Android;
8787
private emulatorManager: IEmulatorManager;
8888
private serverUrl: string;
89-
89+
9090
constructor(emulatorManager: IEmulatorManager) {
9191
this.emulatorManager = emulatorManager;
9292
}
@@ -102,7 +102,7 @@ export class Android implements IPlatform {
102102
public getCordovaName(): string {
103103
return "android";
104104
}
105-
105+
106106
/**
107107
* Gets the server url used for testing.
108108
*/
@@ -112,7 +112,7 @@ export class Android implements IPlatform {
112112
}
113113

114114
public getPlatformWwwPath(projectDirectory: string): string {
115-
return path.join(projectDirectory, "platforms/android/assets/www");
115+
return path.join(projectDirectory, "platforms/android/app/src/main/assets/www");
116116
}
117117

118118
public getEmulatorManager(): IEmulatorManager {
@@ -147,7 +147,7 @@ export class IOS implements IPlatform {
147147
public getCordovaName(): string {
148148
return "ios";
149149
}
150-
150+
151151
/**
152152
* Gets the server url used for testing.
153153
*/
@@ -177,7 +177,7 @@ function bootEmulatorInternal(platformName: string, restartEmulators: boolean, t
177177
checkEmulator: () => Q.Promise<string>, startEmulator: (targetEmulator: string) => Q.Promise<string>, killEmulator: () => Q.Promise<string>): Q.Promise<string> {
178178
var deferred = Q.defer<string>();
179179
console.log("Setting up " + platformName + " emulator.");
180-
180+
181181
function onEmulatorReady(): Q.Promise<string> {
182182
console.log(platformName + " emulator is ready!");
183183
deferred.resolve(undefined);
@@ -187,7 +187,7 @@ function bootEmulatorInternal(platformName: string, restartEmulators: boolean, t
187187
// Called to check if the emulator for the platform is initialized.
188188
function checkEmulatorReady(): Q.Promise<string> {
189189
var checkDeferred = Q.defer<string>();
190-
190+
191191
console.log("Checking if " + platformName + " emulator is ready yet...");
192192
// Dummy command that succeeds if emulator is ready and fails otherwise.
193193
checkEmulator()
@@ -197,10 +197,10 @@ function bootEmulatorInternal(platformName: string, restartEmulators: boolean, t
197197
console.log(platformName + " emulator is not ready yet!");
198198
checkDeferred.reject(error);
199199
});
200-
200+
201201
return checkDeferred.promise;
202202
}
203-
203+
204204
var emulatorReadyAttempts = 0;
205205
// Loops checks to see if the emulator is ready and eventually fails after surpassing emulatorMaxReadyAttempts.
206206
function checkEmulatorReadyLooper(): Q.Promise<string> {
@@ -212,17 +212,17 @@ function bootEmulatorInternal(platformName: string, restartEmulators: boolean, t
212212
looperDeferred.resolve(undefined);
213213
}
214214
setTimeout(() => {
215-
checkEmulatorReady()
216-
.then(() => {
217-
looperDeferred.resolve(undefined);
218-
onEmulatorReady();
219-
}, () => {
220-
return checkEmulatorReadyLooper().then(() => { looperDeferred.resolve(undefined); }, () => { looperDeferred.reject(undefined); });
221-
});
222-
}, emulatorReadyCheckDelayMs);
215+
checkEmulatorReady()
216+
.then(() => {
217+
looperDeferred.resolve(undefined);
218+
onEmulatorReady();
219+
}, () => {
220+
return checkEmulatorReadyLooper().then(() => { looperDeferred.resolve(undefined); }, () => { looperDeferred.reject(undefined); });
221+
});
222+
}, emulatorReadyCheckDelayMs);
223223
return looperDeferred.promise;
224224
}
225-
225+
226226
// Starts and loops the emulator.
227227
function startEmulatorAndLoop(): Q.Promise<string> {
228228
console.log("Booting " + platformName + " emulator named " + targetEmulator + ".");
@@ -236,7 +236,7 @@ function bootEmulatorInternal(platformName: string, restartEmulators: boolean, t
236236
} else {
237237
promise = checkEmulatorReady().then(onEmulatorReady, startEmulatorAndLoop);
238238
}
239-
239+
240240
return deferred.promise;
241241
}
242242

@@ -257,20 +257,20 @@ export class IOSEmulatorManager implements IEmulatorManager {
257257
function killIOSEmulator(): Q.Promise<string> {
258258
return tu.TestUtil.getProcessOutput("killall Simulator");
259259
}
260-
260+
261261
return tu.TestUtil.readIOSEmulator()
262262
.then((iOSEmulatorName: string) => {
263263
return bootEmulatorInternal("iOS", restartEmulators, iOSEmulatorName, checkIOSEmulator, startIOSEmulator, killIOSEmulator);
264264
});
265265
}
266-
266+
267267
/**
268268
* Launches an already installed application by app id.
269269
*/
270270
launchInstalledApplication(appId: string): Q.Promise<string> {
271271
return tu.TestUtil.getProcessOutput("xcrun simctl launch booted " + appId, undefined);
272272
}
273-
273+
274274
/**
275275
* Ends a running application given its app id.
276276
*/
@@ -295,7 +295,7 @@ export class IOSEmulatorManager implements IEmulatorManager {
295295
return Q.resolve(error);
296296
});
297297
}
298-
298+
299299
/**
300300
* Restarts an already installed application by app id.
301301
*/
@@ -307,13 +307,13 @@ export class IOSEmulatorManager implements IEmulatorManager {
307307
})
308308
.then(() => this.launchInstalledApplication(appId));
309309
}
310-
310+
311311
/**
312312
* Navigates away from the current app, waits for a delay (defaults to 1 second), then navigates to the specified app.
313313
*/
314314
resumeApplication(appId: string, delayBeforeResumingMs: number = 1000): Q.Promise<string> {
315315
// open a default iOS app (for example, camera)
316-
return this.launchInstalledApplication("com.apple.camera")
316+
return this.launchInstalledApplication("com.apple.Preferences")
317317
.then<void>(() => {
318318
console.log("Waiting for " + delayBeforeResumingMs + "ms before resuming the test application.");
319319
return Q.delay(delayBeforeResumingMs);
@@ -323,14 +323,14 @@ export class IOSEmulatorManager implements IEmulatorManager {
323323
return this.launchInstalledApplication(appId);
324324
});
325325
}
326-
326+
327327
/**
328328
* Prepares the emulator for a test.
329329
*/
330330
prepareEmulatorForTest(appId: string): Q.Promise<string> {
331331
return this.endRunningApplication(appId);
332332
}
333-
333+
334334
/**
335335
* Uninstalls the app from the emulator.
336336
*/
@@ -349,30 +349,42 @@ export class AndroidEmulatorManager implements IEmulatorManager {
349349
// List all of the packages on the device.
350350
return tu.TestUtil.getProcessOutput("adb shell pm list packages");
351351
}
352+
352353
function startAndroidEmulator(androidEmulatorName: string): Q.Promise<string> {
353-
return tu.TestUtil.getProcessOutput("emulator @" + androidEmulatorName);
354+
const androidEmulatorCommand = `emulator @${androidEmulatorName}`;
355+
let osSpecificCommand = "";
356+
if (process.platform === "darwin") {
357+
osSpecificCommand = `${androidEmulatorCommand} &`;
358+
} else {
359+
osSpecificCommand = `START /B ${androidEmulatorCommand}`;
360+
}
361+
return tu.TestUtil.getProcessOutput(osSpecificCommand, { timeout: 5000 }, false);
354362
}
363+
355364
function killAndroidEmulator(): Q.Promise<string> {
356365
return tu.TestUtil.getProcessOutput("adb emu kill");
357366
}
358-
359-
return bootEmulatorInternal("Android", restartEmulators, tu.TestUtil.readAndroidEmulator(), checkAndroidEmulator, startAndroidEmulator, killAndroidEmulator);
367+
368+
return tu.TestUtil.readAndroidEmulator()
369+
.then((AndroidEmulatorName: string) => {
370+
return bootEmulatorInternal("Android", restartEmulators, AndroidEmulatorName, checkAndroidEmulator, startAndroidEmulator, killAndroidEmulator);
371+
});
360372
}
361-
373+
362374
/**
363375
* Launches an already installed application by app id.
364376
*/
365377
launchInstalledApplication(appId: string): Q.Promise<string> {
366378
return ProjectManager.ProjectManager.execChildProcess("adb shell monkey -p " + appId + " -c android.intent.category.LAUNCHER 1");
367379
}
368-
380+
369381
/**
370382
* Ends a running application given its app id.
371383
*/
372384
endRunningApplication(appId: string): Q.Promise<string> {
373385
return ProjectManager.ProjectManager.execChildProcess("adb shell am force-stop " + appId);
374386
}
375-
387+
376388
/**
377389
* Restarts an already installed application by app id.
378390
*/
@@ -383,10 +395,10 @@ export class AndroidEmulatorManager implements IEmulatorManager {
383395
return Q.delay(1000);
384396
})
385397
.then<string>(() => {
386-
return this.launchInstalledApplication(appId);
387-
});
398+
return this.launchInstalledApplication(appId);
399+
});
388400
}
389-
401+
390402
/**
391403
* Navigates away from the current app, waits for a delay (defaults to 1 second), then navigates to the specified app.
392404
*/
@@ -402,20 +414,20 @@ export class AndroidEmulatorManager implements IEmulatorManager {
402414
return this.launchInstalledApplication(appId);
403415
});
404416
}
405-
417+
406418
/**
407419
* Prepares the emulator for a test.
408420
*/
409421
prepareEmulatorForTest(appId: string): Q.Promise<string> {
410422
return this.endRunningApplication(appId)
411-
.then(() => { return ProjectManager.ProjectManager.execChildProcess("adb shell pm clear " + appId); });
423+
.then(() => { return commandWithCheckAppExistence("adb shell pm clear", appId); });
412424
}
413-
425+
414426
/**
415427
* Uninstalls the app from the emulator.
416428
*/
417429
uninstallApplication(appId: string): Q.Promise<string> {
418-
return ProjectManager.ProjectManager.execChildProcess("adb uninstall " + appId);
430+
return commandWithCheckAppExistence("adb uninstall", appId);
419431
}
420432
}
421433

@@ -441,7 +453,7 @@ export class PlatformResolver {
441453
return undefined;
442454
}
443455
}
444-
456+
445457
return platforms;
446458
}
447459

@@ -454,9 +466,22 @@ export class PlatformResolver {
454466
return this.supportedPlatforms[i];
455467
}
456468
}
457-
469+
458470
// we could not find this platform in the list of platforms, so abort
459471
console.error("Unsupported platform: " + cordovaPlatformName);
460472
return undefined;
461473
}
462-
}
474+
}
475+
476+
function commandWithCheckAppExistence(command: string, appId: string) {
477+
return ProjectManager.ProjectManager.execChildProcess("adb shell pm list packages")
478+
.then((output) => {
479+
return output.includes(appId);
480+
}).then((isAppExist) => {
481+
if (isAppExist) {
482+
return ProjectManager.ProjectManager.execChildProcess(`${command} ${appId}`).then(function () { return null; });
483+
}
484+
console.log(`Command "${command}" is skipped because the application has not yet been installed`);
485+
return null;
486+
});
487+
}

0 commit comments

Comments
 (0)