Skip to content

Commit f1383e2

Browse files
Tsenov/device controller (#53)
* merge * fix: kill device server for windowsm * feat: introduce ignoreDeviceController * Fix ios simulator * fix: remove check for null device * merge: fix after rebase to master * update: tsconfig lib
1 parent c3f1366 commit f1383e2

17 files changed

+96
-77
lines changed

README.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ $ tns build ios
3333
The command that will run the tests should specify the targeted platform using the `runType` option as shown below. This way a capabilities will be selected from the [capabilities config file](#customCapabilities).
3434

3535
```
36-
$ npm run e2e -- --runType android23
36+
$ npm run e2e -- --runType android25
3737
```
3838

3939
or
4040

4141
```
42-
$ npm run e2e -- --runType ios-simulator10iPhone6
42+
$ npm run e2e -- --runType sim.iPhone7.iOS110
4343
```
4444

4545
Generated tests are standard [Mocha](http://mochajs.org) tests.
@@ -73,36 +73,33 @@ Thus, the same configuration can be used by both apps without duplication of fil
7373

7474
If you wish to use another location of the capapabilities file instead default ones, you can specify it with `--capsLocation` option. Remember that the path provided has to be relative to the root directory.
7575

76-
Notice that once custom capabilities are provided you will be able to pick any of them using the `--runType` option (e.g. `--runType android21`). Sample content of `appium.capabilities.json` file could be:
76+
Notice that once custom capabilities are provided you will be able to pick any of them using the `--runType` option (e.g. `--runType android25`). Sample content of `appium.capabilities.json` file could be:
7777

7878
```
7979
{
8080
"android21": {
8181
"browserName": "",
82-
"appium-version": "1.6.3",
8382
"platformName": "Android",
8483
"platformVersion": "5.0",
8584
"deviceName": "Android Emulator",
8685
"noReset": false,
8786
"app": ""
8887
8988
},
90-
"android23": {
89+
"android25": {
9190
"browserName": "",
92-
"appium-version": "1.6.5",
9391
"platformName": "Android",
94-
"platformVersion": "6.0",
92+
"platformVersion": "7.0",
9593
"deviceName": "Android Emulator",
9694
"noReset": false,
9795
"app": ""
9896
9997
},
100-
"ios-simulator10iPhone6": {
98+
"sim.iPhone7.iOS110": {
10199
"browserName": "",
102-
"appium-version": "1.6.5",
103100
"platformName": "iOS",
104101
"platformVersion": "10.0",
105-
"deviceName": "iPhone 6 Simulator",
102+
"deviceName": "iPhone 7 110",
106103
"app": ""
107104
108105
}
@@ -125,7 +122,7 @@ As you can see, the `app` property can be left an empty string which will force
125122
Examples:
126123

127124
```
128-
$ npm run e2e --runType android23 --sauceLab --appLocation demo.apk --capsLocation "/e2e-tests/config"
125+
$ npm run e2e --runType android25 --sauceLab --appLocation demo.apk --capsLocation "/e2e-tests/config"
129126
130127
```
131128

e2e/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"chai"
1212
],
1313
"lib": [
14-
"es6",
14+
"es2015",
1515
"dom"
1616
]
1717
}

index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export async function createDriver() {
7373
} else if (appiumDriver === null) {
7474
appiumDriver = await AppiumDriver.createAppiumDriver(appiumServer.port, nsCapabilities);
7575
} else if (appiumDriver !== null && !appiumDriver.isAlive) {
76-
await appiumDriver.inint();
76+
await appiumDriver.init();
7777
}
7878

7979
return appiumDriver;

lib/appium-driver.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ export class AppiumDriver {
366366

367367
driverConfig = "https://" + sauceUser + ":" + sauceKey + "@ondemand.saucelabs.com:443/wd/hub";
368368

369-
370369
args.appiumCaps.app = "sauce-storage:" + args.appPath;
371370
console.log("Using Sauce Labs. The application path is changed to: " + args.appPath);
372371
}

lib/appium-server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export class AppiumServer {
8888
shutdown(this._server, this._args.verbose);
8989
this._server.kill("SIGINT");
9090
this._server.kill("SIGINT");
91+
this._server = null;
9192
} else {
9293
this._server.kill("SIGINT");
9394
this._server.kill("SIGINT");

lib/device-controller.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export declare class DeviceController {
55
static startDevice(args: INsCapabilities): Promise<any>;
66
static stop(args: INsCapabilities): Promise<void>;
77
static kill(device: IDevice): Promise<void>;
8+
private static getDefaultDevice(args);
89
private static device(runType);
910
private static getDevicesByStatus(devices, status);
1011
}

lib/device-controller.ts

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,68 @@ import * as child_process from "child_process";
33
import { INsCapabilities } from "./ins-capabilities";
44

55
import {
6-
DeviceManager,
7-
AndroidManager,
8-
IOSManager,
96
IDevice,
7+
Device,
8+
DeviceManager,
109
Platform,
11-
Status
10+
Status,
11+
DeviceType
1212
} from "mobile-devices-controller";
1313

1414

1515
export class DeviceController {
1616
private static _emulators: Map<string, IDevice> = new Map();
1717

1818
public static async startDevice(args: INsCapabilities) {
19-
const devices = (await DeviceManager.getAllDevices(args.appiumCaps.platformName.toLowerCase(), args.appiumCaps.deviceName));
20-
if (!devices || devices === null || devices.size) {
21-
console.log("Available devices:\n", devices);
22-
throw new Error(`No such device ${args.appiumCaps.deviceName}!!!\n Check availabe emulators!!!`);
19+
if (args.isSauceLab || args.ignoreDeviceController) {
20+
return DeviceController.getDefaultDevice(args);
2321
}
2422

25-
let device: IDevice;
26-
// Should find new device
27-
if (!args.reuseDevice) {
28-
device = DeviceController.getDevicesByStatus(devices, Status.SHUTDOWN);
23+
const allDevices = (await DeviceManager.getAllDevices(args.appiumCaps.platformName.toLowerCase()));
24+
if (!allDevices || allDevices === null || allDevices.size === 0) {
25+
console.log("We couldn't find any devices. We will try to prossede to appium! Maybe avd manager is missing")
26+
console.log("Available devices:\n", allDevices);
2927
}
3028

31-
// If there is no shutdown device
32-
if (!device || device === null) {
33-
device = DeviceController.getDevicesByStatus(devices, Status.BOOTED);
29+
let searchedDevices = allDevices.get(args.appiumCaps.deviceName);
30+
if (!searchedDevices || searchedDevices.length === 0) {
31+
console.log(`No such device ${args.appiumCaps.deviceName}!!!\n Check your device name!!!`);
32+
console.log("Available devices:\n", allDevices);
3433
}
3534

36-
// If there is no booted device
37-
if (!device || device === null) {
38-
device = DeviceController.getDevicesByStatus(devices, Status.FREE);
39-
}
35+
let device: IDevice;
4036

41-
// In case reuse device is true but there weren't any booted devices. We need to fall back and boot new one.
42-
if (!device || device === null && args.reuseDevice) {
43-
device = DeviceController.getDevicesByStatus(devices, Status.SHUTDOWN);
44-
}
37+
if (searchedDevices && searchedDevices.length > 0) {
4538

46-
if (device.status === Status.SHUTDOWN) {
47-
await DeviceManager.startDevice(device);
48-
console.log("Started device: ", device);
49-
} else {
50-
console.log("Device is alredy started", device);
39+
// Should find new device
5140
if (!args.reuseDevice) {
52-
DeviceController.kill(device);
41+
device = DeviceController.getDevicesByStatus(searchedDevices, Status.SHUTDOWN);
42+
}
43+
44+
// If there is no shutdown device
45+
if (!device || device === null) {
46+
device = DeviceController.getDevicesByStatus(searchedDevices, Status.BOOTED);
47+
}
48+
49+
// In case reuse device is true but there weren't any booted devices. We need to fall back and boot new one.
50+
if (!device || device === null && args.reuseDevice) {
51+
device = DeviceController.getDevicesByStatus(searchedDevices, Status.SHUTDOWN);
52+
}
53+
54+
if (device.status === Status.SHUTDOWN) {
5355
await DeviceManager.startDevice(device);
56+
console.log("Started device: ", device);
57+
} else {
58+
console.log("Device is alredy started", device);
59+
if (!args.reuseDevice) {
60+
DeviceController.kill(device);
61+
await DeviceManager.startDevice(device);
62+
}
5463
}
5564
}
5665

57-
if (device.token && args.appiumCaps.platformName.toLowerCase() === Platform.ANDROID) {
58-
const density = AndroidManager.getPhysicalDensity(device.token);
59-
const offsetPixels = AndroidManager.getPixelsOffset(device.token);
60-
device.config = {
61-
density: density,
62-
offsetPixels: offsetPixels,
63-
};
66+
if (!device || device === null) {
67+
device = DeviceController.getDefaultDevice(args);
6468
}
6569

6670
DeviceController._emulators.set(args.runType, device);
@@ -69,7 +73,7 @@ export class DeviceController {
6973
}
7074

7175
public static async stop(args: INsCapabilities) {
72-
if (DeviceController._emulators.has(args.runType) && !args.reuseDevice) {
76+
if (DeviceController._emulators.has(args.runType) && !args.reuseDevice && !args.isSauceLab && !args.ignoreDeviceController) {
7377
const device = DeviceController._emulators.get(args.runType);
7478
await DeviceManager.kill(device);
7579
}
@@ -79,6 +83,11 @@ export class DeviceController {
7983
await DeviceManager.kill(device);
8084
}
8185

86+
87+
private static getDefaultDevice(args) {
88+
return new Device(args.appiumCaps.deviceName, args.appiumCaps.platformVersion, undefined, args.appiumCaps.platformName, undefined, undefined);
89+
}
90+
8291
private static device(runType) {
8392
return DeviceController._emulators.get(runType);
8493
}

lib/ins-capabilities.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ export interface INsCapabilities {
1717
testReports: string;
1818
reuseDevice: boolean;
1919
device: IDevice;
20+
ignoreDeviceController: boolean;
2021
}

lib/ins-capabilities.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ export interface INsCapabilities {
1717
storage: string;
1818
testReports: string;
1919
reuseDevice: boolean;
20-
device: IDevice;
20+
device:IDevice;
21+
ignoreDeviceController: boolean;
2122
}

lib/ns-capabilities.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export declare class NsCapabilities implements INsCapabilities {
1818
private _appPath;
1919
private _emulatorOptions;
2020
private _device;
21+
private _ignoreDeviceController;
2122
private exceptions;
2223
constructor();
2324
readonly projectDir: any;
@@ -35,6 +36,7 @@ export declare class NsCapabilities implements INsCapabilities {
3536
readonly runType: any;
3637
readonly isSauceLab: any;
3738
appPath: string;
39+
readonly ignoreDeviceController: boolean;
3840
device: IDevice;
3941
readonly emulatorOptions: string;
4042
private resolveAppPath();

0 commit comments

Comments
 (0)