@qawolf/cli 1.7.3 → 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 +97 -43
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -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) {
|
|
@@ -170194,49 +170194,86 @@ function createLoggingSystem(opts) {
|
|
|
170194
170194
|
};
|
|
170195
170195
|
}
|
|
170196
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
|
+
|
|
170197
170238
|
// src/shell/platform/describeErrors.ts
|
|
170198
170239
|
var m = authMessages.errors;
|
|
170240
|
+
var inlineReasonMaxLength = 200;
|
|
170199
170241
|
function describeIdentityError(err) {
|
|
170200
170242
|
if (err.kind === "http") {
|
|
170201
170243
|
if (err.status === 401 || err.status === 403) {
|
|
170202
|
-
return m.identity.invalidOrUnauthorized;
|
|
170244
|
+
return { error: m.identity.invalidOrUnauthorized };
|
|
170203
170245
|
}
|
|
170204
|
-
return
|
|
170246
|
+
return {
|
|
170247
|
+
error: m.identity.couldNotVerify(parseErrorBody(err.body, inlineReasonMaxLength), err.status)
|
|
170248
|
+
};
|
|
170205
170249
|
}
|
|
170206
170250
|
if (err.kind === "network") {
|
|
170207
|
-
return m.identity.couldNotVerifyNetwork(err.cause.message);
|
|
170251
|
+
return { error: m.identity.couldNotVerifyNetwork(err.cause.message) };
|
|
170208
170252
|
}
|
|
170209
|
-
if (err.kind === "timeout")
|
|
170210
|
-
return m.identity.timedOut(err.timeoutMs);
|
|
170211
|
-
|
|
170212
|
-
}
|
|
170213
|
-
function parseErrorBody(body) {
|
|
170214
|
-
if (!body)
|
|
170215
|
-
return "";
|
|
170216
|
-
try {
|
|
170217
|
-
const parsed = JSON.parse(body);
|
|
170218
|
-
if (typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "string") {
|
|
170219
|
-
return parsed.error;
|
|
170220
|
-
}
|
|
170221
|
-
} catch {}
|
|
170222
|
-
return "";
|
|
170253
|
+
if (err.kind === "timeout") {
|
|
170254
|
+
return { error: m.identity.timedOut(err.timeoutMs) };
|
|
170255
|
+
}
|
|
170256
|
+
return { error: m.identity.unexpectedFormat };
|
|
170223
170257
|
}
|
|
170224
170258
|
function describeRequestError(err, baseUrl, noun) {
|
|
170225
170259
|
if (err.kind === "http") {
|
|
170260
|
+
const reason = parseErrorBody(err.body);
|
|
170261
|
+
const body = reason ? { errorBody: reason } : {};
|
|
170226
170262
|
if (err.status === 401)
|
|
170227
|
-
return m.request.rejected401(noun);
|
|
170263
|
+
return { error: m.request.rejected401(noun), ...body };
|
|
170228
170264
|
if (err.status === 403)
|
|
170229
|
-
return m.request.rejected403(noun);
|
|
170265
|
+
return { error: m.request.rejected403(noun), ...body };
|
|
170230
170266
|
if (err.status === 404)
|
|
170231
|
-
return m.request.notFound404(noun);
|
|
170232
|
-
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 };
|
|
170233
170269
|
}
|
|
170234
170270
|
if (err.kind === "network") {
|
|
170235
|
-
return m.request.networkUnreachable(baseUrl, noun);
|
|
170271
|
+
return { error: m.request.networkUnreachable(baseUrl, noun) };
|
|
170236
170272
|
}
|
|
170237
|
-
if (err.kind === "timeout")
|
|
170238
|
-
return m.request.timedOut(err.timeoutMs, noun);
|
|
170239
|
-
|
|
170273
|
+
if (err.kind === "timeout") {
|
|
170274
|
+
return { error: m.request.timedOut(err.timeoutMs, noun) };
|
|
170275
|
+
}
|
|
170276
|
+
return { error: m.request.unexpectedResponse(noun) };
|
|
170240
170277
|
}
|
|
170241
170278
|
function describeBundleDownloadError(err) {
|
|
170242
170279
|
if (err.kind === "http") {
|
|
@@ -170271,6 +170308,9 @@ import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
|
170271
170308
|
var sleep = (ms) => setTimeout2(ms);
|
|
170272
170309
|
|
|
170273
170310
|
// src/shell/platform/requestWithRetry.ts
|
|
170311
|
+
function failureFields(failure) {
|
|
170312
|
+
return failure.errorBody ? { error: failure.error, errorBody: failure.errorBody } : { error: failure.error };
|
|
170313
|
+
}
|
|
170274
170314
|
async function requestWithRetry(args) {
|
|
170275
170315
|
const sleep2 = args.sleep ?? sleep;
|
|
170276
170316
|
for (let attempt = 0;; attempt++) {
|
|
@@ -170280,7 +170320,7 @@ async function requestWithRetry(args) {
|
|
|
170280
170320
|
const backoff = args.backoffMs[attempt];
|
|
170281
170321
|
const retryable = result.error.kind === "network" || result.error.kind === "timeout";
|
|
170282
170322
|
if (backoff === undefined || !retryable) {
|
|
170283
|
-
return { ok: false,
|
|
170323
|
+
return { ok: false, ...args.describe(result.error) };
|
|
170284
170324
|
}
|
|
170285
170325
|
await sleep2(backoff);
|
|
170286
170326
|
}
|
|
@@ -171185,15 +171225,15 @@ function createTrpcClient(apiKey, deps) {
|
|
|
171185
171225
|
}
|
|
171186
171226
|
};
|
|
171187
171227
|
}
|
|
171188
|
-
function
|
|
171228
|
+
function clip2(text) {
|
|
171189
171229
|
return text.length > 200 ? text.slice(0, 200) + "…" : text;
|
|
171190
171230
|
}
|
|
171191
171231
|
function summarize(error51) {
|
|
171192
171232
|
if (error51.kind === "http")
|
|
171193
|
-
return `${error51.status} ${
|
|
171233
|
+
return `${error51.status} ${clip2(error51.body)}`;
|
|
171194
171234
|
if (error51.kind === "timeout")
|
|
171195
171235
|
return `timed out after ${error51.timeoutMs}ms`;
|
|
171196
|
-
return
|
|
171236
|
+
return clip2(error51.cause.message);
|
|
171197
171237
|
}
|
|
171198
171238
|
|
|
171199
171239
|
// src/shell/platform/downloadBundle.ts
|
|
@@ -174626,7 +174666,7 @@ function startUpdateCheck(deps) {
|
|
|
174626
174666
|
// package.json
|
|
174627
174667
|
var package_default = {
|
|
174628
174668
|
name: "@qawolf/cli",
|
|
174629
|
-
version: "1.7.
|
|
174669
|
+
version: "1.7.4",
|
|
174630
174670
|
description: "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
174631
174671
|
keywords: [
|
|
174632
174672
|
"automation",
|
|
@@ -177089,9 +177129,8 @@ async function flowsListRemote(ctx, pattern, options) {
|
|
|
177089
177129
|
environmentId: options.env,
|
|
177090
177130
|
includeDrafts: options.includeDrafts
|
|
177091
177131
|
});
|
|
177092
|
-
if (!result.ok)
|
|
177093
|
-
return
|
|
177094
|
-
}
|
|
177132
|
+
if (!result.ok)
|
|
177133
|
+
return failureFields(result);
|
|
177095
177134
|
const matches = pattern ? import_picomatch2.default(pattern) : undefined;
|
|
177096
177135
|
const items = result.value.flows.filter((f2) => !matches || matches(f2.path)).map((f2) => ({
|
|
177097
177136
|
flowId: f2.flowId,
|
|
@@ -180963,7 +181002,7 @@ var findContract = publicContractsV1.environment.find;
|
|
|
180963
181002
|
async function pickEnvironment(deps) {
|
|
180964
181003
|
const fetched = await fetchAllEnvironments(deps.platformClient);
|
|
180965
181004
|
if (!fetched.ok)
|
|
180966
|
-
return { kind: "error"
|
|
181005
|
+
return { ...failureFields(fetched), kind: "error" };
|
|
180967
181006
|
const environments = fetched.environments;
|
|
180968
181007
|
if (environments.length === 0) {
|
|
180969
181008
|
return { kind: "error", error: environmentsMessages.noEnvironments };
|
|
@@ -181056,6 +181095,7 @@ async function resolveRef2(deps, ref) {
|
|
|
181056
181095
|
});
|
|
181057
181096
|
if (!result.ok) {
|
|
181058
181097
|
return {
|
|
181098
|
+
...failureFields(result),
|
|
181059
181099
|
kind: "error",
|
|
181060
181100
|
error: environmentsMessages.couldNotResolve(ref, result.error)
|
|
181061
181101
|
};
|
|
@@ -181089,7 +181129,7 @@ function withResolvedEnv(signals, args, fn2) {
|
|
|
181089
181129
|
return;
|
|
181090
181130
|
}
|
|
181091
181131
|
if (outcome.kind === "error") {
|
|
181092
|
-
return
|
|
181132
|
+
return failureFields(outcome);
|
|
181093
181133
|
}
|
|
181094
181134
|
return fn2(ctx, outcome.env);
|
|
181095
181135
|
})(opts, command);
|
|
@@ -184753,7 +184793,7 @@ async function handlePublicApiCommand(ctx, spec, options) {
|
|
|
184753
184793
|
return { error: exports_external.prettifyError(parsed.error) };
|
|
184754
184794
|
const result = await ctx.platformClient.callPublicApi(spec.contract, parsed.data);
|
|
184755
184795
|
if (!result.ok)
|
|
184756
|
-
return
|
|
184796
|
+
return failureFields(result);
|
|
184757
184797
|
ctx.ui.output(result.value, renderHuman(result.value));
|
|
184758
184798
|
return;
|
|
184759
184799
|
}
|
|
@@ -184765,8 +184805,16 @@ var groupDescriptions = {
|
|
|
184765
184805
|
var handWrittenContractNames = new Set(["flow.list"]);
|
|
184766
184806
|
var skippedContractNames = new Set([
|
|
184767
184807
|
...handWrittenContractNames,
|
|
184768
|
-
"issue.update"
|
|
184808
|
+
"issue.update",
|
|
184809
|
+
"runner.performAction"
|
|
184769
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
|
+
}
|
|
184770
184818
|
function resolveGroup(parent2, segment) {
|
|
184771
184819
|
const existing = parent2.commands.find((command) => command.name() === segment);
|
|
184772
184820
|
return existing ?? parent2.command(segment).description(groupDescriptions[segment] ?? `QA Wolf public API ${segment} commands`);
|
|
@@ -184783,7 +184831,13 @@ function registerSpec(program2, signals, spec, authDeps) {
|
|
|
184783
184831
|
}
|
|
184784
184832
|
const command = declareCommandKind(parent2.command(leafName), spec.kind).description(spec.description);
|
|
184785
184833
|
for (const flag of spec.flags) {
|
|
184786
|
-
|
|
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) {
|
|
184787
184841
|
command.requiredOption(flag.flag, flag.description);
|
|
184788
184842
|
} else {
|
|
184789
184843
|
command.option(flag.flag, flag.description);
|
|
@@ -184835,4 +184889,4 @@ createProgram({ signals }).parseAsync().catch(() => {
|
|
|
184835
184889
|
process.exitCode = 1;
|
|
184836
184890
|
}).finally(() => flushAndExit(typeof process.exitCode === "number" ? process.exitCode : 0));
|
|
184837
184891
|
|
|
184838
|
-
//# debugId=
|
|
184892
|
+
//# debugId=6CBE0567ED2CC02E64756E2164756E21
|