Skip to content

Commit 89ab7b0

Browse files
feat: start session command. (#207)
* feat: start session command. It is very useful to reuse already running server and driver. To start simply run ns-start-session [options]
1 parent 45a8ff6 commit 89ab7b0

13 files changed

+106
-21
lines changed

Diff for: bin/start-session

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env node
2+
3+
"use strict";
4+
require("../lib/helpers/start-session.js");

Diff for: bin/start-session.cmd

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@node %~dp0\start-session %*

Diff for: lib/appium-driver.d.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,13 @@ export declare class AppiumDriver {
8585
* @param text
8686
* @param waitForElement
8787
*/
88-
findElementByAutomationText(automationText: string, waitForElement?: number): Promise<any>;
88+
findElementByAutomationText(automationText: string, waitForElement?: number): Promise<UIElement>;
89+
/**
90+
* Search for element by given automationText. Searches only for exact string.
91+
* @param text
92+
* @param waitForElement
93+
*/
94+
findElementByAutomationTextIfExists(automationText: string, waitForElement?: number): Promise<any>;
8995
/**
9096
* Search for element by given automationText and waits until the element is displayed.
9197
* @param text

Diff for: lib/appium-driver.ts

+28-10
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,18 @@ export class AppiumDriver {
320320
* @param waitForElement
321321
*/
322322
public async findElementByAutomationText(automationText: string, waitForElement: number = this.defaultWaitTime) {
323+
if (this.isIOS) {
324+
return await this.findElementByAccessibilityId(`${automationText}`, waitForElement);
325+
}
326+
return await this.findElementByXPath(this._elementHelper.getXPathByText(automationText, true), waitForElement);
327+
}
328+
329+
/**
330+
* Search for element by given automationText. Searches only for exact string.
331+
* @param text
332+
* @param waitForElement
333+
*/
334+
public async findElementByAutomationTextIfExists(automationText: string, waitForElement: number = this.defaultWaitTime) {
323335
if (this.isIOS) {
324336
return await this.findElementByAccessibilityIdIfExists(`${automationText}`, waitForElement);
325337
}
@@ -334,12 +346,12 @@ export class AppiumDriver {
334346
public async waitForElement(automationText: string, waitInMilliseconds: number = this.defaultWaitTime): Promise<UIElement> {
335347
let element;
336348
try {
337-
element = await this.findElementByAutomationText(automationText, 100);
349+
element = await this.findElementByAutomationTextIfExists(automationText, 100);
338350
} catch (error) { }
339351
const startTime = Date.now();
340352
while ((!element || !(await element.isDisplayed())) && Date.now() - startTime <= waitInMilliseconds) {
341353
try {
342-
element = await this.findElementByAutomationText(automationText, 100);
354+
element = await this.findElementByAutomationTextIfExists(automationText, 100);
343355
} catch (error) { }
344356
}
345357

@@ -730,7 +742,7 @@ export class AppiumDriver {
730742
* @param time in minutes
731743
*/
732744
public async backgroundApp(minutes: number) {
733-
console.log("Sending the currently active app to the background ...");
745+
logInfo("Sending the currently active app to the background ...");
734746
await this._driver.backgroundApp(minutes);
735747
}
736748

@@ -756,20 +768,23 @@ export class AppiumDriver {
756768
}
757769

758770
public async quit() {
759-
console.log("Killing driver");
760771
if (this._recordVideoInfo && this._recordVideoInfo['videoRecordingProcess']) {
761772
this._recordVideoInfo['videoRecordingProcess'].kill("SIGINT");
762773
}
763774
try {
764775
if (!this._args.attachToDebug) {
776+
console.log("Killing driver...");
765777
await this._driver.quit();
778+
this._isAlive = false;
779+
console.log("Driver is dead!");
766780
} else {
767781
//await this._webio.detach();
768782
}
769783
} catch (error) {
784+
if (this._args.verbose) {
785+
console.dir(error);
786+
}
770787
}
771-
this._isAlive = false;
772-
console.log("Driver is dead");
773788
}
774789

775790
private static async applyAdditionalSettings(args) {
@@ -817,13 +832,16 @@ export class AppiumDriver {
817832

818833
private static configureLogging(driver, verbose) {
819834
driver.on("status", function (info) {
820-
log(info.cyan, verbose);
835+
log(info, verbose);
836+
});
837+
driver.on("quit", function (info) {
838+
console.log("QUIT: ", info);
821839
});
822840
driver.on("command", function (meth, path, data) {
823-
log(" > " + meth.yellow + path.grey + " " + (data || ""), verbose);
841+
log(" > " + meth + " " + path + " " + (data || ""), verbose);
824842
});
825843
driver.on("http", function (meth, path, data) {
826-
log(" > " + meth.magenta + path + " " + (data || "").grey, verbose);
844+
log(" > " + meth + " " + path + " " + (data || ""), verbose);
827845
});
828846
};
829847

@@ -945,4 +963,4 @@ export class AppiumDriver {
945963

946964
return new UIElement(searchResult, this._driver, this._wd, this._webio, this._args, "elementByImage", imageAsBase64);
947965
}
948-
}
966+
}

Diff for: lib/appium-server.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChildProcess, spawn } from "child_process";
1+
import { ChildProcess, spawn, execSync } from "child_process";
22
import {
33
log,
44
resolvePath,
@@ -9,7 +9,8 @@ import {
99
logWarn,
1010
logInfo,
1111
prepareApp,
12-
prepareDevice
12+
prepareDevice,
13+
stopServerCommand
1314
} from "./utils";
1415
import { INsCapabilities } from "./interfaces/ns-capabilities";
1516
import { IDeviceManager } from "./interfaces/device-manager";

Diff for: lib/helpers/start-session.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { INsCapabilities } from "../interfaces/ns-capabilities";
2+
export declare const nsCapabilities: INsCapabilities;

Diff for: lib/helpers/start-session.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { execSync } from "child_process";
2+
import { NsCapabilities } from "../ns-capabilities";
3+
import { AppiumServer } from "../appium-server";
4+
import { AppiumDriver } from "../appium-driver";
5+
import { isWin, logInfo, logError, stopServerCommand } from "../utils";
6+
import * as parser from "../parser"
7+
import { INsCapabilities } from "../interfaces/ns-capabilities";
8+
9+
export const nsCapabilities: INsCapabilities = new NsCapabilities(parser);
10+
let server: AppiumServer;
11+
const startSession = async () => {
12+
if (!isWin()) {
13+
execSync(stopServerCommand(nsCapabilities.port));
14+
console.log(stopServerCommand(nsCapabilities.port));
15+
}
16+
17+
nsCapabilities.validateArgs();
18+
nsCapabilities.appiumCaps = nsCapabilities.appiumCaps || {};
19+
nsCapabilities.appiumCaps["newCommandTimeout"] = 300;
20+
server = new AppiumServer(nsCapabilities);
21+
await server.start(nsCapabilities.port);
22+
const driver = await AppiumDriver.createAppiumDriver(nsCapabilities);
23+
const session = await driver.sessionId();
24+
logInfo(`port: ${nsCapabilities.port}`);
25+
logInfo(`session id: ${session}`);
26+
}
27+
28+
startSession().then(s => {
29+
logInfo("session started")
30+
});
31+
32+
process.once("uncaughtException", async () => {
33+
logError(`uncaughtException!`)
34+
})
35+
36+
process.once("SIGINT", async () => {
37+
if (!isWin()) {
38+
console.log(`stop server!`)
39+
execSync(stopServerCommand(nsCapabilities.port));
40+
}
41+
await server.stop();
42+
})

Diff for: lib/parser.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export declare const projectDir: string, projectBinary: string, pluginRoot: string, pluginBinary: string, port: number, verbose: boolean, appiumCapsLocation: string, testFolder: string, runType: string, isSauceLab: boolean, appPath: string, storage: string, testReports: string, devMode: boolean, ignoreDeviceController: boolean, wdaLocalPort: number, path: string, relaxedSecurity: boolean, cleanApp: boolean, attachToDebug: boolean, sessionId: string, startSession: boolean, capabilitiesName: string, imagesPath: string, startDeviceOptions: string, deviceTypeOrPlatform: string, device: any, driverConfig: any;
1+
export declare const projectDir: string, projectBinary: string, pluginRoot: string, pluginBinary: string, port: number, verbose: boolean, appiumCapsLocation: string, testFolder: string, runType: string, isSauceLab: boolean, appPath: string, storage: string, testReports: string, devMode: boolean, ignoreDeviceController: boolean, wdaLocalPort: number, path: string, relaxedSecurity: boolean, cleanApp: boolean, attachToDebug: boolean, sessionId: string, startSession: boolean, capabilitiesName: string, imagesPath: string, startDeviceOptions: string, deviceTypeOrPlatform: string, device: import("mobile-devices-controller/lib/device").IDevice, driverConfig: any;

Diff for: lib/parser.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as yargs from "yargs";
22
import { join } from "path";
3-
import { resolvePath, logError } from "./utils";
3+
import { resolvePath, logError, logWarn } from "./utils";
44
import { INsCapabilitiesArgs } from "./interfaces/ns-capabilities-args";
55

66
const config = (() => {
@@ -105,8 +105,8 @@ const config = (() => {
105105
options.devMode = true;
106106
console.log(`Option attachToDebug is set to true. Option --devMode is set true as well !`)
107107
if (!options.port) {
108-
logError("Provide appium server port started from desktop application!")
109-
process.exit(1);
108+
logWarn(`Default appium server port 4732!`);
109+
logWarn(`In order to change it use --port option!`);
110110
}
111111
}
112112

Diff for: lib/utils.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export declare const prepareApp: (args: INsCapabilities) => Promise<INsCapabilit
3939
export declare const sessionIds: (port: any) => Promise<any[]>;
4040
export declare function encodeImageToBase64(path: any): string;
4141
export declare const shouldUserMobileDevicesController: (args: INsCapabilities) => boolean;
42+
export declare const stopServerCommand: (port: any) => string;
4243
export declare function logInfo(info: any, obj?: any): void;
4344
export declare function logWarn(info: any, obj?: any): void;
4445
export declare function logError(info: any, obj?: any): void;

Diff for: lib/utils.ts

+3
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,9 @@ export const shouldUserMobileDevicesController = (args: INsCapabilities) => {
606606
return !args.isSauceLab && (new RegExp(`${useDsCS}`).test(`true`) || new RegExp(`${useMDsCS}`).test(`true`));
607607
}
608608

609+
export const stopServerCommand = (port) => {
610+
return `lsof -i tcp:${port} | grep -v grep | grep -v PID | awk '{print $2}' | xargs kill -9 || true`;
611+
}
609612

610613
export function logInfo(info, obj = undefined) {
611614
info += " " + convertObjToString(obj);

Diff for: package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"bin": {
2828
"nativescript-dev-appium": "./bin/nativescript-dev-appium",
2929
"ns-dev-appium": "./bin/nativescript-dev-appium",
30-
"ns-appium": "./bin/nativescript-dev-appium"
30+
"ns-appium": "./bin/nativescript-dev-appium",
31+
"ns-start-session": "./bin/start-session"
3132
},
3233
"dependencies": {
3334
"app-root-path": "~2.1.0",

Diff for: test/device-manager.spec.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ describe("Start device by apiLevel", async () => {
245245

246246
describe("dev-mode-options", async () => {
247247
let appiumServer: AppiumServer;
248+
const port = 8399;
248249

249250
before("start devices", async () => {
250251
await DeviceController.startDevice({ platform: Platform.ANDROID, apiLevel: "23" });
@@ -263,6 +264,8 @@ describe("dev-mode-options", async () => {
263264
const nsCaps = new NsCapabilities(<INsCapabilitiesArgs>{
264265
deviceTypeOrPlatform: Platform.IOS,
265266
appPath: iosApp,
267+
port: port,
268+
verbose: true
266269
});
267270

268271
const appiumDriver = await AppiumDriver.createAppiumDriver(nsCaps);
@@ -273,7 +276,8 @@ describe("dev-mode-options", async () => {
273276
it("test android", async () => {
274277
const nsCaps = new NsCapabilities(<INsCapabilitiesArgs>{
275278
deviceTypeOrPlatform: Platform.ANDROID,
276-
appPath: androidApp
279+
appPath: androidApp,
280+
port: port,
277281
});
278282

279283
const appiumDriver = await AppiumDriver.createAppiumDriver(nsCaps);
@@ -284,7 +288,8 @@ describe("dev-mode-options", async () => {
284288
it("test --device.platform=android", async () => {
285289
const nsCaps = new NsCapabilities(<INsCapabilitiesArgs>{
286290
device: { platform: Platform.ANDROID },
287-
appPath: androidApp
291+
appPath: androidApp,
292+
port: port
288293
});
289294

290295
const appiumDriver = await AppiumDriver.createAppiumDriver(nsCaps);
@@ -295,7 +300,8 @@ describe("dev-mode-options", async () => {
295300
it("test --device.platform=ios", async () => {
296301
const nsCaps = new NsCapabilities(<INsCapabilitiesArgs>{
297302
device: { platform: Platform.IOS },
298-
appPath: iosApp
303+
appPath: iosApp,
304+
port: port
299305
});
300306

301307
const appiumDriver = await AppiumDriver.createAppiumDriver(nsCaps);

0 commit comments

Comments
 (0)