@wdio/appium-service
Advanced tools
Comparing version 9.0.0-alpha.426 to 9.0.0
@@ -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; |
{ | ||
"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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
0
22062
12
424
+ Added@isaacs/cliui@8.0.2(transitive)
+ Added@pkgjs/parseargs@0.11.0(transitive)
+ Added@promptbook/utils@0.69.5(transitive)
+ Added@puppeteer/browsers@2.7.1(transitive)
+ Added@tootallnate/quickjs-emscripten@0.23.0(transitive)
+ Added@types/node@20.17.19(transitive)
+ Added@types/sinonjs__fake-timers@8.1.5(transitive)
+ Added@types/which@2.0.2(transitive)
+ Added@types/ws@8.5.14(transitive)
+ Added@types/yauzl@2.10.3(transitive)
+ Added@wdio/config@9.0.0(transitive)
+ Added@wdio/logger@8.38.09.0.0(transitive)
+ Added@wdio/protocols@9.0.0(transitive)
+ Added@wdio/repl@9.0.0(transitive)
+ Added@wdio/types@9.0.0(transitive)
+ Added@wdio/utils@9.0.0(transitive)
+ Added@zip.js/zip.js@2.7.57(transitive)
+ Addedabort-controller@3.0.0(transitive)
+ Addedagent-base@7.1.3(transitive)
+ Addedansi-regex@5.0.16.1.0(transitive)
+ Addedansi-styles@4.3.06.2.1(transitive)
+ Addedarchiver@7.0.1(transitive)
+ Addedarchiver-utils@5.0.2(transitive)
+ Addedaria-query@5.3.2(transitive)
+ Addedast-types@0.13.4(transitive)
+ Addedasync@3.2.6(transitive)
+ Addedb4a@1.6.7(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbare-events@2.5.4(transitive)
+ Addedbare-fs@4.0.1(transitive)
+ Addedbare-os@3.4.0(transitive)
+ Addedbare-path@3.0.0(transitive)
+ Addedbare-stream@2.6.5(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbasic-ftp@5.0.5(transitive)
+ Addedboolbase@1.0.0(transitive)
+ Addedbrace-expansion@2.0.1(transitive)
+ Addedbuffer@6.0.3(transitive)
+ Addedbuffer-crc32@0.2.131.0.0(transitive)
+ Addedchalk@4.1.25.4.1(transitive)
+ Addedcheerio@1.0.0(transitive)
+ Addedcheerio-select@2.1.0(transitive)
+ Addedcliui@8.0.1(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedcommander@9.5.0(transitive)
+ Addedcompress-commons@6.0.2(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addedcrc-32@1.2.2(transitive)
+ Addedcrc32-stream@6.0.0(transitive)
+ Addedcross-spawn@7.0.6(transitive)
+ Addedcss-select@5.1.0(transitive)
+ Addedcss-shorthand-properties@1.1.2(transitive)
+ Addedcss-value@0.0.1(transitive)
+ Addedcss-what@6.1.0(transitive)
+ Addeddata-uri-to-buffer@4.0.16.0.2(transitive)
+ Addeddebug@4.4.0(transitive)
+ Addeddecamelize@6.0.0(transitive)
+ Addeddeepmerge-ts@7.1.4(transitive)
+ Addeddegenerator@5.0.1(transitive)
+ Addeddom-serializer@2.0.0(transitive)
+ Addeddomelementtype@2.3.0(transitive)
+ Addeddomhandler@5.0.3(transitive)
+ Addeddomutils@3.2.2(transitive)
+ Addedeastasianwidth@0.2.0(transitive)
+ Addededge-paths@3.0.5(transitive)
+ Addededgedriver@5.6.1(transitive)
+ Addedemoji-regex@8.0.09.2.2(transitive)
+ Addedencoding-sniffer@0.2.0(transitive)
+ Addedend-of-stream@1.4.4(transitive)
+ Addedentities@4.5.0(transitive)
+ Addedescalade@3.2.0(transitive)
+ Addedescodegen@2.1.0(transitive)
+ Addedesprima@4.0.1(transitive)
+ Addedestraverse@5.3.0(transitive)
+ Addedesutils@2.0.3(transitive)
+ Addedevent-target-shim@5.0.1(transitive)
+ Addedevents@3.3.0(transitive)
+ Addedextract-zip@2.0.1(transitive)
+ Addedfast-deep-equal@2.0.1(transitive)
+ Addedfast-fifo@1.3.2(transitive)
+ Addedfast-xml-parser@4.5.2(transitive)
+ Addedfd-slicer@1.1.0(transitive)
+ Addedfetch-blob@3.2.0(transitive)
+ Addedforeground-child@3.3.0(transitive)
+ Addedformdata-polyfill@4.0.10(transitive)
+ Addedgeckodriver@4.5.1(transitive)
+ Addedget-caller-file@2.0.5(transitive)
+ Addedget-stream@5.2.0(transitive)
+ Addedget-uri@6.0.4(transitive)
+ Addedglob@10.4.5(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedgrapheme-splitter@1.0.4(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedhtmlfy@0.2.1(transitive)
+ Addedhtmlparser2@9.1.0(transitive)
+ Addedhttp-proxy-agent@7.0.2(transitive)
+ Addedhttps-proxy-agent@7.0.6(transitive)
+ Addediconv-lite@0.6.3(transitive)
+ Addedieee754@1.2.1(transitive)
+ Addedimmediate@3.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedip-address@9.0.5(transitive)
+ Addedis-fullwidth-code-point@3.0.0(transitive)
+ Addedis-plain-obj@4.1.0(transitive)
+ Addedis-stream@2.0.1(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisexe@2.0.03.1.1(transitive)
+ Addedjackspeak@3.4.3(transitive)
+ Addedjsbn@1.1.0(transitive)
+ Addedjszip@3.10.1(transitive)
+ Addedlazystream@1.0.1(transitive)
+ Addedlie@3.3.0(transitive)
+ Addedlocate-app@2.5.0(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedlodash.clonedeep@4.5.0(transitive)
+ Addedlodash.zip@4.2.0(transitive)
+ Addedloglevel@1.9.2(transitive)
+ Addedloglevel-plugin-prefix@0.8.4(transitive)
+ Addedlru-cache@10.4.37.18.3(transitive)
+ Addedminimatch@5.1.69.0.5(transitive)
+ Addedminipass@7.1.2(transitive)
+ Addedms@2.1.3(transitive)
+ Addednetmask@2.0.2(transitive)
+ Addednode-domexception@1.0.0(transitive)
+ Addednode-fetch@3.3.2(transitive)
+ Addednormalize-path@3.0.0(transitive)
+ Addednth-check@2.1.1(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpac-proxy-agent@7.2.0(transitive)
+ Addedpac-resolver@7.0.1(transitive)
+ Addedpackage-json-from-dist@1.0.1(transitive)
+ Addedpako@1.0.11(transitive)
+ Addedparse5@7.2.1(transitive)
+ Addedparse5-htmlparser2-tree-adapter@7.1.0(transitive)
+ Addedparse5-parser-stream@7.1.2(transitive)
+ Addedpath-key@3.1.1(transitive)
+ Addedpath-scurry@1.11.1(transitive)
+ Addedpend@1.2.0(transitive)
+ Addedprocess@0.11.10(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedprogress@2.0.3(transitive)
+ Addedproxy-agent@6.5.0(transitive)
+ Addedproxy-from-env@1.1.0(transitive)
+ Addedpump@3.0.2(transitive)
+ Addedquery-selector-shadow-dom@1.0.1(transitive)
+ Addedreadable-stream@2.3.84.7.0(transitive)
+ Addedreaddir-glob@1.1.3(transitive)
+ Addedrequire-directory@2.1.1(transitive)
+ Addedresq@1.11.0(transitive)
+ Addedrgb2hex@0.2.5(transitive)
+ Addedsafaridriver@0.1.2(transitive)
+ Addedsafe-buffer@5.1.25.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsemver@7.7.1(transitive)
+ Addedserialize-error@11.0.3(transitive)
+ Addedsetimmediate@1.0.5(transitive)
+ Addedshebang-command@2.0.0(transitive)
+ Addedshebang-regex@3.0.0(transitive)
+ Addedsignal-exit@4.1.0(transitive)
+ Addedsmart-buffer@4.2.0(transitive)
+ Addedsocks@2.8.4(transitive)
+ Addedsocks-proxy-agent@8.0.5(transitive)
+ Addedsource-map@0.6.1(transitive)
+ Addedspacetrim@0.11.59(transitive)
+ Addedsplit2@4.2.0(transitive)
+ Addedsprintf-js@1.1.3(transitive)
+ Addedstreamx@2.22.0(transitive)
+ Addedstring-width@4.2.35.1.2(transitive)
+ Addedstring_decoder@1.1.11.3.0(transitive)
+ Addedstrip-ansi@6.0.17.1.0(transitive)
+ Addedstrnum@1.0.5(transitive)
+ Addedsupports-color@7.2.0(transitive)
+ Addedtar-fs@3.0.8(transitive)
+ Addedtar-stream@3.1.7(transitive)
+ Addedtext-decoder@1.2.3(transitive)
+ Addedtslib@2.8.1(transitive)
+ Addedtype-fest@2.19.04.26.0(transitive)
+ Addedundici@6.21.1(transitive)
+ Addedundici-types@6.19.8(transitive)
+ Addedurlpattern-polyfill@10.0.0(transitive)
+ Addeduserhome@1.0.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedwait-port@1.1.0(transitive)
+ Addedweb-streams-polyfill@3.3.3(transitive)
+ Addedwebdriver@9.0.0(transitive)
+ Addedwebdriverio@9.0.0(transitive)
+ Addedwhatwg-encoding@3.1.1(transitive)
+ Addedwhatwg-mimetype@4.0.0(transitive)
+ Addedwhich@2.0.24.0.0(transitive)
+ Addedwrap-ansi@7.0.08.1.0(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedws@8.18.0(transitive)
+ Addedy18n@5.0.8(transitive)
+ Addedyargs@17.7.2(transitive)
+ Addedyargs-parser@21.1.1(transitive)
+ Addedyauzl@2.10.0(transitive)
+ Addedzip-stream@6.0.1(transitive)
Updated@wdio/config@9.0.0
Updated@wdio/logger@9.0.0
Updated@wdio/types@9.0.0
Updated@wdio/utils@9.0.0
Updatedwebdriverio@9.0.0