@qawolf/cli 1.7.2 → 1.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +461 -298
- package/package.json +1 -2
package/dist/cli.js
CHANGED
|
@@ -8514,7 +8514,7 @@ var require_BufferList = __commonJS((exports, module) => {
|
|
|
8514
8514
|
this.head = this.tail = null;
|
|
8515
8515
|
this.length = 0;
|
|
8516
8516
|
};
|
|
8517
|
-
BufferList.prototype.join = function
|
|
8517
|
+
BufferList.prototype.join = function join35(s3) {
|
|
8518
8518
|
if (this.length === 0)
|
|
8519
8519
|
return "";
|
|
8520
8520
|
var p3 = this.head;
|
|
@@ -23070,7 +23070,7 @@ var require_BufferList2 = __commonJS((exports, module) => {
|
|
|
23070
23070
|
this.head = this.tail = null;
|
|
23071
23071
|
this.length = 0;
|
|
23072
23072
|
};
|
|
23073
|
-
BufferList.prototype.join = function
|
|
23073
|
+
BufferList.prototype.join = function join35(s3) {
|
|
23074
23074
|
if (this.length === 0)
|
|
23075
23075
|
return "";
|
|
23076
23076
|
var p3 = this.head;
|
|
@@ -144620,19 +144620,19 @@ async function takeScreenshotBidi(filepath, options) {
|
|
|
144620
144620
|
type: imageFormat,
|
|
144621
144621
|
quality
|
|
144622
144622
|
};
|
|
144623
|
-
const
|
|
144623
|
+
const clip3 = options?.clip ? {
|
|
144624
144624
|
type: "box",
|
|
144625
144625
|
x: options.clip.x,
|
|
144626
144626
|
y: options.clip.y,
|
|
144627
144627
|
width: options.clip.width,
|
|
144628
144628
|
height: options.clip.height
|
|
144629
144629
|
} : undefined;
|
|
144630
|
-
if (
|
|
144631
|
-
if (typeof
|
|
144630
|
+
if (clip3) {
|
|
144631
|
+
if (typeof clip3.x !== "number" || typeof clip3.y !== "number" || typeof clip3.width !== "number" || typeof clip3.height !== "number") {
|
|
144632
144632
|
throw new Error("Invalid clip, use an object with x, y, width and height properties");
|
|
144633
144633
|
}
|
|
144634
144634
|
}
|
|
144635
|
-
const { data: data2 } = contextManager.findParentContext(context, tree.contexts) ? await browser.$("html").getElement().then((el) => this.takeElementScreenshot(el.elementId).then((data22) => ({ data: data22 }))) : await this.browsingContextCaptureScreenshot({ context, origin, format, clip:
|
|
144635
|
+
const { data: data2 } = contextManager.findParentContext(context, tree.contexts) ? await browser.$("html").getElement().then((el) => this.takeElementScreenshot(el.elementId).then((data22) => ({ data: data22 }))) : await this.browsingContextCaptureScreenshot({ context, origin, format, clip: clip3 });
|
|
144636
144636
|
return data2;
|
|
144637
144637
|
}
|
|
144638
144638
|
async function saveElementScreenshot(filepath) {
|
|
@@ -155283,7 +155283,8 @@ var doctorMessages = {
|
|
|
155283
155283
|
playwright: {
|
|
155284
155284
|
notFound: (path) => toolNotInstalled("Playwright", path),
|
|
155285
155285
|
launchFailed: "Could not launch Playwright. Try reinstalling the qawolf CLI.",
|
|
155286
|
-
versionUnparseable: "Could not parse playwright version output"
|
|
155286
|
+
versionUnparseable: "Could not parse playwright version output",
|
|
155287
|
+
versionMismatch: (installed, pinned) => `Playwright ${installed} is installed but the flow runtime requires ${pinned}; local runs will fail to launch browsers. Run \`qawolf install\` to repair the runtime dependencies.`
|
|
155287
155288
|
},
|
|
155288
155289
|
appium: {
|
|
155289
155290
|
notFound: (path) => toolNotInstalled("Appium", path),
|
|
@@ -155395,11 +155396,20 @@ var initMessages = {
|
|
|
155395
155396
|
outro: "Run `qawolf auth login`, then `qawolf flows pull`, then `qawolf flows run`.",
|
|
155396
155397
|
createPackageJsonPrompt: "Create package.json (required to run flows)?",
|
|
155397
155398
|
skippedCreatingPackageJson: "Skipped package.json",
|
|
155398
|
-
|
|
155399
|
+
skippedUpdatingPackageJson: "Skipped updating package.json",
|
|
155399
155400
|
createdPackageJson: "Created package.json",
|
|
155400
|
-
packageJsonInvalidJson: "package.json
|
|
155401
|
-
|
|
155402
|
-
|
|
155401
|
+
packageJsonInvalidJson: "`package.json` contains invalid JSON. Correct the JSON syntax, then run `qawolf init` again.",
|
|
155402
|
+
packageJsonNotAnObject: "`package.json` must contain a JSON object. Update it, then run `qawolf init` again.",
|
|
155403
|
+
packageJsonMalformedSection: (field) => `The \`${field}\` field in \`package.json\` must be a JSON object. Update it, then run \`qawolf init\` again.`,
|
|
155404
|
+
packageJsonHasTestE2e: "package.json already has `test:e2e` — leaving it as is",
|
|
155405
|
+
packageJsonUpToDate: "package.json already configured — nothing to update",
|
|
155406
|
+
typeChanged: (from) => `Changed "type" from "${from}" to "module" — .js files in this package now load as ES modules.`,
|
|
155407
|
+
pkgChanges: {
|
|
155408
|
+
script: "add `test:e2e` script",
|
|
155409
|
+
type: 'set "type": "module"',
|
|
155410
|
+
flowsDep: "add @qawolf/flows dependency"
|
|
155411
|
+
},
|
|
155412
|
+
updatePackageJsonPrompt: (changes) => `Update package.json (${changes.join(", ")})?`,
|
|
155403
155413
|
updatedPackageJson: "Updated package.json",
|
|
155404
155414
|
overwritePrompt: (relPath) => `Overwrite ${relPath}?`,
|
|
155405
155415
|
skippedFile: (relPath) => `Skipped ${relPath}`,
|
|
@@ -170184,49 +170194,86 @@ function createLoggingSystem(opts) {
|
|
|
170184
170194
|
};
|
|
170185
170195
|
}
|
|
170186
170196
|
|
|
170197
|
+
// src/shell/platform/parseErrorBody.ts
|
|
170198
|
+
var defaultMaxLength = 1024;
|
|
170199
|
+
function asRecord(value) {
|
|
170200
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
170201
|
+
}
|
|
170202
|
+
function asString(value) {
|
|
170203
|
+
return typeof value === "string" ? value : undefined;
|
|
170204
|
+
}
|
|
170205
|
+
function extractMessage(parsed) {
|
|
170206
|
+
const root = asRecord(parsed);
|
|
170207
|
+
if (!root)
|
|
170208
|
+
return;
|
|
170209
|
+
const flat = asString(root["error"]);
|
|
170210
|
+
if (flat !== undefined)
|
|
170211
|
+
return flat;
|
|
170212
|
+
const error51 = asRecord(root["error"]);
|
|
170213
|
+
if (!error51)
|
|
170214
|
+
return;
|
|
170215
|
+
const json2 = asRecord(error51["json"]);
|
|
170216
|
+
return asString(json2?.["message"]) ?? asString(error51["message"]);
|
|
170217
|
+
}
|
|
170218
|
+
function parseErrorBody(body, maxLength = defaultMaxLength) {
|
|
170219
|
+
if (!body)
|
|
170220
|
+
return "";
|
|
170221
|
+
let parsed;
|
|
170222
|
+
try {
|
|
170223
|
+
parsed = JSON.parse(body);
|
|
170224
|
+
} catch {
|
|
170225
|
+
return "";
|
|
170226
|
+
}
|
|
170227
|
+
const message = extractMessage(parsed)?.trim();
|
|
170228
|
+
if (!message)
|
|
170229
|
+
return "";
|
|
170230
|
+
return clip(message, maxLength);
|
|
170231
|
+
}
|
|
170232
|
+
function clip(message, maxLength) {
|
|
170233
|
+
if (message.length <= maxLength)
|
|
170234
|
+
return message;
|
|
170235
|
+
return maxLength < 1 ? "" : `${message.slice(0, maxLength - 1)}…`;
|
|
170236
|
+
}
|
|
170237
|
+
|
|
170187
170238
|
// src/shell/platform/describeErrors.ts
|
|
170188
170239
|
var m = authMessages.errors;
|
|
170240
|
+
var inlineReasonMaxLength = 200;
|
|
170189
170241
|
function describeIdentityError(err) {
|
|
170190
170242
|
if (err.kind === "http") {
|
|
170191
170243
|
if (err.status === 401 || err.status === 403) {
|
|
170192
|
-
return m.identity.invalidOrUnauthorized;
|
|
170244
|
+
return { error: m.identity.invalidOrUnauthorized };
|
|
170193
170245
|
}
|
|
170194
|
-
return
|
|
170246
|
+
return {
|
|
170247
|
+
error: m.identity.couldNotVerify(parseErrorBody(err.body, inlineReasonMaxLength), err.status)
|
|
170248
|
+
};
|
|
170195
170249
|
}
|
|
170196
170250
|
if (err.kind === "network") {
|
|
170197
|
-
return m.identity.couldNotVerifyNetwork(err.cause.message);
|
|
170251
|
+
return { error: m.identity.couldNotVerifyNetwork(err.cause.message) };
|
|
170198
170252
|
}
|
|
170199
|
-
if (err.kind === "timeout")
|
|
170200
|
-
return m.identity.timedOut(err.timeoutMs);
|
|
170201
|
-
|
|
170202
|
-
}
|
|
170203
|
-
function parseErrorBody(body) {
|
|
170204
|
-
if (!body)
|
|
170205
|
-
return "";
|
|
170206
|
-
try {
|
|
170207
|
-
const parsed = JSON.parse(body);
|
|
170208
|
-
if (typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "string") {
|
|
170209
|
-
return parsed.error;
|
|
170210
|
-
}
|
|
170211
|
-
} catch {}
|
|
170212
|
-
return "";
|
|
170253
|
+
if (err.kind === "timeout") {
|
|
170254
|
+
return { error: m.identity.timedOut(err.timeoutMs) };
|
|
170255
|
+
}
|
|
170256
|
+
return { error: m.identity.unexpectedFormat };
|
|
170213
170257
|
}
|
|
170214
170258
|
function describeRequestError(err, baseUrl, noun) {
|
|
170215
170259
|
if (err.kind === "http") {
|
|
170260
|
+
const reason = parseErrorBody(err.body);
|
|
170261
|
+
const body = reason ? { errorBody: reason } : {};
|
|
170216
170262
|
if (err.status === 401)
|
|
170217
|
-
return m.request.rejected401(noun);
|
|
170263
|
+
return { error: m.request.rejected401(noun), ...body };
|
|
170218
170264
|
if (err.status === 403)
|
|
170219
|
-
return m.request.rejected403(noun);
|
|
170265
|
+
return { error: m.request.rejected403(noun), ...body };
|
|
170220
170266
|
if (err.status === 404)
|
|
170221
|
-
return m.request.notFound404(noun);
|
|
170222
|
-
return m.request.failedWithStatus(err.status, noun);
|
|
170267
|
+
return { error: m.request.notFound404(noun), ...body };
|
|
170268
|
+
return { error: m.request.failedWithStatus(err.status, noun), ...body };
|
|
170223
170269
|
}
|
|
170224
170270
|
if (err.kind === "network") {
|
|
170225
|
-
return m.request.networkUnreachable(baseUrl, noun);
|
|
170271
|
+
return { error: m.request.networkUnreachable(baseUrl, noun) };
|
|
170226
170272
|
}
|
|
170227
|
-
if (err.kind === "timeout")
|
|
170228
|
-
return m.request.timedOut(err.timeoutMs, noun);
|
|
170229
|
-
|
|
170273
|
+
if (err.kind === "timeout") {
|
|
170274
|
+
return { error: m.request.timedOut(err.timeoutMs, noun) };
|
|
170275
|
+
}
|
|
170276
|
+
return { error: m.request.unexpectedResponse(noun) };
|
|
170230
170277
|
}
|
|
170231
170278
|
function describeBundleDownloadError(err) {
|
|
170232
170279
|
if (err.kind === "http") {
|
|
@@ -170261,6 +170308,9 @@ import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
|
170261
170308
|
var sleep = (ms) => setTimeout2(ms);
|
|
170262
170309
|
|
|
170263
170310
|
// src/shell/platform/requestWithRetry.ts
|
|
170311
|
+
function failureFields(failure) {
|
|
170312
|
+
return failure.errorBody ? { error: failure.error, errorBody: failure.errorBody } : { error: failure.error };
|
|
170313
|
+
}
|
|
170264
170314
|
async function requestWithRetry(args) {
|
|
170265
170315
|
const sleep2 = args.sleep ?? sleep;
|
|
170266
170316
|
for (let attempt = 0;; attempt++) {
|
|
@@ -170270,7 +170320,7 @@ async function requestWithRetry(args) {
|
|
|
170270
170320
|
const backoff = args.backoffMs[attempt];
|
|
170271
170321
|
const retryable = result.error.kind === "network" || result.error.kind === "timeout";
|
|
170272
170322
|
if (backoff === undefined || !retryable) {
|
|
170273
|
-
return { ok: false,
|
|
170323
|
+
return { ok: false, ...args.describe(result.error) };
|
|
170274
170324
|
}
|
|
170275
170325
|
await sleep2(backoff);
|
|
170276
170326
|
}
|
|
@@ -171175,15 +171225,15 @@ function createTrpcClient(apiKey, deps) {
|
|
|
171175
171225
|
}
|
|
171176
171226
|
};
|
|
171177
171227
|
}
|
|
171178
|
-
function
|
|
171228
|
+
function clip2(text) {
|
|
171179
171229
|
return text.length > 200 ? text.slice(0, 200) + "…" : text;
|
|
171180
171230
|
}
|
|
171181
171231
|
function summarize(error51) {
|
|
171182
171232
|
if (error51.kind === "http")
|
|
171183
|
-
return `${error51.status} ${
|
|
171233
|
+
return `${error51.status} ${clip2(error51.body)}`;
|
|
171184
171234
|
if (error51.kind === "timeout")
|
|
171185
171235
|
return `timed out after ${error51.timeoutMs}ms`;
|
|
171186
|
-
return
|
|
171236
|
+
return clip2(error51.cause.message);
|
|
171187
171237
|
}
|
|
171188
171238
|
|
|
171189
171239
|
// src/shell/platform/downloadBundle.ts
|
|
@@ -174616,7 +174666,7 @@ function startUpdateCheck(deps) {
|
|
|
174616
174666
|
// package.json
|
|
174617
174667
|
var package_default = {
|
|
174618
174668
|
name: "@qawolf/cli",
|
|
174619
|
-
version: "1.7.
|
|
174669
|
+
version: "1.7.4",
|
|
174620
174670
|
description: "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
174621
174671
|
keywords: [
|
|
174622
174672
|
"automation",
|
|
@@ -174676,7 +174726,6 @@ var package_default = {
|
|
|
174676
174726
|
"@clack/prompts": "1.5.1",
|
|
174677
174727
|
"@napi-rs/keyring": "1.3.0",
|
|
174678
174728
|
"@oxc-node/core": "0.1.0",
|
|
174679
|
-
"@playwright/test": "1.62.0",
|
|
174680
174729
|
"@qawolf/api-contracts": "0.22.0",
|
|
174681
174730
|
"@qawolf/emails": "1.1.1",
|
|
174682
174731
|
"@qawolf/flow-targets": "1.0.0",
|
|
@@ -174770,7 +174819,7 @@ function withContext(signals, fn) {
|
|
|
174770
174819
|
try {
|
|
174771
174820
|
const result = await fn(ctx);
|
|
174772
174821
|
if (result !== undefined) {
|
|
174773
|
-
ctx.ui.error(result.error);
|
|
174822
|
+
ctx.ui.error(result.error, result.errorBody);
|
|
174774
174823
|
process.exitCode = result.exitCode ?? 1;
|
|
174775
174824
|
}
|
|
174776
174825
|
} catch (err) {
|
|
@@ -174803,7 +174852,7 @@ function withAuthContext(signals, fn, deps = {}) {
|
|
|
174803
174852
|
apiKeySource: resolved.source
|
|
174804
174853
|
});
|
|
174805
174854
|
if (result !== undefined) {
|
|
174806
|
-
ctx.ui.error(result.error);
|
|
174855
|
+
ctx.ui.error(result.error, result.errorBody);
|
|
174807
174856
|
process.exitCode = result.exitCode ?? 1;
|
|
174808
174857
|
}
|
|
174809
174858
|
} catch (err) {
|
|
@@ -175047,9 +175096,6 @@ function nodeModulesBinCandidates(envDir, name, platform) {
|
|
|
175047
175096
|
function appiumCliCandidates(envDir, platform) {
|
|
175048
175097
|
return nodeModulesBinCandidates(envDir, "appium", platform);
|
|
175049
175098
|
}
|
|
175050
|
-
function playwrightCliCandidates(envDir, platform) {
|
|
175051
|
-
return nodeModulesBinCandidates(envDir, "playwright", platform);
|
|
175052
|
-
}
|
|
175053
175099
|
|
|
175054
175100
|
// src/domains/doctor/checks/androidAppium.ts
|
|
175055
175101
|
function firstLine(result) {
|
|
@@ -175412,19 +175458,48 @@ async function checkNpmRegistry(deps) {
|
|
|
175412
175458
|
return { name: "npm-registry", status: "pass" };
|
|
175413
175459
|
}
|
|
175414
175460
|
|
|
175461
|
+
// src/core/playwrightCli.ts
|
|
175462
|
+
import { join as join13 } from "node:path";
|
|
175463
|
+
function playwrightCliJsPath(envDir) {
|
|
175464
|
+
return join13(envDir, "node_modules", "playwright", "cli.js");
|
|
175465
|
+
}
|
|
175466
|
+
function playwrightCliInvocation(args) {
|
|
175467
|
+
return {
|
|
175468
|
+
cmd: args.execPath,
|
|
175469
|
+
args: [playwrightCliJsPath(args.envDir), ...args.cliArgs],
|
|
175470
|
+
env: { BUN_BE_BUN: "1" }
|
|
175471
|
+
};
|
|
175472
|
+
}
|
|
175473
|
+
|
|
175474
|
+
// src/generated/dependencyVersions.ts
|
|
175475
|
+
var flowsVersion = "0.1.4";
|
|
175476
|
+
var playwrightVersion = "1.62.0";
|
|
175477
|
+
var emailsVersion = "1.1.1";
|
|
175478
|
+
var testkitVersion = "1.1.1";
|
|
175479
|
+
var appiumVersion = "2.11.3";
|
|
175480
|
+
var appiumXcuitestDriverVersion = "9.10.5";
|
|
175481
|
+
var appiumUiautomator2DriverVersion = "3.7.0";
|
|
175482
|
+
var expectWebdriverioVersion = "5.6.5";
|
|
175483
|
+
|
|
175415
175484
|
// src/domains/doctor/checks/playwright.ts
|
|
175416
175485
|
async function checkPlaywright(deps) {
|
|
175417
|
-
const
|
|
175418
|
-
const
|
|
175419
|
-
if (
|
|
175486
|
+
const { envDir } = deps;
|
|
175487
|
+
const cliJsPath = envDir === undefined ? undefined : playwrightCliJsPath(envDir);
|
|
175488
|
+
if (envDir === undefined || cliJsPath === undefined || !deps.checkExists(cliJsPath)) {
|
|
175420
175489
|
return {
|
|
175421
175490
|
name: "playwright",
|
|
175422
175491
|
status: "fail",
|
|
175423
|
-
detail: doctorMessages.playwright.notFound(
|
|
175492
|
+
detail: doctorMessages.playwright.notFound(cliJsPath)
|
|
175424
175493
|
};
|
|
175425
175494
|
}
|
|
175426
|
-
const
|
|
175427
|
-
|
|
175495
|
+
const invocation = playwrightCliInvocation({
|
|
175496
|
+
envDir,
|
|
175497
|
+
execPath: deps.execPath,
|
|
175498
|
+
cliArgs: ["--version"]
|
|
175499
|
+
});
|
|
175500
|
+
const result = await deps.spawn(invocation.cmd, invocation.args, {
|
|
175501
|
+
platform: deps.platform,
|
|
175502
|
+
env: invocation.env
|
|
175428
175503
|
});
|
|
175429
175504
|
if (result.exitCode < 0) {
|
|
175430
175505
|
return {
|
|
@@ -175446,6 +175521,14 @@ async function checkPlaywright(deps) {
|
|
|
175446
175521
|
detail: doctorMessages.playwright.versionUnparseable
|
|
175447
175522
|
};
|
|
175448
175523
|
}
|
|
175524
|
+
if (version2 !== playwrightVersion) {
|
|
175525
|
+
return {
|
|
175526
|
+
name: "playwright",
|
|
175527
|
+
status: "fail",
|
|
175528
|
+
version: version2,
|
|
175529
|
+
detail: doctorMessages.playwright.versionMismatch(version2, playwrightVersion)
|
|
175530
|
+
};
|
|
175531
|
+
}
|
|
175449
175532
|
return { name: "playwright", status: "pass", version: version2 };
|
|
175450
175533
|
}
|
|
175451
175534
|
|
|
@@ -175466,6 +175549,7 @@ async function runChecks(deps) {
|
|
|
175466
175549
|
}),
|
|
175467
175550
|
checkPlaywright({
|
|
175468
175551
|
spawn: deps.spawn,
|
|
175552
|
+
execPath: deps.execPath,
|
|
175469
175553
|
envDir: deps.envDir,
|
|
175470
175554
|
platform: deps.platform,
|
|
175471
175555
|
checkExists: deps.checkExists
|
|
@@ -175525,11 +175609,11 @@ function renderResults(ui, results) {
|
|
|
175525
175609
|
}
|
|
175526
175610
|
|
|
175527
175611
|
// src/domains/flows/ensureDeps.ts
|
|
175528
|
-
import { dirname as dirname4, join as
|
|
175612
|
+
import { dirname as dirname4, join as join14 } from "node:path";
|
|
175529
175613
|
function findEnvDir(flowPath, fs2) {
|
|
175530
175614
|
let dir = dirname4(flowPath);
|
|
175531
175615
|
while (true) {
|
|
175532
|
-
if (fs2.existsSync(
|
|
175616
|
+
if (fs2.existsSync(join14(dir, "package.json")))
|
|
175533
175617
|
return dir;
|
|
175534
175618
|
const parent = dirname4(dir);
|
|
175535
175619
|
if (parent === dir)
|
|
@@ -175555,7 +175639,7 @@ function resolveProjectDirSafe(files, fs2) {
|
|
|
175555
175639
|
}
|
|
175556
175640
|
|
|
175557
175641
|
// src/domains/flows/expand.ts
|
|
175558
|
-
import { join as
|
|
175642
|
+
import { join as join15, resolve as resolve3 } from "node:path";
|
|
175559
175643
|
|
|
175560
175644
|
// node_modules/tinyglobby/dist/index.mjs
|
|
175561
175645
|
import { readdir, readdirSync, realpath, realpathSync, stat, statSync } from "fs";
|
|
@@ -176446,11 +176530,11 @@ function makePeekFlowMeta(fs2) {
|
|
|
176446
176530
|
};
|
|
176447
176531
|
}
|
|
176448
176532
|
async function resolveGlobRoots(cwd, fs2) {
|
|
176449
|
-
const qawolfPath =
|
|
176533
|
+
const qawolfPath = join15(cwd, ".qawolf");
|
|
176450
176534
|
let envDirs = [];
|
|
176451
176535
|
try {
|
|
176452
176536
|
const entries = await fs2.readdirWithTypes(qawolfPath);
|
|
176453
|
-
envDirs = entries.filter((e) => e.isDirectory()).map((e) =>
|
|
176537
|
+
envDirs = entries.filter((e) => e.isDirectory()).map((e) => join15(qawolfPath, e.name));
|
|
176454
176538
|
} catch {}
|
|
176455
176539
|
return [cwd, ...envDirs];
|
|
176456
176540
|
}
|
|
@@ -176475,21 +176559,11 @@ async function expandPatterns(patterns, cwd, logger, fs2) {
|
|
|
176475
176559
|
}
|
|
176476
176560
|
|
|
176477
176561
|
// src/domains/runtimeEnv/clearRuntimeEnv.ts
|
|
176478
|
-
import { join as
|
|
176562
|
+
import { join as join17 } from "node:path";
|
|
176479
176563
|
|
|
176480
176564
|
// src/domains/runtimeEnv/managedEnvDir.ts
|
|
176481
176565
|
import { createHash } from "node:crypto";
|
|
176482
|
-
import { join as
|
|
176483
|
-
|
|
176484
|
-
// src/generated/dependencyVersions.ts
|
|
176485
|
-
var flowsVersion = "0.1.4";
|
|
176486
|
-
var playwrightVersion = "1.62.0";
|
|
176487
|
-
var emailsVersion = "1.1.1";
|
|
176488
|
-
var testkitVersion = "1.1.1";
|
|
176489
|
-
var appiumVersion = "2.11.3";
|
|
176490
|
-
var appiumXcuitestDriverVersion = "9.10.5";
|
|
176491
|
-
var appiumUiautomator2DriverVersion = "3.7.0";
|
|
176492
|
-
var expectWebdriverioVersion = "5.6.5";
|
|
176566
|
+
import { join as join16, resolve as resolve4 } from "node:path";
|
|
176493
176567
|
|
|
176494
176568
|
// src/domains/runtimeEnv/pinnedPackages.ts
|
|
176495
176569
|
var pinnedPackages = [
|
|
@@ -176522,19 +176596,19 @@ function managedEnvBaseDir() {
|
|
|
176522
176596
|
const override = process.env["QAWOLF_RUNTIME_DIR"]?.trim();
|
|
176523
176597
|
if (override)
|
|
176524
176598
|
return resolve4(override);
|
|
176525
|
-
return
|
|
176599
|
+
return join16(getDataDir(), "runtime");
|
|
176526
176600
|
}
|
|
176527
176601
|
function runStagingRoot() {
|
|
176528
176602
|
return `${managedEnvBaseDir()}-runs`;
|
|
176529
176603
|
}
|
|
176530
176604
|
function managedEnvDir() {
|
|
176531
|
-
return
|
|
176605
|
+
return join16(managedEnvBaseDir(), managedEnvHash());
|
|
176532
176606
|
}
|
|
176533
176607
|
async function scaffoldManagedEnv(dir, fs2) {
|
|
176534
176608
|
await fs2.mkdir(dir, { recursive: true });
|
|
176535
176609
|
const dependencies = Object.fromEntries(pinnedPackages.map(({ name, version: version2 }) => [name, version2]));
|
|
176536
|
-
await fs2.writeFile(
|
|
176537
|
-
await fs2.writeFile(
|
|
176610
|
+
await fs2.writeFile(join16(dir, "package.json"), JSON.stringify({ name: "qawolf-runtime", private: true, dependencies }, undefined, 2));
|
|
176611
|
+
await fs2.writeFile(join16(dir, ".npmrc"), `@qawolf:registry=https://registry.npmjs.org/
|
|
176538
176612
|
`);
|
|
176539
176613
|
}
|
|
176540
176614
|
|
|
@@ -176556,14 +176630,14 @@ async function isManagedRuntimeBase(dir, fs2) {
|
|
|
176556
176630
|
for (const entry of entries) {
|
|
176557
176631
|
if (!entry.isDirectory())
|
|
176558
176632
|
return false;
|
|
176559
|
-
if (!await hasRuntimeSentinel(
|
|
176633
|
+
if (!await hasRuntimeSentinel(join17(dir, entry.name), fs2))
|
|
176560
176634
|
return false;
|
|
176561
176635
|
}
|
|
176562
176636
|
return true;
|
|
176563
176637
|
}
|
|
176564
176638
|
async function hasRuntimeSentinel(hashDir, fs2) {
|
|
176565
176639
|
try {
|
|
176566
|
-
const pkg = JSON.parse(await fs2.readFile(
|
|
176640
|
+
const pkg = JSON.parse(await fs2.readFile(join17(hashDir, "package.json")));
|
|
176567
176641
|
return pkg.name === runtimeSentinel;
|
|
176568
176642
|
} catch {
|
|
176569
176643
|
return false;
|
|
@@ -176637,10 +176711,10 @@ function spawnNpmInstall(cwd, spawn2 = spawn) {
|
|
|
176637
176711
|
}
|
|
176638
176712
|
|
|
176639
176713
|
// src/domains/runtimeEnv/resolvePinned.ts
|
|
176640
|
-
import { join as
|
|
176714
|
+
import { join as join18 } from "node:path";
|
|
176641
176715
|
function readInstalledVersion(dir, pkgName, fs2) {
|
|
176642
176716
|
try {
|
|
176643
|
-
const pkgPath =
|
|
176717
|
+
const pkgPath = join18(dir, "node_modules", ...pkgName.split("/"), "package.json");
|
|
176644
176718
|
const raw = JSON.parse(fs2.readFileSync(pkgPath));
|
|
176645
176719
|
const { version: version2 } = raw;
|
|
176646
176720
|
return typeof version2 === "string" ? version2 : undefined;
|
|
@@ -176649,8 +176723,18 @@ function readInstalledVersion(dir, pkgName, fs2) {
|
|
|
176649
176723
|
}
|
|
176650
176724
|
}
|
|
176651
176725
|
var shims = [
|
|
176652
|
-
{
|
|
176653
|
-
|
|
176726
|
+
{
|
|
176727
|
+
name: "playwright",
|
|
176728
|
+
display: "node_modules/playwright/cli.js",
|
|
176729
|
+
candidates: (dir, _platform) => [
|
|
176730
|
+
playwrightCliJsPath(dir)
|
|
176731
|
+
]
|
|
176732
|
+
},
|
|
176733
|
+
{
|
|
176734
|
+
name: "appium",
|
|
176735
|
+
display: "node_modules/.bin/appium",
|
|
176736
|
+
candidates: appiumCliCandidates
|
|
176737
|
+
}
|
|
176654
176738
|
];
|
|
176655
176739
|
function pinnedResolutionFailures(dir, fs2, platform) {
|
|
176656
176740
|
const failures = [];
|
|
@@ -176660,16 +176744,16 @@ function pinnedResolutionFailures(dir, fs2, platform) {
|
|
|
176660
176744
|
failures.push({ kind: "package", name, pinned: version2, installed });
|
|
176661
176745
|
}
|
|
176662
176746
|
}
|
|
176663
|
-
for (const { name, candidates } of shims) {
|
|
176747
|
+
for (const { name, display, candidates } of shims) {
|
|
176664
176748
|
if (!candidates(dir, platform).some((p2) => fs2.existsSync(p2))) {
|
|
176665
|
-
failures.push({ kind: "shim", name });
|
|
176749
|
+
failures.push({ kind: "shim", name, display });
|
|
176666
176750
|
}
|
|
176667
176751
|
}
|
|
176668
176752
|
return failures;
|
|
176669
176753
|
}
|
|
176670
176754
|
function describePinnedFailure(failure) {
|
|
176671
176755
|
if (failure.kind === "shim") {
|
|
176672
|
-
return
|
|
176756
|
+
return `${failure.display} (missing)`;
|
|
176673
176757
|
}
|
|
176674
176758
|
return failure.installed === undefined ? `${failure.name} (missing, pinned ${failure.pinned})` : `${failure.name} ${failure.installed} (pinned ${failure.pinned})`;
|
|
176675
176759
|
}
|
|
@@ -176678,10 +176762,10 @@ function allPinnedResolved(dir, fs2, platform) {
|
|
|
176678
176762
|
}
|
|
176679
176763
|
|
|
176680
176764
|
// src/domains/runtimeEnv/shimDeps.ts
|
|
176681
|
-
import { join as
|
|
176765
|
+
import { join as join20 } from "node:path";
|
|
176682
176766
|
|
|
176683
176767
|
// src/shell/resolveExport.ts
|
|
176684
|
-
import { join as
|
|
176768
|
+
import { join as join19 } from "node:path";
|
|
176685
176769
|
function pickPath(entry, preference) {
|
|
176686
176770
|
if (typeof entry === "string")
|
|
176687
176771
|
return entry;
|
|
@@ -176713,28 +176797,28 @@ function resolveFromEnvDir(envDir, specifier, preference = "esm", fs2 = makeDefa
|
|
|
176713
176797
|
const pkgName = parts.slice(0, pkgPartCount).join("/");
|
|
176714
176798
|
const rest = parts.slice(pkgPartCount);
|
|
176715
176799
|
const subpath = rest.length > 0 ? "./" + rest.join("/") : ".";
|
|
176716
|
-
const pkgDir =
|
|
176800
|
+
const pkgDir = join19(envDir, "node_modules", ...pkgName.split("/"));
|
|
176717
176801
|
let pkg;
|
|
176718
176802
|
try {
|
|
176719
|
-
pkg = JSON.parse(fs2.readFileSync(
|
|
176803
|
+
pkg = JSON.parse(fs2.readFileSync(join19(pkgDir, "package.json")));
|
|
176720
176804
|
} catch (err) {
|
|
176721
176805
|
if (isNoEntError(err))
|
|
176722
|
-
throw new Error(`Package '${pkgName}' not found in ${
|
|
176806
|
+
throw new Error(`Package '${pkgName}' not found in ${join19(envDir, "node_modules")}`, { cause: err });
|
|
176723
176807
|
throw err;
|
|
176724
176808
|
}
|
|
176725
176809
|
const exportsMap = normalizeExports(pkg.exports);
|
|
176726
176810
|
const entry = exportsMap?.[subpath];
|
|
176727
176811
|
const relative3 = pickPath(entry, preference) ?? (subpath === "." ? pkg.module ?? pkg.main : undefined);
|
|
176728
176812
|
if (!relative3) {
|
|
176729
|
-
throw new Error(`No entry for "${subpath}" in exports of ${
|
|
176813
|
+
throw new Error(`No entry for "${subpath}" in exports of ${join19(pkgDir, "package.json")}`);
|
|
176730
176814
|
}
|
|
176731
|
-
return
|
|
176815
|
+
return join19(pkgDir, relative3);
|
|
176732
176816
|
}
|
|
176733
176817
|
|
|
176734
176818
|
// src/domains/runtimeEnv/shimDeps.ts
|
|
176735
176819
|
function readShimMarker(shimDir, fs2) {
|
|
176736
176820
|
try {
|
|
176737
|
-
const pkg = JSON.parse(fs2.readFileSync(
|
|
176821
|
+
const pkg = JSON.parse(fs2.readFileSync(join20(shimDir, "package.json")));
|
|
176738
176822
|
if (pkg._qawolf_format) {
|
|
176739
176823
|
return {
|
|
176740
176824
|
_qawolf_version: pkg._qawolf_version ?? "",
|
|
@@ -176750,11 +176834,11 @@ function resolveBunBuild(bunBuild) {
|
|
|
176750
176834
|
return bunBuild === false ? undefined : { build: bunBuild };
|
|
176751
176835
|
}
|
|
176752
176836
|
async function removeStaleShims(flowsDir, flowsDeps, fs2) {
|
|
176753
|
-
const shimsDir =
|
|
176837
|
+
const shimsDir = join20(flowsDir, "node_modules");
|
|
176754
176838
|
if (!fs2.existsSync(shimsDir))
|
|
176755
176839
|
return;
|
|
176756
176840
|
for (const dep of flowsDeps) {
|
|
176757
|
-
const shimDepDir =
|
|
176841
|
+
const shimDepDir = join20(shimsDir, ...dep.split("/"));
|
|
176758
176842
|
if (readShimMarker(shimDepDir, fs2)) {
|
|
176759
176843
|
await fs2.rm(shimDepDir, { recursive: true, force: true });
|
|
176760
176844
|
}
|
|
@@ -176763,17 +176847,17 @@ async function removeStaleShims(flowsDir, flowsDeps, fs2) {
|
|
|
176763
176847
|
async function buildDepShim(args) {
|
|
176764
176848
|
const { envDir, flowsDir, dep, fs: fs2, build: build2 } = args;
|
|
176765
176849
|
const depParts = dep.split("/");
|
|
176766
|
-
const depDir =
|
|
176850
|
+
const depDir = join20(envDir, "node_modules", ...depParts);
|
|
176767
176851
|
if (!fs2.existsSync(depDir))
|
|
176768
176852
|
return;
|
|
176769
176853
|
let depVersion;
|
|
176770
176854
|
try {
|
|
176771
|
-
const pkg = JSON.parse(fs2.readFileSync(
|
|
176855
|
+
const pkg = JSON.parse(fs2.readFileSync(join20(depDir, "package.json")));
|
|
176772
176856
|
depVersion = pkg.version ?? "unknown";
|
|
176773
176857
|
} catch {
|
|
176774
176858
|
depVersion = "unknown";
|
|
176775
176859
|
}
|
|
176776
|
-
const shimDir =
|
|
176860
|
+
const shimDir = join20(flowsDir, "node_modules", ...depParts);
|
|
176777
176861
|
if (fs2.existsSync(shimDir)) {
|
|
176778
176862
|
const marker = readShimMarker(shimDir, fs2);
|
|
176779
176863
|
if (!marker)
|
|
@@ -176800,20 +176884,20 @@ async function buildDepShim(args) {
|
|
|
176800
176884
|
}
|
|
176801
176885
|
const shimCode = await output.text();
|
|
176802
176886
|
await fs2.mkdir(shimDir, { recursive: true });
|
|
176803
|
-
await fs2.writeFile(
|
|
176887
|
+
await fs2.writeFile(join20(shimDir, "package.json"), JSON.stringify({
|
|
176804
176888
|
name: dep,
|
|
176805
176889
|
_qawolf_version: depVersion,
|
|
176806
176890
|
_qawolf_format: "bun-build-v1"
|
|
176807
176891
|
}));
|
|
176808
|
-
await fs2.writeFile(
|
|
176892
|
+
await fs2.writeFile(join20(shimDir, "index.js"), shimCode);
|
|
176809
176893
|
}
|
|
176810
176894
|
async function shimFlowsDeps(envDir, fs2 = makeDefaultFs(), bunBuild) {
|
|
176811
|
-
const flowsDir =
|
|
176895
|
+
const flowsDir = join20(envDir, "node_modules", "@qawolf", "flows");
|
|
176812
176896
|
if (!fs2.existsSync(flowsDir))
|
|
176813
176897
|
return;
|
|
176814
176898
|
let flowsDeps;
|
|
176815
176899
|
try {
|
|
176816
|
-
const flowsPkg = JSON.parse(fs2.readFileSync(
|
|
176900
|
+
const flowsPkg = JSON.parse(fs2.readFileSync(join20(flowsDir, "package.json")));
|
|
176817
176901
|
flowsDeps = Object.keys(flowsPkg.dependencies ?? {});
|
|
176818
176902
|
} catch {
|
|
176819
176903
|
return;
|
|
@@ -176937,6 +177021,7 @@ async function handleDoctor(ctx, opts) {
|
|
|
176937
177021
|
apiKey: resolved?.key,
|
|
176938
177022
|
fetch: globalThis.fetch,
|
|
176939
177023
|
spawn: defaultSpawn,
|
|
177024
|
+
execPath: process.execPath,
|
|
176940
177025
|
apiBaseUrl: ctx.apiBaseUrl,
|
|
176941
177026
|
enginesNode: package_default.engines.node,
|
|
176942
177027
|
processVersion: process.version,
|
|
@@ -177044,9 +177129,8 @@ async function flowsListRemote(ctx, pattern, options) {
|
|
|
177044
177129
|
environmentId: options.env,
|
|
177045
177130
|
includeDrafts: options.includeDrafts
|
|
177046
177131
|
});
|
|
177047
|
-
if (!result.ok)
|
|
177048
|
-
return
|
|
177049
|
-
}
|
|
177132
|
+
if (!result.ok)
|
|
177133
|
+
return failureFields(result);
|
|
177050
177134
|
const matches = pattern ? import_picomatch2.default(pattern) : undefined;
|
|
177051
177135
|
const items = result.value.flows.filter((f2) => !matches || matches(f2.path)).map((f2) => ({
|
|
177052
177136
|
flowId: f2.flowId,
|
|
@@ -177079,11 +177163,11 @@ async function flowsListRemote(ctx, pattern, options) {
|
|
|
177079
177163
|
}
|
|
177080
177164
|
|
|
177081
177165
|
// src/domains/flows/pull/handler.ts
|
|
177082
|
-
import { dirname as dirname7, join as
|
|
177166
|
+
import { dirname as dirname7, join as join25, resolve as resolve8 } from "node:path";
|
|
177083
177167
|
|
|
177084
177168
|
// src/shell/manifest/io.ts
|
|
177085
177169
|
import { createHash as createHash2 } from "node:crypto";
|
|
177086
|
-
import { join as
|
|
177170
|
+
import { join as join21 } from "node:path";
|
|
177087
177171
|
var manifestFilename = ".manifest.json";
|
|
177088
177172
|
var flowEntrySchema = exports_external.object({
|
|
177089
177173
|
path: exports_external.string(),
|
|
@@ -177102,7 +177186,7 @@ var manifestSchema = exports_external.object({
|
|
|
177102
177186
|
async function readManifest(envDir, fs2 = makeDefaultFs()) {
|
|
177103
177187
|
let raw;
|
|
177104
177188
|
try {
|
|
177105
|
-
raw = await fs2.readFile(
|
|
177189
|
+
raw = await fs2.readFile(join21(envDir, manifestFilename));
|
|
177106
177190
|
} catch (err) {
|
|
177107
177191
|
if (isNoEntError(err))
|
|
177108
177192
|
return "missing";
|
|
@@ -177130,7 +177214,7 @@ async function readManifest(envDir, fs2 = makeDefaultFs()) {
|
|
|
177130
177214
|
}
|
|
177131
177215
|
async function writeManifest(envDir, manifest, fs2 = makeDefaultFs()) {
|
|
177132
177216
|
const body = JSON.stringify(manifest, undefined, 2);
|
|
177133
|
-
await fs2.writeFile(
|
|
177217
|
+
await fs2.writeFile(join21(envDir, manifestFilename), `${body}
|
|
177134
177218
|
`);
|
|
177135
177219
|
}
|
|
177136
177220
|
function hashFile(absPath, fs2 = makeDefaultFs()) {
|
|
@@ -177265,7 +177349,7 @@ async function checkSafety(args) {
|
|
|
177265
177349
|
}
|
|
177266
177350
|
|
|
177267
177351
|
// src/domains/flows/pull/bundle.ts
|
|
177268
|
-
import { join as
|
|
177352
|
+
import { join as join22, relative as relative4 } from "node:path";
|
|
177269
177353
|
async function flattenSingleWrapper(dir, fs2 = makeDefaultFs()) {
|
|
177270
177354
|
const entries = await fs2.readdir(dir);
|
|
177271
177355
|
if (entries.length !== 1)
|
|
@@ -177273,12 +177357,12 @@ async function flattenSingleWrapper(dir, fs2 = makeDefaultFs()) {
|
|
|
177273
177357
|
const innerName = entries[0];
|
|
177274
177358
|
if (!innerName)
|
|
177275
177359
|
return;
|
|
177276
|
-
const inner =
|
|
177360
|
+
const inner = join22(dir, innerName);
|
|
177277
177361
|
const innerStat = await fs2.stat(inner);
|
|
177278
177362
|
if (!innerStat.isDirectory())
|
|
177279
177363
|
return;
|
|
177280
177364
|
for (const e of await fs2.readdir(inner)) {
|
|
177281
|
-
await fs2.rename(
|
|
177365
|
+
await fs2.rename(join22(inner, e), join22(dir, e));
|
|
177282
177366
|
}
|
|
177283
177367
|
const leftovers = await fs2.readdir(inner);
|
|
177284
177368
|
if (leftovers.length > 0) {
|
|
@@ -177297,7 +177381,7 @@ async function buildManifest(args, fs2 = makeDefaultFs()) {
|
|
|
177297
177381
|
const flowPaths = await walkForFlows(args.bundleDir, fs2);
|
|
177298
177382
|
const flows = await Promise.all(flowPaths.map(async (rel) => ({
|
|
177299
177383
|
path: rel,
|
|
177300
|
-
contentHash: await hashFile(
|
|
177384
|
+
contentHash: await hashFile(join22(args.bundleDir, rel), fs2)
|
|
177301
177385
|
})));
|
|
177302
177386
|
return {
|
|
177303
177387
|
envId: args.envId,
|
|
@@ -177318,7 +177402,7 @@ async function walkForFlows(root, fs2) {
|
|
|
177318
177402
|
async function walk(current, root, out, fs2) {
|
|
177319
177403
|
const entries = await fs2.readdirWithTypes(current);
|
|
177320
177404
|
for (const e of entries) {
|
|
177321
|
-
const abs =
|
|
177405
|
+
const abs = join22(current, e.name);
|
|
177322
177406
|
if (e.isDirectory()) {
|
|
177323
177407
|
await walk(abs, root, out, fs2);
|
|
177324
177408
|
} else if (e.isFile() && flowExtensions.some((ext) => e.name.endsWith(ext))) {
|
|
@@ -177331,11 +177415,11 @@ async function sampleQawolfCommittedAt(bundleDir, fs2 = makeDefaultFs()) {
|
|
|
177331
177415
|
const sample = flowPaths[0];
|
|
177332
177416
|
if (!sample)
|
|
177333
177417
|
return;
|
|
177334
|
-
return (await fs2.stat(
|
|
177418
|
+
return (await fs2.stat(join22(bundleDir, sample))).mtime.toISOString();
|
|
177335
177419
|
}
|
|
177336
177420
|
|
|
177337
177421
|
// src/domains/flows/pull/applyTeamStorageRewrite.ts
|
|
177338
|
-
import { join as
|
|
177422
|
+
import { join as join23, relative as relative5 } from "node:path";
|
|
177339
177423
|
|
|
177340
177424
|
// src/domains/flows/pull/rewriteTeamStorage.ts
|
|
177341
177425
|
var runnerMountPrefix = "/home/wolf/team-storage/";
|
|
@@ -177371,7 +177455,7 @@ function isFlowFile(name) {
|
|
|
177371
177455
|
async function walk2(dir, out, fs2) {
|
|
177372
177456
|
const entries = await fs2.readdirWithTypes(dir);
|
|
177373
177457
|
for (const e of entries) {
|
|
177374
|
-
const abs =
|
|
177458
|
+
const abs = join23(dir, e.name);
|
|
177375
177459
|
if (e.isDirectory()) {
|
|
177376
177460
|
await walk2(abs, out, fs2);
|
|
177377
177461
|
} else if (e.isFile() && isSourceFile(e.name)) {
|
|
@@ -177399,7 +177483,7 @@ async function applyTeamStorageRewrite(rootDir, fs2 = makeDefaultFs()) {
|
|
|
177399
177483
|
}
|
|
177400
177484
|
|
|
177401
177485
|
// src/domains/flows/pull/envVars.ts
|
|
177402
|
-
import { join as
|
|
177486
|
+
import { join as join24 } from "node:path";
|
|
177403
177487
|
|
|
177404
177488
|
// src/core/dotenv.ts
|
|
177405
177489
|
var bareKeyPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -177464,7 +177548,7 @@ function unquote(escaped) {
|
|
|
177464
177548
|
async function writeEnvFile(envDir, vars, fs2 = makeDefaultFs()) {
|
|
177465
177549
|
if (Object.keys(vars).length === 0)
|
|
177466
177550
|
return;
|
|
177467
|
-
await fs2.writeFile(
|
|
177551
|
+
await fs2.writeFile(join24(envDir, ".env"), serializeDotenv(vars), {
|
|
177468
177552
|
mode: 384
|
|
177469
177553
|
});
|
|
177470
177554
|
}
|
|
@@ -180837,8 +180921,8 @@ async function handleFlowsPull(ctx, opts, deps) {
|
|
|
180837
180921
|
ctx.ui.error(validation.error);
|
|
180838
180922
|
return { error: validation.error };
|
|
180839
180923
|
}
|
|
180840
|
-
const destAbs = resolve8(opts.out ??
|
|
180841
|
-
const assetsAbs =
|
|
180924
|
+
const destAbs = resolve8(opts.out ?? join25(".qawolf", opts.env));
|
|
180925
|
+
const assetsAbs = join25(dirname7(destAbs), "assets");
|
|
180842
180926
|
await resolvedDeps.fs.mkdir(assetsAbs, { recursive: true });
|
|
180843
180927
|
const yes = opts.yes ?? false;
|
|
180844
180928
|
let archive;
|
|
@@ -180904,7 +180988,7 @@ async function handleFlowsPull(ctx, opts, deps) {
|
|
|
180904
180988
|
assetDownloadedCount: assetResult.downloadedCount,
|
|
180905
180989
|
assetReusedCount: assetResult.reusedCount,
|
|
180906
180990
|
assetSkippedCount: assetResult.skippedCount,
|
|
180907
|
-
manifestPath:
|
|
180991
|
+
manifestPath: join25(result.envDir, manifestFilename)
|
|
180908
180992
|
}, "");
|
|
180909
180993
|
}
|
|
180910
180994
|
} finally {
|
|
@@ -180918,7 +181002,7 @@ var findContract = publicContractsV1.environment.find;
|
|
|
180918
181002
|
async function pickEnvironment(deps) {
|
|
180919
181003
|
const fetched = await fetchAllEnvironments(deps.platformClient);
|
|
180920
181004
|
if (!fetched.ok)
|
|
180921
|
-
return { kind: "error"
|
|
181005
|
+
return { ...failureFields(fetched), kind: "error" };
|
|
180922
181006
|
const environments = fetched.environments;
|
|
180923
181007
|
if (environments.length === 0) {
|
|
180924
181008
|
return { kind: "error", error: environmentsMessages.noEnvironments };
|
|
@@ -181011,6 +181095,7 @@ async function resolveRef2(deps, ref) {
|
|
|
181011
181095
|
});
|
|
181012
181096
|
if (!result.ok) {
|
|
181013
181097
|
return {
|
|
181098
|
+
...failureFields(result),
|
|
181014
181099
|
kind: "error",
|
|
181015
181100
|
error: environmentsMessages.couldNotResolve(ref, result.error)
|
|
181016
181101
|
};
|
|
@@ -181044,7 +181129,7 @@ function withResolvedEnv(signals, args, fn2) {
|
|
|
181044
181129
|
return;
|
|
181045
181130
|
}
|
|
181046
181131
|
if (outcome.kind === "error") {
|
|
181047
|
-
return
|
|
181132
|
+
return failureFields(outcome);
|
|
181048
181133
|
}
|
|
181049
181134
|
return fn2(ctx, outcome.env);
|
|
181050
181135
|
})(opts, command);
|
|
@@ -181090,6 +181175,72 @@ function buildPatternArgs(pattern) {
|
|
|
181090
181175
|
return pattern ? [pattern] : [];
|
|
181091
181176
|
}
|
|
181092
181177
|
|
|
181178
|
+
// src/shell/reporter/createCompositeReporter.ts
|
|
181179
|
+
function callEach(reporters, pick2, event) {
|
|
181180
|
+
for (const r2 of reporters) {
|
|
181181
|
+
try {
|
|
181182
|
+
pick2(r2)?.(event);
|
|
181183
|
+
} catch (err) {
|
|
181184
|
+
process.stderr.write(`[reporter error] ${String(err)}
|
|
181185
|
+
`);
|
|
181186
|
+
}
|
|
181187
|
+
}
|
|
181188
|
+
}
|
|
181189
|
+
function createCompositeReporter(reporters) {
|
|
181190
|
+
return {
|
|
181191
|
+
onFlowStart: (e) => callEach(reporters, (r2) => r2.onFlowStart, e),
|
|
181192
|
+
onFlowPass: (e) => callEach(reporters, (r2) => r2.onFlowPass, e),
|
|
181193
|
+
onFlowFail: (e) => callEach(reporters, (r2) => r2.onFlowFail, e),
|
|
181194
|
+
onTestStart: (e) => callEach(reporters, (r2) => r2.onTestStart, e),
|
|
181195
|
+
onTestResult: (e) => callEach(reporters, (r2) => r2.onTestResult, e),
|
|
181196
|
+
onScreenshot: (e) => callEach(reporters, (r2) => r2.onScreenshot, e),
|
|
181197
|
+
onRunComplete: (e) => callEach(reporters, (r2) => r2.onRunComplete, e)
|
|
181198
|
+
};
|
|
181199
|
+
}
|
|
181200
|
+
|
|
181201
|
+
// src/shell/reporter/formatErrorWithCause.ts
|
|
181202
|
+
function filterStack(stack) {
|
|
181203
|
+
const cwd = process.cwd();
|
|
181204
|
+
return stack.split(`
|
|
181205
|
+
`).filter((line) => {
|
|
181206
|
+
if (!/^\s+at /.test(line))
|
|
181207
|
+
return true;
|
|
181208
|
+
return !line.includes("node_modules") && !line.includes("dist/cli.js");
|
|
181209
|
+
}).map((line) => {
|
|
181210
|
+
if (!/^\s+at /.test(line))
|
|
181211
|
+
return line;
|
|
181212
|
+
return line.replace(`file://${cwd}/`, "").replace(`${cwd}/`, "");
|
|
181213
|
+
}).join(`
|
|
181214
|
+
`);
|
|
181215
|
+
}
|
|
181216
|
+
function renderCause(cause) {
|
|
181217
|
+
if (cause instanceof Error)
|
|
181218
|
+
return filterStack(cause.stack ?? cause.message);
|
|
181219
|
+
if (typeof cause === "object" && cause !== null) {
|
|
181220
|
+
const obj = cause;
|
|
181221
|
+
if (typeof obj["message"] === "string")
|
|
181222
|
+
return obj["message"];
|
|
181223
|
+
try {
|
|
181224
|
+
return JSON.stringify(cause);
|
|
181225
|
+
} catch {
|
|
181226
|
+
return String(cause);
|
|
181227
|
+
}
|
|
181228
|
+
}
|
|
181229
|
+
return String(cause);
|
|
181230
|
+
}
|
|
181231
|
+
function formatErrorWithCause(err) {
|
|
181232
|
+
const parts = [String(err)];
|
|
181233
|
+
let cause = err.cause;
|
|
181234
|
+
while (cause !== undefined && cause !== null) {
|
|
181235
|
+
parts.push(`Caused by: ${renderCause(cause)}`);
|
|
181236
|
+
if (!(cause instanceof Error))
|
|
181237
|
+
break;
|
|
181238
|
+
cause = cause.cause;
|
|
181239
|
+
}
|
|
181240
|
+
return parts.join(`
|
|
181241
|
+
`);
|
|
181242
|
+
}
|
|
181243
|
+
|
|
181093
181244
|
// src/domains/runner/runAndroidFlowUtils.ts
|
|
181094
181245
|
import { parseExecutionTarget as parseExecutionTarget3 } from "@qawolf/flow-targets";
|
|
181095
181246
|
|
|
@@ -181437,9 +181588,16 @@ async function flowsRun(ctx, files, flags, deps) {
|
|
|
181437
181588
|
return { error: runnerMessages.androidWorkersUnsupported, exitCode: 2 };
|
|
181438
181589
|
}
|
|
181439
181590
|
const { webOptions, androidOptions } = buildRunOptions(flags);
|
|
181591
|
+
const failureDetails = [];
|
|
181592
|
+
const reporter = ctx.outputMode === "json" ? createCompositeReporter([
|
|
181593
|
+
deps.reporter,
|
|
181594
|
+
{
|
|
181595
|
+
onFlowFail: ({ err }) => failureDetails.push(formatErrorWithCause(err))
|
|
181596
|
+
}
|
|
181597
|
+
]) : deps.reporter;
|
|
181440
181598
|
const result = await executeFlows({
|
|
181441
181599
|
ctx,
|
|
181442
|
-
deps,
|
|
181600
|
+
deps: { ...deps, reporter },
|
|
181443
181601
|
flags,
|
|
181444
181602
|
flows,
|
|
181445
181603
|
webFlows,
|
|
@@ -181467,7 +181625,13 @@ async function flowsRun(ctx, files, flags, deps) {
|
|
|
181467
181625
|
deps.reporter.onRunComplete?.({ summary });
|
|
181468
181626
|
ctx.ui.gap();
|
|
181469
181627
|
if (counts.flowsFailed > 0) {
|
|
181470
|
-
|
|
181628
|
+
const error51 = runnerMessages.flowsFailed(counts.flowsFailed);
|
|
181629
|
+
if (ctx.outputMode === "json" && failureDetails.length > 0) {
|
|
181630
|
+
return { error: error51, errorBody: failureDetails.join(`
|
|
181631
|
+
|
|
181632
|
+
`) };
|
|
181633
|
+
}
|
|
181634
|
+
return { error: error51 };
|
|
181471
181635
|
}
|
|
181472
181636
|
}
|
|
181473
181637
|
|
|
@@ -181518,15 +181682,15 @@ async function defaultRunWebFlowDeps(envDir = process.cwd(), signals) {
|
|
|
181518
181682
|
|
|
181519
181683
|
// src/domains/runtimeEnv/prepareRunDir.ts
|
|
181520
181684
|
import { createHash as createHash4 } from "node:crypto";
|
|
181521
|
-
import { join as
|
|
181685
|
+
import { join as join32, resolve as resolve9 } from "node:path";
|
|
181522
181686
|
|
|
181523
181687
|
// src/domains/runtimeEnv/execSubpathImports.ts
|
|
181524
|
-
import { join as
|
|
181688
|
+
import { join as join26 } from "node:path";
|
|
181525
181689
|
var flowSubpathImports = { "#playwright": "playwright" };
|
|
181526
181690
|
var packageJsonSchema = exports_external.looseObject({ imports: exports_external.record(exports_external.string(), exports_external.unknown()).catch({}) }).catch({ imports: {} });
|
|
181527
181691
|
async function writeExecSubpathImports(args) {
|
|
181528
181692
|
const { execDir, fs: fs3 } = args;
|
|
181529
|
-
const pkgPath =
|
|
181693
|
+
const pkgPath = join26(execDir, "package.json");
|
|
181530
181694
|
const pkg = packageJsonSchema.parse(await readPackageJson(pkgPath, fs3));
|
|
181531
181695
|
const merged = { ...pkg, imports: { ...pkg.imports, ...flowSubpathImports } };
|
|
181532
181696
|
await fs3.writeFile(pkgPath, JSON.stringify(merged, undefined, 2));
|
|
@@ -181548,10 +181712,10 @@ async function readPackageJson(pkgPath, fs3) {
|
|
|
181548
181712
|
}
|
|
181549
181713
|
|
|
181550
181714
|
// src/domains/runtimeEnv/innerHop.ts
|
|
181551
|
-
import { join as
|
|
181715
|
+
import { join as join28 } from "node:path";
|
|
181552
181716
|
|
|
181553
181717
|
// src/domains/runtimeEnv/linkPinnedPackages.ts
|
|
181554
|
-
import { dirname as dirname8, join as
|
|
181718
|
+
import { dirname as dirname8, join as join27 } from "node:path";
|
|
181555
181719
|
|
|
181556
181720
|
// src/domains/runtimeEnv/symlinkDir.ts
|
|
181557
181721
|
import { symlink } from "node:fs/promises";
|
|
@@ -181563,16 +181727,16 @@ async function createDirSymlink(source, target) {
|
|
|
181563
181727
|
// src/domains/runtimeEnv/linkPinnedPackages.ts
|
|
181564
181728
|
async function linkPinnedPackages(args) {
|
|
181565
181729
|
const { depsRoot, nodeModulesDir, fs: fs3 } = args;
|
|
181566
|
-
const managedModules =
|
|
181730
|
+
const managedModules = join27(depsRoot, "node_modules");
|
|
181567
181731
|
await fs3.mkdir(nodeModulesDir, { recursive: true });
|
|
181568
181732
|
for (const { name } of pinnedPackages) {
|
|
181569
181733
|
const segments = name.split("/");
|
|
181570
|
-
const target =
|
|
181734
|
+
const target = join27(nodeModulesDir, ...segments);
|
|
181571
181735
|
if (segments.length > 1) {
|
|
181572
181736
|
await fs3.mkdir(dirname8(target), { recursive: true });
|
|
181573
181737
|
}
|
|
181574
181738
|
await fs3.rm(target, { recursive: true, force: true });
|
|
181575
|
-
await createDirSymlink(
|
|
181739
|
+
await createDirSymlink(join27(managedModules, ...segments), target);
|
|
181576
181740
|
}
|
|
181577
181741
|
}
|
|
181578
181742
|
|
|
@@ -181581,14 +181745,14 @@ async function populateInnerHop(args) {
|
|
|
181581
181745
|
const { depsRoot, execDir, fs: fs3 } = args;
|
|
181582
181746
|
await linkPinnedPackages({
|
|
181583
181747
|
depsRoot,
|
|
181584
|
-
nodeModulesDir:
|
|
181748
|
+
nodeModulesDir: join28(execDir, "node_modules"),
|
|
181585
181749
|
fs: fs3
|
|
181586
181750
|
});
|
|
181587
181751
|
}
|
|
181588
181752
|
|
|
181589
181753
|
// src/domains/runtimeEnv/outerHop.ts
|
|
181590
181754
|
import { lstat } from "node:fs/promises";
|
|
181591
|
-
import { dirname as dirname9, join as
|
|
181755
|
+
import { dirname as dirname9, join as join29 } from "node:path";
|
|
181592
181756
|
var executorPackageNames = new Set(pinnedPackages.map((p3) => p3.name));
|
|
181593
181757
|
async function populateOuterHop(args) {
|
|
181594
181758
|
const { projectDir, runDir, fs: fs3 } = args;
|
|
@@ -181598,7 +181762,7 @@ async function populateOuterHop(args) {
|
|
|
181598
181762
|
const depNames = Object.keys(installableDeps);
|
|
181599
181763
|
const { satisfying, rejected } = await findSatisfyingNodeModulesDir(projectDir, depNames, fs3);
|
|
181600
181764
|
if (satisfying !== undefined) {
|
|
181601
|
-
await createDirSymlink(satisfying,
|
|
181765
|
+
await createDirSymlink(satisfying, join29(runDir, "node_modules"));
|
|
181602
181766
|
return { mode: "symlink", nodeModulesDir: satisfying };
|
|
181603
181767
|
}
|
|
181604
181768
|
if (depNames.length === 0)
|
|
@@ -181607,7 +181771,7 @@ async function populateOuterHop(args) {
|
|
|
181607
181771
|
await installOuterDeps(runDir, installableDeps, fs3, args.install ?? spawnNpmInstall);
|
|
181608
181772
|
await linkPinnedPackages({
|
|
181609
181773
|
depsRoot: args.depsRoot,
|
|
181610
|
-
nodeModulesDir:
|
|
181774
|
+
nodeModulesDir: join29(runDir, "node_modules"),
|
|
181611
181775
|
fs: fs3
|
|
181612
181776
|
});
|
|
181613
181777
|
return { mode: "install", depCount: depNames.length, rejected };
|
|
@@ -181616,10 +181780,10 @@ async function findSatisfyingNodeModulesDir(startDir, depNames, fs3) {
|
|
|
181616
181780
|
const rejected = [];
|
|
181617
181781
|
let dir = startDir;
|
|
181618
181782
|
while (true) {
|
|
181619
|
-
const candidate =
|
|
181783
|
+
const candidate = join29(dir, "node_modules");
|
|
181620
181784
|
const stats = await lstatSafe(candidate);
|
|
181621
181785
|
if (stats !== undefined && stats.isDirectory() && !stats.isSymbolicLink()) {
|
|
181622
|
-
const missing = depNames.filter((name) => !fs3.existsSync(
|
|
181786
|
+
const missing = depNames.filter((name) => !fs3.existsSync(join29(candidate, name, "package.json")));
|
|
181623
181787
|
if (missing.length === 0)
|
|
181624
181788
|
return { satisfying: candidate, rejected };
|
|
181625
181789
|
rejected.push({ dir: candidate, missing });
|
|
@@ -181640,7 +181804,7 @@ async function lstatSafe(path3) {
|
|
|
181640
181804
|
async function readInstallableDeps(projectDir, fs3) {
|
|
181641
181805
|
let content;
|
|
181642
181806
|
try {
|
|
181643
|
-
content = await fs3.readFile(
|
|
181807
|
+
content = await fs3.readFile(join29(projectDir, "package.json"));
|
|
181644
181808
|
} catch {
|
|
181645
181809
|
return {};
|
|
181646
181810
|
}
|
|
@@ -181658,8 +181822,8 @@ async function readInstallableDeps(projectDir, fs3) {
|
|
|
181658
181822
|
return Object.fromEntries(Object.entries(rawDeps).filter(([name]) => !executorPackageNames.has(name)).filter((entry) => typeof entry[1] === "string"));
|
|
181659
181823
|
}
|
|
181660
181824
|
async function installOuterDeps(runDir, deps, fs3, install) {
|
|
181661
|
-
await fs3.writeFile(
|
|
181662
|
-
await fs3.writeFile(
|
|
181825
|
+
await fs3.writeFile(join29(runDir, "package.json"), JSON.stringify({ name: "qawolf-run", private: true, dependencies: deps }, undefined, 2));
|
|
181826
|
+
await fs3.writeFile(join29(runDir, ".npmrc"), `@qawolf:registry=https://registry.npmjs.org/
|
|
181663
181827
|
`);
|
|
181664
181828
|
const result = await install(runDir);
|
|
181665
181829
|
if (result.exitCode !== 0) {
|
|
@@ -181669,14 +181833,14 @@ async function installOuterDeps(runDir, deps, fs3, install) {
|
|
|
181669
181833
|
|
|
181670
181834
|
// src/domains/runtimeEnv/stageFlowFiles.ts
|
|
181671
181835
|
import { createHash as createHash3 } from "node:crypto";
|
|
181672
|
-
import { basename as basename4, dirname as dirname10, join as
|
|
181836
|
+
import { basename as basename4, dirname as dirname10, join as join31, sep as sep4 } from "node:path";
|
|
181673
181837
|
|
|
181674
181838
|
// src/shell/copyDir.ts
|
|
181675
181839
|
import { cp, readdir as readdir2 } from "node:fs/promises";
|
|
181676
|
-
import { basename as basename3, join as
|
|
181840
|
+
import { basename as basename3, join as join30 } from "node:path";
|
|
181677
181841
|
async function copyDirExcluding(source, destination, excludedNames) {
|
|
181678
181842
|
const entries = await readdir2(source, { withFileTypes: true });
|
|
181679
|
-
await Promise.all(entries.filter((entry) => !excludedNames.has(entry.name)).map((entry) => cp(
|
|
181843
|
+
await Promise.all(entries.filter((entry) => !excludedNames.has(entry.name)).map((entry) => cp(join30(source, entry.name), join30(destination, entry.name), {
|
|
181680
181844
|
recursive: true,
|
|
181681
181845
|
filter: (path3) => !excludedNames.has(basename3(path3))
|
|
181682
181846
|
})));
|
|
@@ -181693,14 +181857,14 @@ async function stageFlowFiles(args) {
|
|
|
181693
181857
|
if (files.length > 1) {
|
|
181694
181858
|
return Promise.all(files.map((f3) => stageOneFile(f3, execDir, fs3)));
|
|
181695
181859
|
}
|
|
181696
|
-
await Promise.all(files.map((f3) => fs3.copyFile(f3,
|
|
181697
|
-
return files.map((f3) =>
|
|
181860
|
+
await Promise.all(files.map((f3) => fs3.copyFile(f3, join31(execDir, basename4(f3)))));
|
|
181861
|
+
return files.map((f3) => join31(execDir, basename4(f3)));
|
|
181698
181862
|
}
|
|
181699
181863
|
async function stageOneFile(file2, execDir, fs3) {
|
|
181700
181864
|
const dirHash = createHash3("sha256").update(dirname10(file2)).digest("hex").slice(0, 8);
|
|
181701
|
-
const subDir =
|
|
181865
|
+
const subDir = join31(execDir, dirHash);
|
|
181702
181866
|
await fs3.mkdir(subDir, { recursive: true });
|
|
181703
|
-
const dest =
|
|
181867
|
+
const dest = join31(subDir, basename4(file2));
|
|
181704
181868
|
await fs3.copyFile(file2, dest);
|
|
181705
181869
|
return dest;
|
|
181706
181870
|
}
|
|
@@ -181708,7 +181872,7 @@ function remapPath(file2, projectDir, execDir) {
|
|
|
181708
181872
|
if (file2 === projectDir)
|
|
181709
181873
|
return execDir;
|
|
181710
181874
|
if (file2.startsWith(projectDir + sep4)) {
|
|
181711
|
-
return
|
|
181875
|
+
return join31(execDir, file2.slice(projectDir.length + 1));
|
|
181712
181876
|
}
|
|
181713
181877
|
return;
|
|
181714
181878
|
}
|
|
@@ -181718,10 +181882,10 @@ async function prepareRunDir(args) {
|
|
|
181718
181882
|
const { files, projectDir, depsRoot, runRoot } = args;
|
|
181719
181883
|
const fs3 = args.fs ?? makeDefaultFs();
|
|
181720
181884
|
const runId = buildRunId(projectDir, files);
|
|
181721
|
-
const runDir =
|
|
181885
|
+
const runDir = join32(runRoot, runId);
|
|
181722
181886
|
await fs3.rm(runDir, { recursive: true, force: true });
|
|
181723
181887
|
await fs3.mkdir(runDir, { recursive: true });
|
|
181724
|
-
const execDir =
|
|
181888
|
+
const execDir = join32(runDir, "exec");
|
|
181725
181889
|
await fs3.mkdir(execDir, { recursive: true });
|
|
181726
181890
|
await populateInnerHop({ depsRoot, execDir, fs: fs3 });
|
|
181727
181891
|
const stagedFiles = await stageFlowFiles({ files, projectDir, execDir, fs: fs3 });
|
|
@@ -181752,17 +181916,17 @@ function buildRunId(projectDir, files) {
|
|
|
181752
181916
|
}
|
|
181753
181917
|
|
|
181754
181918
|
// src/shell/testkit.ts
|
|
181755
|
-
import { join as
|
|
181919
|
+
import { join as join33 } from "node:path";
|
|
181756
181920
|
function notAvailableLocally(name) {
|
|
181757
181921
|
throw new Error(runnerMessages.notAvailableLocally(name));
|
|
181758
181922
|
}
|
|
181759
181923
|
async function loadSdkDeps(cwd) {
|
|
181760
|
-
const testkitDir =
|
|
181924
|
+
const testkitDir = join33(cwd, "node_modules", "@qawolf", "testkit");
|
|
181761
181925
|
try {
|
|
181762
181926
|
const clientMod = await importFromPath(resolveFromEnvDir(cwd, "@qawolf/testkit/client"));
|
|
181763
181927
|
if (typeof clientMod.createTestkitClient !== "function")
|
|
181764
181928
|
throw new Error("createTestkitClient is not a function");
|
|
181765
|
-
const scopeMod = await importFromPath(
|
|
181929
|
+
const scopeMod = await importFromPath(join33(testkitDir, "dist", "clientScope.js"));
|
|
181766
181930
|
if (typeof scopeMod.configureTestkitClient !== "function")
|
|
181767
181931
|
throw new Error("configureTestkitClient is not a function");
|
|
181768
181932
|
return {
|
|
@@ -181820,9 +181984,9 @@ async function registerLazyEmailsClient(getInbox, cwd, deps) {
|
|
|
181820
181984
|
}
|
|
181821
181985
|
|
|
181822
181986
|
// src/commands/flows/envVarDeps.ts
|
|
181823
|
-
import { join as
|
|
181987
|
+
import { join as join34 } from "node:path";
|
|
181824
181988
|
function envFilePath(envDir) {
|
|
181825
|
-
return
|
|
181989
|
+
return join34(envDir, ".env");
|
|
181826
181990
|
}
|
|
181827
181991
|
async function readEnv(envDir, fs3) {
|
|
181828
181992
|
try {
|
|
@@ -182319,17 +182483,21 @@ async function findFlowStamp(flowAbsPath) {
|
|
|
182319
182483
|
|
|
182320
182484
|
// src/domains/install/browsers.ts
|
|
182321
182485
|
async function installBrowserList(ctx, browsers, deps) {
|
|
182322
|
-
const
|
|
182323
|
-
|
|
182324
|
-
|
|
182325
|
-
throw new Error(installMessages.playwrightNotFound(candidates[0] ?? deps.envDir));
|
|
182486
|
+
const cliJsPath = playwrightCliJsPath(deps.envDir);
|
|
182487
|
+
if (!deps.checkExists(cliJsPath)) {
|
|
182488
|
+
throw new Error(installMessages.playwrightNotFound(cliJsPath));
|
|
182326
182489
|
}
|
|
182327
182490
|
await ctx.ui.withProgress(browsers.map((browser) => ({
|
|
182328
182491
|
message: installMessages.installingBrowser(browser),
|
|
182329
182492
|
task: async () => {
|
|
182330
|
-
const
|
|
182331
|
-
|
|
182332
|
-
|
|
182493
|
+
const invocation = playwrightCliInvocation({
|
|
182494
|
+
envDir: deps.envDir,
|
|
182495
|
+
execPath: deps.execPath,
|
|
182496
|
+
cliArgs: buildArgs(browser, deps.platform, deps.browserDeps)
|
|
182497
|
+
});
|
|
182498
|
+
const result = await deps.spawn(invocation.cmd, invocation.args, {
|
|
182499
|
+
platform: deps.platform,
|
|
182500
|
+
env: invocation.env
|
|
182333
182501
|
});
|
|
182334
182502
|
if (result.exitCode !== 0) {
|
|
182335
182503
|
throw new Error(formatError2(browser, result));
|
|
@@ -182347,6 +182515,7 @@ async function installBrowsers(ctx, pattern, deps) {
|
|
|
182347
182515
|
}
|
|
182348
182516
|
await installBrowserList(ctx, browsers, {
|
|
182349
182517
|
spawn: deps.spawn,
|
|
182518
|
+
execPath: deps.execPath,
|
|
182350
182519
|
platform: deps.platform,
|
|
182351
182520
|
browserDeps: deps.browserDeps,
|
|
182352
182521
|
envDir: await deps.resolveDepsRoot(files),
|
|
@@ -183221,14 +183390,14 @@ async function runWebFlow({
|
|
|
183221
183390
|
|
|
183222
183391
|
// src/shell/embeddedWorkerCli.ts
|
|
183223
183392
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
183224
|
-
import { basename as basename6, join as
|
|
183393
|
+
import { basename as basename6, join as join35 } from "node:path";
|
|
183225
183394
|
var embeddedCliPathEnv = "QAWOLF_EMBEDDED_CLI_PATH";
|
|
183226
183395
|
function extractEmbeddedWorkerCli() {
|
|
183227
183396
|
const assetPath = process.env[embeddedCliPathEnv];
|
|
183228
183397
|
if (assetPath === undefined || assetPath === "")
|
|
183229
183398
|
return;
|
|
183230
|
-
const dir =
|
|
183231
|
-
const dest =
|
|
183399
|
+
const dir = join35(getDataDir(), "worker");
|
|
183400
|
+
const dest = join35(dir, basename6(assetPath));
|
|
183232
183401
|
if (existsSync3(dest))
|
|
183233
183402
|
return dest;
|
|
183234
183403
|
mkdirSync3(dir, { recursive: true });
|
|
@@ -183387,51 +183556,6 @@ import { dirname as dirname12 } from "node:path";
|
|
|
183387
183556
|
|
|
183388
183557
|
// src/shell/reporter/createConsoleReporter.ts
|
|
183389
183558
|
import { styleText as styleText3 } from "node:util";
|
|
183390
|
-
|
|
183391
|
-
// src/shell/reporter/formatErrorWithCause.ts
|
|
183392
|
-
function filterStack(stack) {
|
|
183393
|
-
const cwd = process.cwd();
|
|
183394
|
-
return stack.split(`
|
|
183395
|
-
`).filter((line) => {
|
|
183396
|
-
if (!/^\s+at /.test(line))
|
|
183397
|
-
return true;
|
|
183398
|
-
return !line.includes("node_modules") && !line.includes("dist/cli.js");
|
|
183399
|
-
}).map((line) => {
|
|
183400
|
-
if (!/^\s+at /.test(line))
|
|
183401
|
-
return line;
|
|
183402
|
-
return line.replace(`file://${cwd}/`, "").replace(`${cwd}/`, "");
|
|
183403
|
-
}).join(`
|
|
183404
|
-
`);
|
|
183405
|
-
}
|
|
183406
|
-
function renderCause(cause) {
|
|
183407
|
-
if (cause instanceof Error)
|
|
183408
|
-
return filterStack(cause.stack ?? cause.message);
|
|
183409
|
-
if (typeof cause === "object" && cause !== null) {
|
|
183410
|
-
const obj = cause;
|
|
183411
|
-
if (typeof obj["message"] === "string")
|
|
183412
|
-
return obj["message"];
|
|
183413
|
-
try {
|
|
183414
|
-
return JSON.stringify(cause);
|
|
183415
|
-
} catch {
|
|
183416
|
-
return String(cause);
|
|
183417
|
-
}
|
|
183418
|
-
}
|
|
183419
|
-
return String(cause);
|
|
183420
|
-
}
|
|
183421
|
-
function formatErrorWithCause(err) {
|
|
183422
|
-
const parts = [String(err)];
|
|
183423
|
-
let cause = err.cause;
|
|
183424
|
-
while (cause !== undefined && cause !== null) {
|
|
183425
|
-
parts.push(`Caused by: ${renderCause(cause)}`);
|
|
183426
|
-
if (!(cause instanceof Error))
|
|
183427
|
-
break;
|
|
183428
|
-
cause = cause.cause;
|
|
183429
|
-
}
|
|
183430
|
-
return parts.join(`
|
|
183431
|
-
`);
|
|
183432
|
-
}
|
|
183433
|
-
|
|
183434
|
-
// src/shell/reporter/createConsoleReporter.ts
|
|
183435
183559
|
function fmtDuration(ms2) {
|
|
183436
183560
|
return `(${(ms2 / 1000).toFixed(2)}s)`;
|
|
183437
183561
|
}
|
|
@@ -183510,30 +183634,8 @@ ${styleText3("dim", "─".repeat(width))}
|
|
|
183510
183634
|
}
|
|
183511
183635
|
};
|
|
183512
183636
|
}
|
|
183513
|
-
// src/shell/reporter/createCompositeReporter.ts
|
|
183514
|
-
function callEach(reporters, pick2, event) {
|
|
183515
|
-
for (const r2 of reporters) {
|
|
183516
|
-
try {
|
|
183517
|
-
pick2(r2)?.(event);
|
|
183518
|
-
} catch (err) {
|
|
183519
|
-
process.stderr.write(`[reporter error] ${String(err)}
|
|
183520
|
-
`);
|
|
183521
|
-
}
|
|
183522
|
-
}
|
|
183523
|
-
}
|
|
183524
|
-
function createCompositeReporter(reporters) {
|
|
183525
|
-
return {
|
|
183526
|
-
onFlowStart: (e) => callEach(reporters, (r2) => r2.onFlowStart, e),
|
|
183527
|
-
onFlowPass: (e) => callEach(reporters, (r2) => r2.onFlowPass, e),
|
|
183528
|
-
onFlowFail: (e) => callEach(reporters, (r2) => r2.onFlowFail, e),
|
|
183529
|
-
onTestStart: (e) => callEach(reporters, (r2) => r2.onTestStart, e),
|
|
183530
|
-
onTestResult: (e) => callEach(reporters, (r2) => r2.onTestResult, e),
|
|
183531
|
-
onScreenshot: (e) => callEach(reporters, (r2) => r2.onScreenshot, e),
|
|
183532
|
-
onRunComplete: (e) => callEach(reporters, (r2) => r2.onRunComplete, e)
|
|
183533
|
-
};
|
|
183534
|
-
}
|
|
183535
183637
|
// src/shell/reporter/createJUnitReporter.ts
|
|
183536
|
-
import { join as
|
|
183638
|
+
import { join as join36 } from "node:path";
|
|
183537
183639
|
|
|
183538
183640
|
// src/shell/reporter/junitXml.ts
|
|
183539
183641
|
function escapeXml(str) {
|
|
@@ -183572,7 +183674,7 @@ ${suites}`;
|
|
|
183572
183674
|
|
|
183573
183675
|
// src/shell/reporter/createJUnitReporter.ts
|
|
183574
183676
|
function resolveJUnitOutputPath(junit, outputDir) {
|
|
183575
|
-
return typeof junit === "string" && junit.trim() !== "" ? junit :
|
|
183677
|
+
return typeof junit === "string" && junit.trim() !== "" ? junit : join36(outputDir, "junit-report.xml");
|
|
183576
183678
|
}
|
|
183577
183679
|
function createJUnitReporter(deps) {
|
|
183578
183680
|
const flows = [];
|
|
@@ -183634,6 +183736,7 @@ function buildFlowsRunDeps(args) {
|
|
|
183634
183736
|
peekFlowMeta: makePeekFlowMeta(ctx.fs),
|
|
183635
183737
|
installBrowsers: (innerCtx, browsers) => installBrowserList(innerCtx, browsers, {
|
|
183636
183738
|
spawn: defaultSpawn,
|
|
183739
|
+
execPath: process.execPath,
|
|
183637
183740
|
platform: process.platform,
|
|
183638
183741
|
browserDeps: flags.browserDeps,
|
|
183639
183742
|
envDir: resolvedDir,
|
|
@@ -183661,11 +183764,11 @@ function buildFlowsRunDeps(args) {
|
|
|
183661
183764
|
|
|
183662
183765
|
// src/commands/flows/loadEnvFile.ts
|
|
183663
183766
|
import { readFile } from "node:fs/promises";
|
|
183664
|
-
import { join as
|
|
183767
|
+
import { join as join37 } from "node:path";
|
|
183665
183768
|
async function loadEnvFile(envDir) {
|
|
183666
183769
|
let content;
|
|
183667
183770
|
try {
|
|
183668
|
-
content = await readFile(
|
|
183771
|
+
content = await readFile(join37(envDir, ".env"), "utf8");
|
|
183669
183772
|
} catch (err) {
|
|
183670
183773
|
if (isNoEntError(err))
|
|
183671
183774
|
return;
|
|
@@ -183766,7 +183869,7 @@ async function handleFlowsRun(ctx, pattern, flags, deps) {
|
|
|
183766
183869
|
}
|
|
183767
183870
|
|
|
183768
183871
|
// src/commands/flows/hybridRunDefaults.ts
|
|
183769
|
-
import { join as
|
|
183872
|
+
import { join as join38, resolve as resolve10 } from "node:path";
|
|
183770
183873
|
function makeDefaultHybridDeps(fs9) {
|
|
183771
183874
|
return {
|
|
183772
183875
|
expandPatterns: (patterns, cwd, logger) => expandPatterns(patterns, cwd, logger, fs9),
|
|
@@ -183785,7 +183888,7 @@ async function handleHybridFlowsRun(ctx, pattern, flags, deps) {
|
|
|
183785
183888
|
if (validation !== "ok") {
|
|
183786
183889
|
return { error: validation.error, exitCode: 2 };
|
|
183787
183890
|
}
|
|
183788
|
-
const envDir = resolve10(
|
|
183891
|
+
const envDir = resolve10(join38(".qawolf", flags.env));
|
|
183789
183892
|
const patternArgs = buildPatternArgs(pattern);
|
|
183790
183893
|
const globFlows = () => resolvedDeps.expandPatterns(patternArgs, envDir, ctx.log("flows"));
|
|
183791
183894
|
let files = await globFlows();
|
|
@@ -183931,7 +184034,100 @@ function registerFlowsCommand(program2, signals) {
|
|
|
183931
184034
|
}
|
|
183932
184035
|
|
|
183933
184036
|
// src/domains/init/init.ts
|
|
183934
|
-
import { dirname as dirname13, join as
|
|
184037
|
+
import { dirname as dirname13, join as join40, relative as relative7 } from "node:path";
|
|
184038
|
+
|
|
184039
|
+
// src/domains/init/ensurePackageJson.ts
|
|
184040
|
+
import { join as join39 } from "node:path";
|
|
184041
|
+
async function ensurePackageJson(ctx, yes, deps) {
|
|
184042
|
+
const pkgPath = join39(deps.cwd, "package.json");
|
|
184043
|
+
if (!await deps.fs.pathExists(pkgPath)) {
|
|
184044
|
+
const confirmed2 = await ctx.ui.confirm(initMessages.createPackageJsonPrompt, { yes });
|
|
184045
|
+
if (!confirmed2.ok || !confirmed2.value) {
|
|
184046
|
+
ctx.ui.info(initMessages.skippedCreatingPackageJson);
|
|
184047
|
+
return;
|
|
184048
|
+
}
|
|
184049
|
+
const pkg2 = {
|
|
184050
|
+
private: true,
|
|
184051
|
+
type: "module",
|
|
184052
|
+
dependencies: { "@qawolf/flows": flowsVersion },
|
|
184053
|
+
scripts: { "test:e2e": "qawolf flows run" }
|
|
184054
|
+
};
|
|
184055
|
+
await deps.fs.writeFile(pkgPath, JSON.stringify(pkg2, undefined, 2) + `
|
|
184056
|
+
`);
|
|
184057
|
+
ctx.ui.step(initMessages.createdPackageJson);
|
|
184058
|
+
return;
|
|
184059
|
+
}
|
|
184060
|
+
const raw = await deps.fs.readFile(pkgPath);
|
|
184061
|
+
let parsed;
|
|
184062
|
+
try {
|
|
184063
|
+
parsed = JSON.parse(raw);
|
|
184064
|
+
} catch {
|
|
184065
|
+
ctx.ui.warn(initMessages.packageJsonInvalidJson);
|
|
184066
|
+
return;
|
|
184067
|
+
}
|
|
184068
|
+
if (!isRecord3(parsed)) {
|
|
184069
|
+
ctx.ui.warn(initMessages.packageJsonNotAnObject);
|
|
184070
|
+
return;
|
|
184071
|
+
}
|
|
184072
|
+
const pkg = parsed;
|
|
184073
|
+
const scripts = readSection(ctx, pkg, "scripts");
|
|
184074
|
+
const dependencies = readSection(ctx, pkg, "dependencies");
|
|
184075
|
+
const devDependencies = readSection(ctx, pkg, "devDependencies");
|
|
184076
|
+
const needScript = scripts !== undefined && !scripts["test:e2e"];
|
|
184077
|
+
const priorType = pkg["type"];
|
|
184078
|
+
const needType = priorType !== "module";
|
|
184079
|
+
const needFlowsDep = dependencies !== undefined && !dependencies["@qawolf/flows"] && !devDependencies?.["@qawolf/flows"];
|
|
184080
|
+
const changes = [];
|
|
184081
|
+
if (needScript)
|
|
184082
|
+
changes.push(initMessages.pkgChanges.script);
|
|
184083
|
+
if (needType)
|
|
184084
|
+
changes.push(initMessages.pkgChanges.type);
|
|
184085
|
+
if (needFlowsDep)
|
|
184086
|
+
changes.push(initMessages.pkgChanges.flowsDep);
|
|
184087
|
+
if (changes.length === 0) {
|
|
184088
|
+
ctx.ui.info(initMessages.packageJsonUpToDate);
|
|
184089
|
+
return;
|
|
184090
|
+
}
|
|
184091
|
+
if (scripts !== undefined && scripts["test:e2e"]) {
|
|
184092
|
+
ctx.ui.warn(initMessages.packageJsonHasTestE2e);
|
|
184093
|
+
}
|
|
184094
|
+
const confirmed = await ctx.ui.confirm(initMessages.updatePackageJsonPrompt(changes), { yes, destructive: true });
|
|
184095
|
+
if (!confirmed.ok || !confirmed.value) {
|
|
184096
|
+
ctx.ui.info(initMessages.skippedUpdatingPackageJson);
|
|
184097
|
+
return;
|
|
184098
|
+
}
|
|
184099
|
+
if (needScript && scripts !== undefined) {
|
|
184100
|
+
scripts["test:e2e"] = "qawolf flows run";
|
|
184101
|
+
pkg["scripts"] = scripts;
|
|
184102
|
+
}
|
|
184103
|
+
if (needType)
|
|
184104
|
+
pkg["type"] = "module";
|
|
184105
|
+
if (needFlowsDep && dependencies !== undefined) {
|
|
184106
|
+
dependencies["@qawolf/flows"] = flowsVersion;
|
|
184107
|
+
pkg["dependencies"] = dependencies;
|
|
184108
|
+
}
|
|
184109
|
+
const trailingNewline = raw.endsWith(`
|
|
184110
|
+
`) ? `
|
|
184111
|
+
` : "";
|
|
184112
|
+
await deps.fs.writeFile(pkgPath, JSON.stringify(pkg, undefined, 2) + trailingNewline);
|
|
184113
|
+
ctx.ui.step(initMessages.updatedPackageJson);
|
|
184114
|
+
if (needType && priorType !== undefined) {
|
|
184115
|
+
const label = typeof priorType === "string" ? priorType : JSON.stringify(priorType);
|
|
184116
|
+
ctx.ui.warn(initMessages.typeChanged(label));
|
|
184117
|
+
}
|
|
184118
|
+
}
|
|
184119
|
+
function isRecord3(value) {
|
|
184120
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
184121
|
+
}
|
|
184122
|
+
function readSection(ctx, pkg, key) {
|
|
184123
|
+
const value = pkg[key];
|
|
184124
|
+
if (value === undefined)
|
|
184125
|
+
return {};
|
|
184126
|
+
if (isRecord3(value))
|
|
184127
|
+
return value;
|
|
184128
|
+
ctx.ui.warn(initMessages.packageJsonMalformedSection(key));
|
|
184129
|
+
return;
|
|
184130
|
+
}
|
|
183935
184131
|
|
|
183936
184132
|
// src/domains/init/templates.ts
|
|
183937
184133
|
var qawolfConfigTs = `export default {
|
|
@@ -183969,9 +184165,9 @@ function makeDefaultInitDeps() {
|
|
|
183969
184165
|
async function handleInit(ctx, opts, deps = makeDefaultInitDeps()) {
|
|
183970
184166
|
ctx.ui.gap();
|
|
183971
184167
|
ctx.ui.intro(initMessages.title);
|
|
183972
|
-
const configPath =
|
|
183973
|
-
const flowPath =
|
|
183974
|
-
const gitignorePath =
|
|
184168
|
+
const configPath = join40(deps.cwd, "qawolf.config.ts");
|
|
184169
|
+
const flowPath = join40(deps.cwd, "src", "flows", "example.flow.ts");
|
|
184170
|
+
const gitignorePath = join40(deps.cwd, ".qawolf", ".gitignore");
|
|
183975
184171
|
await writeWithPrompt(ctx, configPath, qawolfConfigTs, opts.yes, deps);
|
|
183976
184172
|
await writeWithPrompt(ctx, flowPath, exampleFlowTs, opts.yes, deps);
|
|
183977
184173
|
await writeWithPrompt(ctx, gitignorePath, qawolfGitignore, opts.yes, deps);
|
|
@@ -183994,54 +184190,6 @@ async function writeWithPrompt(ctx, filePath, content, yes, deps) {
|
|
|
183994
184190
|
await deps.fs.writeFile(filePath, content);
|
|
183995
184191
|
ctx.ui.step(initMessages.createdFile(relPath));
|
|
183996
184192
|
}
|
|
183997
|
-
async function ensurePackageJson(ctx, yes, deps) {
|
|
183998
|
-
const pkgPath = join38(deps.cwd, "package.json");
|
|
183999
|
-
if (!await deps.fs.pathExists(pkgPath)) {
|
|
184000
|
-
const confirmed2 = await ctx.ui.confirm(initMessages.createPackageJsonPrompt, { yes });
|
|
184001
|
-
if (!confirmed2.ok || !confirmed2.value) {
|
|
184002
|
-
ctx.ui.info(initMessages.skippedCreatingPackageJson);
|
|
184003
|
-
return;
|
|
184004
|
-
}
|
|
184005
|
-
const pkg2 = {
|
|
184006
|
-
private: true,
|
|
184007
|
-
type: "module",
|
|
184008
|
-
dependencies: { "@qawolf/flows": flowsVersion },
|
|
184009
|
-
scripts: { "test:e2e": "qawolf flows run" }
|
|
184010
|
-
};
|
|
184011
|
-
await deps.fs.writeFile(pkgPath, JSON.stringify(pkg2, undefined, 2) + `
|
|
184012
|
-
`);
|
|
184013
|
-
ctx.ui.step(initMessages.createdPackageJson);
|
|
184014
|
-
return;
|
|
184015
|
-
}
|
|
184016
|
-
const raw = await deps.fs.readFile(pkgPath);
|
|
184017
|
-
let pkg;
|
|
184018
|
-
try {
|
|
184019
|
-
pkg = JSON.parse(raw);
|
|
184020
|
-
} catch {
|
|
184021
|
-
ctx.ui.warn(initMessages.packageJsonInvalidJson);
|
|
184022
|
-
return;
|
|
184023
|
-
}
|
|
184024
|
-
const scripts = pkg["scripts"] ?? {};
|
|
184025
|
-
if (scripts["test:e2e"]) {
|
|
184026
|
-
ctx.ui.warn(initMessages.packageJsonHasTestE2e);
|
|
184027
|
-
return;
|
|
184028
|
-
}
|
|
184029
|
-
const confirmed = await ctx.ui.confirm(initMessages.addTestE2ePrompt, {
|
|
184030
|
-
yes,
|
|
184031
|
-
destructive: true
|
|
184032
|
-
});
|
|
184033
|
-
if (!confirmed.ok || !confirmed.value) {
|
|
184034
|
-
ctx.ui.info(initMessages.skippedAddingTestE2e);
|
|
184035
|
-
return;
|
|
184036
|
-
}
|
|
184037
|
-
scripts["test:e2e"] = "qawolf flows run";
|
|
184038
|
-
pkg["scripts"] = scripts;
|
|
184039
|
-
const trailingNewline = raw.endsWith(`
|
|
184040
|
-
`) ? `
|
|
184041
|
-
` : "";
|
|
184042
|
-
await deps.fs.writeFile(pkgPath, JSON.stringify(pkg, undefined, 2) + trailingNewline);
|
|
184043
|
-
ctx.ui.step(initMessages.updatedPackageJson);
|
|
184044
|
-
}
|
|
184045
184193
|
|
|
184046
184194
|
// src/commands/init/index.ts
|
|
184047
184195
|
function registerInitCommand(program2, signals) {
|
|
@@ -184057,7 +184205,7 @@ Examples:
|
|
|
184057
184205
|
import { parseExecutionTarget as parseExecutionTarget4 } from "@qawolf/flow-targets";
|
|
184058
184206
|
|
|
184059
184207
|
// src/domains/install/android/avd.ts
|
|
184060
|
-
import { join as
|
|
184208
|
+
import { join as join41 } from "node:path";
|
|
184061
184209
|
async function installAvds(ctx, specs, deps) {
|
|
184062
184210
|
const sdkManagerPath = sdkManagerBin(deps.androidHome, deps.platform);
|
|
184063
184211
|
const avdManagerPath = avdManagerBin(deps.androidHome, deps.platform);
|
|
@@ -184067,7 +184215,7 @@ async function installAvds(ctx, specs, deps) {
|
|
|
184067
184215
|
if (versionResult.exitCode !== 0) {
|
|
184068
184216
|
throw new Error(installMessages.android.sdkmanagerNotFound(sdkManagerPath));
|
|
184069
184217
|
}
|
|
184070
|
-
const licenseFile =
|
|
184218
|
+
const licenseFile = join41(deps.androidHome, "licenses", "android-sdk-license");
|
|
184071
184219
|
if (deps.checkExists(licenseFile)) {
|
|
184072
184220
|
ctx.ui.info(installMessages.android.licensesAlreadyAccepted);
|
|
184073
184221
|
} else {
|
|
@@ -184082,7 +184230,7 @@ async function installAvds(ctx, specs, deps) {
|
|
|
184082
184230
|
for (const spec of specs) {
|
|
184083
184231
|
if (installedImages.has(spec.systemImage))
|
|
184084
184232
|
continue;
|
|
184085
|
-
const systemImg =
|
|
184233
|
+
const systemImg = join41(deps.androidHome, ...spec.systemImage.split(";"), "system.img");
|
|
184086
184234
|
if (deps.checkExists(systemImg)) {
|
|
184087
184235
|
ctx.ui.info(installMessages.android.systemImageAlreadyInstalled(spec.systemImage));
|
|
184088
184236
|
installedImages.add(spec.systemImage);
|
|
@@ -184236,6 +184384,7 @@ async function handleInstallBrowsers(ctx, pattern, options) {
|
|
|
184236
184384
|
return installBrowsers(ctx, pattern, {
|
|
184237
184385
|
cwd,
|
|
184238
184386
|
spawn: defaultSpawn,
|
|
184387
|
+
execPath: process.execPath,
|
|
184239
184388
|
platform: process.platform,
|
|
184240
184389
|
browserDeps,
|
|
184241
184390
|
expandPatterns: (patterns, dir) => expandPatterns(patterns, dir ?? cwd, undefined, fs9),
|
|
@@ -184644,7 +184793,7 @@ async function handlePublicApiCommand(ctx, spec, options) {
|
|
|
184644
184793
|
return { error: exports_external.prettifyError(parsed.error) };
|
|
184645
184794
|
const result = await ctx.platformClient.callPublicApi(spec.contract, parsed.data);
|
|
184646
184795
|
if (!result.ok)
|
|
184647
|
-
return
|
|
184796
|
+
return failureFields(result);
|
|
184648
184797
|
ctx.ui.output(result.value, renderHuman(result.value));
|
|
184649
184798
|
return;
|
|
184650
184799
|
}
|
|
@@ -184656,8 +184805,16 @@ var groupDescriptions = {
|
|
|
184656
184805
|
var handWrittenContractNames = new Set(["flow.list"]);
|
|
184657
184806
|
var skippedContractNames = new Set([
|
|
184658
184807
|
...handWrittenContractNames,
|
|
184659
|
-
"issue.update"
|
|
184808
|
+
"issue.update",
|
|
184809
|
+
"runner.performAction"
|
|
184660
184810
|
]);
|
|
184811
|
+
var optionEnvironmentVariables = new Map([
|
|
184812
|
+
["environmentId", "QAWOLF_ENVIRONMENT"],
|
|
184813
|
+
["public.run.create.aiTaskId", "QAWOLF_AI_TASK_ID"]
|
|
184814
|
+
]);
|
|
184815
|
+
function optionEnvironmentVariable(spec, field) {
|
|
184816
|
+
return optionEnvironmentVariables.get(`${spec.trpcPath}.${field}`) ?? optionEnvironmentVariables.get(field);
|
|
184817
|
+
}
|
|
184661
184818
|
function resolveGroup(parent2, segment) {
|
|
184662
184819
|
const existing = parent2.commands.find((command) => command.name() === segment);
|
|
184663
184820
|
return existing ?? parent2.command(segment).description(groupDescriptions[segment] ?? `QA Wolf public API ${segment} commands`);
|
|
@@ -184674,7 +184831,13 @@ function registerSpec(program2, signals, spec, authDeps) {
|
|
|
184674
184831
|
}
|
|
184675
184832
|
const command = declareCommandKind(parent2.command(leafName), spec.kind).description(spec.description);
|
|
184676
184833
|
for (const flag of spec.flags) {
|
|
184677
|
-
|
|
184834
|
+
const environmentVariable = optionEnvironmentVariable(spec, flag.field);
|
|
184835
|
+
if (environmentVariable) {
|
|
184836
|
+
const option = new Option(flag.flag, flag.description).env(environmentVariable);
|
|
184837
|
+
if (flag.required)
|
|
184838
|
+
option.makeOptionMandatory();
|
|
184839
|
+
command.addOption(option);
|
|
184840
|
+
} else if (flag.required) {
|
|
184678
184841
|
command.requiredOption(flag.flag, flag.description);
|
|
184679
184842
|
} else {
|
|
184680
184843
|
command.option(flag.flag, flag.description);
|
|
@@ -184726,4 +184889,4 @@ createProgram({ signals }).parseAsync().catch(() => {
|
|
|
184726
184889
|
process.exitCode = 1;
|
|
184727
184890
|
}).finally(() => flushAndExit(typeof process.exitCode === "number" ? process.exitCode : 0));
|
|
184728
184891
|
|
|
184729
|
-
//# debugId=
|
|
184892
|
+
//# debugId=6CBE0567ED2CC02E64756E2164756E21
|