Skip to content

Commit 22bdabe

Browse files
refactor(device-manager): handle devices (#185)
* refactor(device-manager): handle devices * chore: bump device controller version
1 parent 8751550 commit 22bdabe

File tree

4 files changed

+75
-62
lines changed

4 files changed

+75
-62
lines changed

index.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { logInfo, logError, logWarn } from "./lib/utils";
1010
import { INsCapabilities } from "./lib/interfaces/ns-capabilities";
1111
import { INsCapabilitiesArgs } from "./lib/interfaces/ns-capabilities-args";
1212
import * as parser from "./lib/parser"
13+
import { isWin } from "mobile-devices-controller/lib/utils";
1314

1415
export { AppiumDriver } from "./lib/appium-driver";
1516
export { AppiumServer } from "./lib/appium-server";
@@ -33,21 +34,6 @@ const appiumServer = new AppiumServer(nsCapabilities);
3334
let frameComparer: FrameComparer;
3435
let appiumDriver = null;
3536

36-
const attachToExitProcessHoockup = (processToAttach, processName) => {
37-
const signals = ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
38-
'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'];
39-
if (!processToAttach) {
40-
return;
41-
}
42-
signals.forEach(function (sig) {
43-
processToAttach.once(sig, async function () {
44-
await killProcesses(sig);
45-
console.log(`Exited from ${processName}`);
46-
processToAttach.removeListener(sig, killProcesses);
47-
});
48-
});
49-
}
50-
5137
if (nsCapabilities.startSession) {
5238
startServer(nsCapabilities.port).then(s => {
5339
createDriver().then((d: AppiumDriver) => {
@@ -71,7 +57,7 @@ if (nsCapabilities.startSession) {
7157

7258
export async function startServer(port?: number, deviceManager?: IDeviceManager) {
7359
await appiumServer.start(port || nsCapabilities.port, deviceManager);
74-
await attachToExitProcessHoockup(appiumServer.server, "appium");
60+
await attachToExitProcessHookup(appiumServer.server, "appium");
7561
return appiumServer;
7662
}
7763

@@ -144,8 +130,25 @@ const killProcesses = async (code) => {
144130
if (appiumServer) {
145131
await stopServer();
146132
}
133+
process.removeAllListeners();
134+
try {
135+
if (isWin() && process) {
136+
process.exit(0);
137+
}
138+
} catch (error) { }
147139
}
148140

149-
process.once("exit", async (code) => await killProcesses(code));
150-
151-
attachToExitProcessHoockup(process, "main process");
141+
const attachToExitProcessHookup = (processToAttach, processName) => {
142+
const signals = ['exit', 'SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
143+
'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'];
144+
if (!processToAttach) {
145+
return;
146+
}
147+
signals.forEach(function (sig) {
148+
processToAttach.once(sig, async function () {
149+
await killProcesses(sig);
150+
console.log(`Exited from ${processName}`);
151+
processToAttach.removeListener(sig, killProcesses);
152+
});
153+
});
154+
}

lib/device-manager.ts

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ export class DeviceManager implements IDeviceManager {
3232
public async startDevice(args: INsCapabilities): Promise<IDevice> {
3333
args.appiumCaps.platformName = args.appiumCaps.platformName.toLowerCase();
3434
let device: IDevice = DeviceManager.getDefaultDevice(args);
35-
if (process.env["DEVICE_TOKEN"]) {
36-
device.token = process.env["DEVICE_TOKEN"];
35+
console.log("Default device: ", device);
36+
const token = process.env["DEVICE_TOKEN"] || process.env.npm_config_deviceToken;
37+
if (token) {
38+
device.token = token;
3739
device.name = process.env["DEVICE_NAME"] || device.name;
38-
const allDevices = await DeviceController.getDevices({ platform: device.platform });
39-
const foundDevice = DeviceController.filter(allDevices, { token: device.token.replace("emulator-", "") })[0];
40+
const foundDevice = await DeviceController.getDevices({ token: device.token.replace("emulator-", "") })[0];
4041
logInfo("Device: ", foundDevice);
4142
return foundDevice;
4243
}
@@ -48,62 +49,61 @@ export class DeviceManager implements IDeviceManager {
4849
return device;
4950
}
5051

51-
const allDevices = await DeviceController.getDevices({ platform: args.appiumCaps.platformName });
52-
if (!allDevices || allDevices === null || allDevices.length === 0) {
53-
logError("We couldn't find any devices. We will try to proceed to appium!")
54-
console.log("Available devices:\n", allDevices);
52+
const searchQuery = args.appiumCaps.udid ? { token: args.appiumCaps.udid } : device;
53+
54+
const foundDevices = await DeviceController.getDevices(searchQuery);
55+
if (!foundDevices || foundDevices.length === 0) {
56+
logError("We couldn't find any devices of type: ", searchQuery);
57+
logError("We will try to proceed to appium!");
58+
if (device.platform) {
59+
console.log("Available devices:\t\t\t\t", await DeviceController.getDevices({ platform: device.platform }));
60+
} else {
61+
console.log("Available devices:\t\t\t\t", await DeviceController.getDevices({}));
62+
}
5563
logWarn(`We couldn't find any devices. We will try to proceed to appium!`);
5664
if (args.appiumCaps.platformVersion.toLowerCase() === Platform.ANDROID) {
5765
const errMsg = `1. Check if ANDROID_HOME environment variable is set correctly!\n
5866
2. Check if avd manager is available!
59-
3. Check appium capabilites and provide correct device options!`;
67+
3. Check appium capabilities and provide correct device options!`;
6068
logWarn(errMsg);
6169
}
6270
args.ignoreDeviceController = true;
71+
return device;
6372
}
6473

65-
const searchObj = args.appiumCaps.udid ? { token: args.appiumCaps.udid } : { name: args.appiumCaps.deviceName, apiLevel: args.appiumCaps.platformVersion };
66-
let searchedDevices = DeviceController.filter(allDevices, searchObj);
67-
if (!searchedDevices || searchedDevices.length === 0) {
68-
logError(`No such device ${args.appiumCaps.deviceName}!!!`);
69-
logWarn("All properties like platformVersion, deviceName etc should match!");
70-
logInfo("Available devices:\t\t\t\t");
71-
console.log('', allDevices);
74+
if (args.verbose) {
75+
console.log("Found devices: ", foundDevices);
7276
}
7377

74-
if (searchedDevices && searchedDevices.length > 0) {
75-
76-
// Should find new device
77-
if (!args.reuseDevice) {
78-
device = DeviceController.filter(searchedDevices, { status: Status.SHUTDOWN })[0];
79-
}
78+
if (foundDevices && foundDevices.length > 0) {
79+
let deviceStatus = args.reuseDevice ? Status.BOOTED : Status.SHUTDOWN;
80+
device = DeviceController.filter(foundDevices, { status: deviceStatus })[0];
8081

8182
// If there is no shutdown device
82-
if (!device || device === null || !device.status) {
83-
device = DeviceController.filter(searchedDevices, { status: Status.BOOTED })[0];
83+
if (!device || !device.status) {
84+
deviceStatus = args.reuseDevice ? Status.SHUTDOWN : Status.BOOTED;
85+
device = DeviceController.filter(foundDevices, { status: deviceStatus })[0];
8486
}
8587

86-
// In case reuse device is true but there weren't any booted devices. We need to fall back and boot new one.
87-
if (!device || device === null && args.reuseDevice) {
88-
device = DeviceController.filter(searchedDevices, { status: Status.SHUTDOWN })[0];
88+
// If the device should not be reused we need to shutdown device and boot a clean instance
89+
let startDeviceOptions = args.startDeviceOptions || undefined;
90+
if (!args.reuseDevice && device.status !== Status.SHUTDOWN) {
91+
await DeviceController.kill(device);
92+
device.status = Status.SHUTDOWN;
93+
startDeviceOptions = device.type === DeviceType.EMULATOR ? "-wipe-data -no-snapshot-load -no-boot-anim -no-audio" : "";
94+
logInfo("Change appium config to fullReset: false if no restart of the device needed!");
8995
}
9096

97+
if (device.type === DeviceType.DEVICE) {
98+
logInfo("Device is connected:", device)
99+
}
91100
if (device.status === Status.SHUTDOWN) {
92-
await DeviceController.startDevice(device);
101+
await DeviceController.startDevice(device, startDeviceOptions);
93102
try {
94103
delete device.process;
95104
} catch (error) { }
96-
97-
await DeviceController.startDevice(device, args.startDeviceOptions);
105+
98106
logInfo("Started device: ", device);
99-
} else {
100-
device.type === DeviceType.DEVICE ? logInfo("Device is connected:", device) : logInfo("Device is already started", device)
101-
if (!args.reuseDevice && device.type !== DeviceType.DEVICE) {
102-
logInfo("Option --reuseDevice is set to false, the device would be shut down and restart!");
103-
logInfo("Use --reuseDevice to preserve device state!");
104-
DeviceController.kill(device);
105-
await DeviceController.startDevice(device);
106-
}
107107
}
108108
}
109109

@@ -114,7 +114,7 @@ export class DeviceManager implements IDeviceManager {
114114
DeviceManager._emulators.set(args.runType, device);
115115

116116
if (!device || !device.token) {
117-
console.error("Check appium capabilites and provide correct device options!");
117+
console.error("Check appium capabilities and provide correct device options!");
118118
process.exit(1);
119119
}
120120
return device;
@@ -152,10 +152,20 @@ export class DeviceManager implements IDeviceManager {
152152
}
153153

154154
public static getDefaultDevice(args: INsCapabilities, deviceName?: string, token?: string, type?: DeviceType, platformVersion?: number) {
155-
let device = new Device(deviceName || args.appiumCaps.deviceName, platformVersion || args.appiumCaps.platformVersion, type, args.appiumCaps.platformName.toLowerCase(), token, undefined, undefined);
156-
device.config = { "density": args.appiumCaps.density, "offsetPixels": args.appiumCaps.offsetPixels };
155+
let device: IDevice = {
156+
name: deviceName || args.appiumCaps.deviceName,
157+
type: type,
158+
platform: args.appiumCaps.platformName.toLowerCase(),
159+
token: token,
160+
apiLevel: platformVersion || args.appiumCaps.platformVersion,
161+
config: { "density": args.appiumCaps.density, "offsetPixels": args.appiumCaps.offsetPixels }
162+
}
163+
157164
delete args.appiumCaps.density;
158165
delete args.appiumCaps.offsetPixels;
166+
167+
Object.getOwnPropertyNames(device).forEach(prop => !device[prop] && delete device[prop]);
168+
159169
return device;
160170
}
161171

lib/image-helper.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export declare class ImageHelper {
1010
blockOutAreas: IRectangle[];
1111
imageOutputLimit(): ImageOptions;
1212
thresholdType(): ImageOptions;
13-
threshold(thresholdType: any): 10 | 0.01;
13+
threshold(thresholdType: any): 0.01 | 10;
1414
delta(): number;
1515
static cropImageDefault(_args: INsCapabilities): {
1616
x: number;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"frame-comparer": "^2.0.1",
4040
"glob": "^7.1.0",
4141
"inquirer": "^6.2.0",
42-
"mobile-devices-controller": "^3.0.8-3",
42+
"mobile-devices-controller": "^3.0.8-4",
4343
"wd": "~1.11.1",
4444
"webdriverio": "~4.14.0",
4545
"yargs": "~12.0.5"

0 commit comments

Comments
 (0)