New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@wdio/appium-service

Package Overview
Dependencies
Maintainers
0
Versions
403
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wdio/appium-service - npm Package Compare versions

Comparing version 9.0.0-alpha.426 to 9.0.0

240

build/index.js

@@ -1,6 +0,236 @@

/* istanbul ignore file */
import AppiumLauncher from './launcher.js';
export default class AppiumService {
// src/launcher.ts
import fs from "node:fs";
import fsp from "node:fs/promises";
import url from "node:url";
import path from "node:path";
import treeKill from "tree-kill";
import { spawn } from "node:child_process";
import logger from "@wdio/logger";
import getPort from "get-port";
import { resolve as resolve2 } from "import-meta-resolve";
import { isCloudCapability } from "@wdio/config";
import { SevereServiceError } from "webdriverio";
import { isAppiumCapability } from "@wdio/utils";
// src/utils.ts
import { basename, join, resolve } from "node:path";
import { kebabCase } from "change-case";
var FILE_EXTENSION_REGEX = /\.[0-9a-z]+$/i;
function getFilePath(filePath, defaultFilename) {
let absolutePath = resolve(filePath);
if (!FILE_EXTENSION_REGEX.test(basename(absolutePath))) {
absolutePath = join(absolutePath, defaultFilename);
}
return absolutePath;
}
export const launcher = AppiumLauncher;
export * from './types.js';
function formatCliArgs(args) {
const cliArgs = [];
for (const key in args) {
const value = args[key];
if (typeof value === "boolean" && !value || value === null) {
continue;
}
cliArgs.push(`--${kebabCase(key)}`);
if (typeof value !== "boolean") {
cliArgs.push(sanitizeCliOptionValue(value));
}
}
return cliArgs;
}
function sanitizeCliOptionValue(value) {
const valueString = typeof value === "object" ? JSON.stringify(value) : String(value);
return /\s/.test(valueString) ? `'${valueString}'` : valueString;
}
// src/launcher.ts
var log = logger("@wdio/appium-service");
var DEFAULT_APPIUM_PORT = 4723;
var DEFAULT_LOG_FILENAME = "wdio-appium.log";
var DEFAULT_CONNECTION = {
protocol: "http",
hostname: "127.0.0.1",
path: "/"
};
var APPIUM_START_TIMEOUT = 30 * 1e3;
var AppiumLauncher = class _AppiumLauncher {
constructor(_options, _capabilities, _config) {
this._options = _options;
this._capabilities = _capabilities;
this._config = _config;
this._args = {
basePath: DEFAULT_CONNECTION.path,
...this._options.args || {}
};
this._logPath = _options.logPath || this._config?.outputDir;
}
_logPath;
_appiumCliArgs = [];
_args;
_process;
_isShuttingDown = false;
async _getCommand(command) {
if (!command) {
command = "node";
this._appiumCliArgs.unshift(await _AppiumLauncher._getAppiumCommand());
}
if (process.platform === "win32") {
this._appiumCliArgs.unshift("/c", command);
command = "cmd";
}
return command;
}
/**
* update capability connection options to connect
* to Appium server
*/
_setCapabilities(port) {
if (!Array.isArray(this._capabilities)) {
for (const [, capability] of Object.entries(this._capabilities)) {
const cap = capability.capabilities || capability;
const c = cap.alwaysMatch || cap;
if (!isCloudCapability(c) && isAppiumCapability(c)) {
Object.assign(
capability,
DEFAULT_CONNECTION,
{ path: this._args.basePath, port },
{ ...capability }
);
}
}
return;
}
this._capabilities.forEach((cap) => {
const w3cCap = cap;
if (Object.values(cap).length > 0 && Object.values(cap).every((c) => typeof c === "object" && c.capabilities)) {
Object.values(cap).forEach(
(c) => {
const capability = c.capabilities.alwaysMatch || c.capabilities || c;
if (!isCloudCapability(capability) && isAppiumCapability(capability)) {
Object.assign(
c,
DEFAULT_CONNECTION,
{ path: this._args.basePath, port },
{ ...c }
);
}
}
);
} else if (!isCloudCapability(w3cCap.alwaysMatch || cap) && isAppiumCapability(w3cCap.alwaysMatch || cap)) {
Object.assign(
cap,
DEFAULT_CONNECTION,
{ path: this._args.basePath, port },
{ ...cap }
);
}
});
}
async onPrepare() {
if (Array.isArray(this._options.args)) {
throw new Error("Args should be an object");
}
this._args.port = typeof this._args.port === "number" ? this._args.port : await getPort({ port: DEFAULT_APPIUM_PORT });
this._setCapabilities(this._args.port);
this._appiumCliArgs.push(...formatCliArgs({ ...this._args }));
const command = await this._getCommand(this._options.command);
this._process = await this._startAppium(command, this._appiumCliArgs);
if (this._logPath) {
this._redirectLogStream(this._logPath);
}
}
onComplete() {
this._isShuttingDown = true;
if (this._process && this._process.pid) {
log.info("Killing entire Appium tree");
treeKill(this._process.pid, "SIGTERM", (err) => {
if (err) {
log.warn("Failed to kill process:", err);
} else {
log.info(
"Process and its children successfully terminated"
);
}
});
}
}
_startAppium(command, args, timeout = APPIUM_START_TIMEOUT) {
log.info(`Will spawn Appium process: ${command} ${args.join(" ")}`);
const process2 = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
let errorCaptured = false;
let timeoutId;
let error;
return new Promise((resolve3, reject) => {
let outputBuffer = "";
timeoutId = setTimeout(() => {
rejectOnce(new Error("Timeout: Appium did not start within expected time"));
}, timeout);
const rejectOnce = (err) => {
if (!errorCaptured) {
errorCaptured = true;
clearTimeout(timeoutId);
reject(err);
}
};
process2.stdout.on("data", (data) => {
outputBuffer += data.toString();
if (outputBuffer.includes("Appium REST http interface listener started")) {
outputBuffer = "";
log.info(`Appium started with ID: ${process2.pid}`);
clearTimeout(timeoutId);
resolve3(process2);
}
});
process2.stderr.once("data", (data) => {
error = data.toString() || "Appium exited without unknown error message";
log.error(error);
rejectOnce(new Error(error));
});
process2.once("exit", (exitCode) => {
if (this._isShuttingDown) {
return;
}
let errorMessage = `Appium exited before timeout (exit code: ${exitCode})`;
if (exitCode === 2) {
errorMessage += "\n" + (error?.toString() || "Check that you don't already have a running Appium service.");
} else if (errorCaptured) {
errorMessage += `
${error?.toString()}`;
}
if (exitCode !== 0) {
log.error(errorMessage);
}
rejectOnce(new Error(errorMessage));
});
});
}
async _redirectLogStream(logPath) {
if (!this._process) {
throw Error("No Appium process to redirect log stream");
}
const logFile = getFilePath(logPath, DEFAULT_LOG_FILENAME);
await fsp.mkdir(path.dirname(logFile), { recursive: true });
log.debug(`Appium logs written to: ${logFile}`);
const logStream = fs.createWriteStream(logFile, { flags: "w" });
this._process.stdout.pipe(logStream);
this._process.stderr.pipe(logStream);
}
static async _getAppiumCommand(command = "appium") {
try {
const entryPath = await resolve2(command, import.meta.url);
return url.fileURLToPath(entryPath);
} catch (err) {
const errorMessage = "Appium is not installed locally. Please install via e.g. `npm i --save-dev appium`.\nIf you use globally installed appium please add: `appium: { command: 'appium' }`\nto your wdio.conf.js!\n\n" + err.stack;
log.error(errorMessage);
throw new SevereServiceError(errorMessage);
}
}
};
// src/index.ts
var AppiumService = class {
};
var launcher = AppiumLauncher;
export {
AppiumService as default,
launcher
};

@@ -11,2 +11,3 @@ import type { Services, Capabilities, Options } from '@wdio/types';

private _process?;
private _isShuttingDown;
constructor(_options: AppiumServiceConfig, _capabilities: Capabilities.TestrunnerCapabilities, _config?: Options.Testrunner | undefined);

@@ -13,0 +14,0 @@ private _getCommand;

20

package.json
{
"name": "@wdio/appium-service",
"version": "9.0.0-alpha.426+d760644c4",
"version": "9.0.0",
"description": "A WebdriverIO service to start & stop Appium Server",

@@ -31,11 +31,13 @@ "author": "Morten Bjerg Gregersen <morten@mogee.dk>",

"exports": {
".": "./build/index.js",
"./package.json": "./package.json"
".": {
"import": "./build/index.js",
"types": "./build/index.d.ts"
}
},
"typeScriptVersion": "3.8.3",
"dependencies": {
"@wdio/config": "9.0.0-alpha.426+d760644c4",
"@wdio/logger": "9.0.0-alpha.426+d760644c4",
"@wdio/types": "9.0.0-alpha.426+d760644c4",
"@wdio/utils": "9.0.0-alpha.426+d760644c4",
"@wdio/config": "9.0.0",
"@wdio/logger": "9.0.0",
"@wdio/types": "9.0.0",
"@wdio/utils": "9.0.0",
"change-case": "^5.4.3",

@@ -45,3 +47,3 @@ "get-port": "^7.0.0",

"tree-kill": "^1.2.2",
"webdriverio": "9.0.0-alpha.426+d760644c4"
"webdriverio": "9.0.0"
},

@@ -51,3 +53,3 @@ "publishConfig": {

},
"gitHead": "d760644c4c6e1ef910c0bee120cb422e25dbbe06"
"gitHead": "957693463371a4cb329395dcdbce8fb0c930ab93"
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc