diff --git a/lib/appium-driver.d.ts b/lib/appium-driver.d.ts index 3a83987..e043d05 100644 --- a/lib/appium-driver.d.ts +++ b/lib/appium-driver.d.ts @@ -25,7 +25,7 @@ export declare class AppiumDriver { private _logPath; private _storageByDeviceName; private _storageByPlatform; - private constructor(_driver, _wd, _webio, _driverConfig, _args); + private constructor(); readonly imageHelper: ImageHelper; defaultWaitTime: number; readonly capabilities: any; diff --git a/lib/appium-driver.ts b/lib/appium-driver.ts index 4b0ffcc..4125e88 100644 --- a/lib/appium-driver.ts +++ b/lib/appium-driver.ts @@ -11,7 +11,6 @@ import { UIElement } from "./ui-element"; import { Direction } from "./direction"; import { Locator } from "./locators"; import { Platform } from "mobile-devices-controller"; -import { ServiceContext } from "./service/service-context"; import { addExt, log, @@ -470,9 +469,8 @@ export class AppiumDriver { // It looks we need it for XCTest (iOS 10+ automation) if (args.appiumCaps.platformVersion >= 10) { - let freePort = await findFreePort(10, (parseInt(args.appiumCaps["wdaLocalPort"])) || 8400, args); - console.log(" args.appiumCaps['wdaLocalPort']", freePort) - args.appiumCaps["wdaLocalPort"] = freePort; + console.log(`args.appiumCaps['wdaLocalPort']: ${args.wdaPort}`); + args.appiumCaps["wdaLocalPort"] = args.wdaPort; } } } diff --git a/lib/appium-server.d.ts b/lib/appium-server.d.ts index e497074..25251ff 100644 --- a/lib/appium-server.d.ts +++ b/lib/appium-server.d.ts @@ -16,6 +16,7 @@ export declare class AppiumServer { readonly server: child_process.ChildProcess; hasStarted: boolean; start(port: any, deviceManager?: IDeviceManager): Promise; + private startAppiumServer(logLevel); stop(): Promise<{}>; private resolveAppiumDependency(); } diff --git a/lib/appium-server.ts b/lib/appium-server.ts index 531de9f..ae83285 100644 --- a/lib/appium-server.ts +++ b/lib/appium-server.ts @@ -12,7 +12,6 @@ import { import { INsCapabilities } from "./interfaces/ns-capabilities"; import { IDeviceManager } from "./interfaces/device-manager"; import { DeviceManger } from "./device-controller"; -import { ServiceContext } from "../lib/service/service-context"; export class AppiumServer { private _server: child_process.ChildProcess; @@ -56,7 +55,7 @@ export class AppiumServer { this._hasStarted = hasStarted; } - public async start(port, deviceManager: IDeviceManager = new DeviceManger(this._args.deviceControllerServerPort)) { + public async start(port, deviceManager: IDeviceManager = new DeviceManger()) { this._deviceManager = deviceManager; if (!this._args.device) { const device = await this._deviceManager.startDevice(this._args); @@ -70,25 +69,30 @@ export class AppiumServer { this.port = port || this._args.port; let retry = false; - let response: boolean = false; + this.startAppiumServer(logLevel); + + let response = await waitForOutput(this._server, /listener started/, /Error: listen/, 60000, this._args.verbose); + let retries = 11; while (retries > 0 && !response) { retries--; + this.port += 10; this.port = (await findFreePort(100, this.port, this._args)); - this._server = child_process.spawn(this._appium, ["-p", this.port.toString(), "--log-level", logLevel], { - shell: true, - detached: false - }); + this.startAppiumServer(logLevel); response = await waitForOutput(this._server, /listener started/, /Error: listen/, 60000, this._args.verbose); - if (!response) { - this.port += 10; - } } return response; } + private startAppiumServer(logLevel) { + this._server = child_process.spawn(this._appium, ["-p", this.port.toString(), "--log-level", logLevel], { + shell: true, + detached: false + }); + } + public async stop() { await this._deviceManager.stopDevice(this._args); return new Promise((resolve, reject) => { diff --git a/lib/device-controller.d.ts b/lib/device-controller.d.ts index a5a4056..7466008 100644 --- a/lib/device-controller.d.ts +++ b/lib/device-controller.d.ts @@ -1,11 +1,9 @@ import { INsCapabilities } from "./interfaces/ns-capabilities"; import { IDeviceManager } from "./interfaces/device-manager"; -import { ServiceContext } from "./service/service-context"; import { IDevice } from "mobile-devices-controller"; export declare class DeviceManger implements IDeviceManager { - private _serveiceContext; private static _emulators; - constructor(port: any, _serveiceContext?: ServiceContext); + constructor(); startDevice(args: INsCapabilities): Promise; stopDevice(args: INsCapabilities): Promise; installApp(args: INsCapabilities): Promise; diff --git a/lib/device-controller.ts b/lib/device-controller.ts index 54c790e..3ddc10d 100644 --- a/lib/device-controller.ts +++ b/lib/device-controller.ts @@ -4,13 +4,11 @@ import { log, isWin, shutdown, - executeCommand, - findFreePort + executeCommand } from "./utils"; import * as child_process from "child_process"; import { INsCapabilities } from "./interfaces/ns-capabilities"; import { IDeviceManager } from "./interfaces/device-manager"; -import { ServiceContext } from "./service/service-context"; import { IDevice, @@ -26,10 +24,7 @@ import { export class DeviceManger implements IDeviceManager { private static _emulators: Map = new Map(); - constructor(port, private _serveiceContext: ServiceContext = undefined) { - if (!this._serveiceContext) { - this._serveiceContext = ServiceContext.createServer(port); - } + constructor() { } public async startDevice(args: INsCapabilities): Promise { @@ -46,20 +41,6 @@ export class DeviceManger implements IDeviceManager { return device; } - // Using serve to manage deivces. - if (args.useDeviceControllerServer) { - const d = await this._serveiceContext.subscribe(args.appiumCaps.deviceName, args.appiumCaps.platformName.toLowerCase(), args.appiumCaps.platformVersion, args.appiumCaps.app); - delete d['__v']; - delete d['_id'] - if (!d || !(d as IDevice)) { - console.error("", d); - throw new Error("Missing device: " + d); - } - console.log(`Device:`, d); - - return d; - } - const allDevices = (await DeviceController.getDevices({ platform: args.appiumCaps.platformName })); if (!allDevices || allDevices === null || allDevices.length === 0) { console.log("We couldn't find any devices. We will try to proceed to appium! Maybe avd manager is missing") @@ -111,27 +92,10 @@ export class DeviceManger implements IDeviceManager { public async stopDevice(args: INsCapabilities): Promise { if (process.env["DEVICE_TOKEN"]) { return; - } - if (args.useDeviceControllerServer) { - const d = await this._serveiceContext.unsubscribe(args.device.token); - if (!d) { - console.error("", d); - throw new Error("Missing device: " + d); - } - - try { - await this._serveiceContext.releasePort(args.port); - if (args.appiumCaps.wdaLocalPort) { - await this._serveiceContext.releasePort(args.appiumCaps.wdaLocalPort); - } - } catch (error) { - console.log(error); - } } else if (DeviceManger._emulators.has(args.runType) && !args.reuseDevice && !args.isSauceLab - && !args.ignoreDeviceController - && !args.useDeviceControllerServer) { + && !args.ignoreDeviceController) { const device = DeviceManger._emulators.get(args.runType); await DeviceManger.kill(device); } diff --git a/lib/interfaces/ns-capabilities.d.ts b/lib/interfaces/ns-capabilities.d.ts index d4ed002..ed7bca5 100644 --- a/lib/interfaces/ns-capabilities.d.ts +++ b/lib/interfaces/ns-capabilities.d.ts @@ -20,6 +20,5 @@ export interface INsCapabilities { reuseDevice: boolean; device: IDevice; ignoreDeviceController: boolean; - useDeviceControllerServer: boolean; - deviceControllerServerPort: number; + wdaLocalPort: number; } diff --git a/lib/interfaces/ns-capabilities.ts b/lib/interfaces/ns-capabilities.ts index c8dc57c..55e986e 100644 --- a/lib/interfaces/ns-capabilities.ts +++ b/lib/interfaces/ns-capabilities.ts @@ -21,6 +21,5 @@ export interface INsCapabilities { reuseDevice: boolean; device: IDevice; ignoreDeviceController: boolean; - useDeviceControllerServer: boolean; - deviceControllerServerPort: number; + wdaLocalPort: number; } \ No newline at end of file diff --git a/lib/ns-capabilities.d.ts b/lib/ns-capabilities.d.ts index 64fc779..29430a3 100644 --- a/lib/ns-capabilities.d.ts +++ b/lib/ns-capabilities.d.ts @@ -21,8 +21,7 @@ export declare class NsCapabilities implements INsCapabilities { private _emulatorOptions; private _device; private _ignoreDeviceController; - private _useDeviceControllerServer; - private _deviceControllerServerPort; + private _wdaLocalPort; private exceptions; constructor(); readonly projectDir: any; @@ -43,8 +42,7 @@ export declare class NsCapabilities implements INsCapabilities { readonly isSauceLab: any; appPath: string; readonly ignoreDeviceController: boolean; - readonly useDeviceControllerServer: boolean; - readonly deviceControllerServerPort: number; + readonly wdaLocalPort: number; device: IDevice; readonly emulatorOptions: string; private isAndroidPlatform(); diff --git a/lib/ns-capabilities.ts b/lib/ns-capabilities.ts index 77315e5..a6544e1 100644 --- a/lib/ns-capabilities.ts +++ b/lib/ns-capabilities.ts @@ -25,8 +25,7 @@ export class NsCapabilities implements INsCapabilities { private _emulatorOptions: string; private _device: IDevice; private _ignoreDeviceController: boolean; - private _useDeviceControllerServer: boolean; - private _deviceControllerServerPort: number; + private _wdaLocalPort: number; private exceptions: Array = new Array(); constructor() { @@ -48,8 +47,7 @@ export class NsCapabilities implements INsCapabilities { this._isIOS = !this._isAndroid; this._isSauceLab = parser.isSauceLab; this._ignoreDeviceController = parser.ignoreDeviceController; - this._useDeviceControllerServer = parser.useDeviceControllerServer; - this._deviceControllerServerPort = parser.deviceControllerServerPort; + this._wdaLocalPort = parser.wdaLocalPort; this.resolveAppPath(); this.checkMandatoryCapabiliies(); this.throwExceptions(); @@ -73,8 +71,7 @@ export class NsCapabilities implements INsCapabilities { get isSauceLab() { return this._isSauceLab; } get appPath() { return this._appPath; } get ignoreDeviceController() { return this._ignoreDeviceController; } - get useDeviceControllerServer() { return this._useDeviceControllerServer; } - get deviceControllerServerPort() { return this._deviceControllerServerPort; } + get wdaLocalPort() { return this._wdaLocalPort; } set appPath(appPath: string) { this._appPath = appPath; } get device() { return this._device; } set device(device: IDevice) { this._device = device; } diff --git a/lib/parser.d.ts b/lib/parser.d.ts index aaa91f9..a8b2251 100644 --- a/lib/parser.d.ts +++ b/lib/parser.d.ts @@ -1,2 +1,2 @@ export declare const capabilitiesName = "appium.capabilities.json"; -export declare const projectDir: any, projectBinary: any, pluginRoot: any, pluginBinary: any, port: any, verbose: any, appiumCapsLocation: any, testFolder: any, runType: any, isSauceLab: any, appPath: any, storage: any, testReports: any, reuseDevice: any, ignoreDeviceController: any, useDeviceControllerServer: any, deviceControllerServerPort: number; +export declare const projectDir: any, projectBinary: any, pluginRoot: any, pluginBinary: any, port: any, verbose: any, appiumCapsLocation: any, testFolder: any, runType: any, isSauceLab: any, appPath: any, storage: any, testReports: any, reuseDevice: any, ignoreDeviceController: any, wdaLocalPort: any; diff --git a/lib/parser.ts b/lib/parser.ts index c23cbf1..2da33fa 100644 --- a/lib/parser.ts +++ b/lib/parser.ts @@ -10,13 +10,14 @@ const config = (() => { .option("testFolder", { describe: "e2e test folder name", default: "e2e", type: "string" }) .option("appiumCapsLocation", { describe: "Capabilities", type: "string" }) .option("sauceLab", { describe: "SauceLab", default: false, type: "boolean" }) - .option("port", { alias: "p", describe: "Execution port", type: "string" }) + .option("port", { alias: "p", describe: "Appium port", type: "string" }) + .option("wdaLocalPort", { alias: "p", describe: "WDA port", type: "string" }) .option("verbose", { alias: "v", describe: "Log actions", type: "boolean" }) .option("path", { describe: "path", default: process.cwd(), type: "string" }) .option("appPath", { describe: "application path", type: "string" }) .option("storage", { describe: "Storage for images folder.", type: "string" }) .option("testReports", { describe: "Test reporting folder", type: "string" }) - .option("reuseDevice", { describe: "Reusing device if available.", type: "boolean", defualt: false }) + .option("reuseDevice", { describe: "Reusing device if available.", type: "boolean", defualt: true }) .option("ignoreDeviceController", { alias: "i-ns-device-controller", describe: "Use default appium options for running emulatos/ simulators.", type: "boolean", defualt: false }) .option("useDeviceControllerServer", { alias: "use-ns-device-controller-server", @@ -47,7 +48,8 @@ const config = (() => { projectBinary: projectBinary, pluginRoot: pluginRoot, pluginBinary: pluginBinary, - port: options.port || process.env.npm_config_port, + port: options.port || process.env.npm_config_port || process.env["APPIUM_PORT"], + wdaLocalPort: options.wdaLocalPort || process.env["WDA_LOCAL_PORT"], testFolder: options.testFolder || process.env.npm_config_testFolder || "e2e", runType: options.runType || process.env.npm_config_runType, appiumCapsLocation: options.appiumCapsLocation || join(projectDir, options.testFolder, "config", capabilitiesName), @@ -57,9 +59,7 @@ const config = (() => { storage: options.storage || process.env.npm_config_STORAGE || process.env.STORAGE, testReports: options.testReports || process.env.npm_config_TEST_REPORTS || process.env.TEST_REPORTS, reuseDevice: options.reuseDevice || process.env.npm_config_REUSE_DEVICE || process.env.REUSE_DEVICE, - ignoreDeviceController: options.ignoreDeviceController, - useDeviceControllerServer: options.useDeviceControllerServer || process.env['USE_DEVICE_CONTROLLER_SERVER'], - deviceControllerServerPort: parseInt(options.deviceControllerServerPort) || parseInt(process.env['DEVICE_CONTROLLER_SERVER_PORT']) || 8700 + ignoreDeviceController: options.ignoreDeviceController }; return config; @@ -81,6 +81,5 @@ export const { testReports, reuseDevice, ignoreDeviceController, - useDeviceControllerServer, - deviceControllerServerPort + wdaLocalPort } = config; \ No newline at end of file diff --git a/lib/service/service-context.d.ts b/lib/service/service-context.d.ts deleted file mode 100644 index 8931954..0000000 --- a/lib/service/service-context.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export declare class ServiceContext { - private _port; - private _baseUrl; - private readonly _apiVersion; - private readonly _deviceController; - private readonly _utilsController; - private static serviceContext; - constructor(_port: any, _baseUrl: any); - static createServer(port?: number, host?: string): ServiceContext; - subscribe(deviceName: any, platformName: any, platformVersion: any, info: any): Promise<{}>; - unsubscribe(token: any): Promise<{}>; - releasePort(port: any): Promise<{}>; - getFreePort(retriesCount?: number, from?: number): Promise; - getJSON(query: any): Promise<{}>; -} diff --git a/lib/service/service-context.ts b/lib/service/service-context.ts deleted file mode 100644 index 810dbd5..0000000 --- a/lib/service/service-context.ts +++ /dev/null @@ -1,66 +0,0 @@ - -import * as http from "http"; - -export class ServiceContext { - private readonly _apiVersion = "/api/v1/"; - private readonly _deviceController = `${this._apiVersion}/devices` - private readonly _utilsController = `${this._apiVersion}/utils` - private static serviceContext: ServiceContext; - - constructor(private _port, private _baseUrl) { - } - - public static createServer(port = 8700, host = "localhost") { - if (!ServiceContext.serviceContext) { - ServiceContext.serviceContext = new ServiceContext(port, host); - } - - return ServiceContext.serviceContext; - } - - public async subscribe(deviceName, platformName, platformVersion, info) { - return await this.getJSON(`${this._deviceController}/subscribe?name=${encodeURIComponent(deviceName)}&platform=${encodeURIComponent(platformName)}&apiLevel=${encodeURIComponent(platformVersion)}&info=${encodeURIComponent(info)}`); - } - - public async unsubscribe(token) { - return await this.getJSON(`${this._deviceController}/unsubscribe?token=${token}`); - } - - public async releasePort(port) { - return await this.getJSON(`${this._utilsController}/release-port?port=${port}`); - } - - public async getFreePort(retriesCount = 30, from = 8300): Promise { - return await this.getJSON(`${this._utilsController}/free-port?retriesCount=${retriesCount}&from=${from}`) + ""; - } - - public getJSON(query) { - return new Promise((resolve, reject) => { - http.get( - { - host: this._baseUrl, - port: this._port, - path: query, - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'Connection': 'keep-alive' - } - }, (resp) => { - let data = ''; - resp.on('data', (chunk) => { - console.log(data); - data += chunk; - }); - - resp.on('end', () => { - resolve(JSON.parse(data)); - }); - - }).on("error", (err) => { - console.log("", err); - reject("Error: " + err.message); - }); - }); - } -} \ No newline at end of file diff --git a/lib/utils.ts b/lib/utils.ts index a61fb7f..16cd4ba 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -6,7 +6,6 @@ import * as glob from "glob"; import { INsCapabilities } from "./interfaces/ns-capabilities"; import { Point } from "./point"; import { Direction } from "./direction"; -import { ServiceContext } from "./service/service-context"; export function resolve(mainPath, ...args) { if (!path.isAbsolute(mainPath)) { @@ -418,14 +417,11 @@ export const isPortAvailable = (port) => { export const findFreePort = async (retries: number = 10, port: number = 3000, args: INsCapabilities) => { let p: number = port; - if (args.useDeviceControllerServer) { - p = parseInt(await ServiceContext.createServer(args.deviceControllerServerPort).getFreePort(100, port)); - } else { - while (!(await isPortAvailable(p)) && retries > 0) { - p += 10; - retries--; - } + while (!(await isPortAvailable(p)) && retries > 0) { + p += 10; + retries--; } + return p; } function resolveSauceLabAppName(appName: string) {