@qawolf/cli 1.30.0 → 1.31.0
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/runner-sdk.js
CHANGED
|
@@ -9485,7 +9485,14 @@ var authErrorMessages = {
|
|
|
9485
9485
|
rejected401: (noun) => `QA Wolf API rejected the${noun ? ` ${noun}` : ""} request (HTTP 401). Check your API key.`,
|
|
9486
9486
|
rejected402: (noun) => `QA Wolf API refused the${noun ? ` ${noun}` : ""} request (HTTP 402): billing prevented it.`,
|
|
9487
9487
|
rejected403: (noun) => `QA Wolf API rejected the${noun ? ` ${noun}` : ""} request (HTTP 403). Check that your API key has access to this environment.`,
|
|
9488
|
-
|
|
9488
|
+
notFound404Environment: (noun) => `QA Wolf API could not find ${noun ? `${noun} for that environment` : "that environment"} (HTTP 404). Check the --env value.`,
|
|
9489
|
+
notFound404Runner: (runnerId) => runnerId === undefined ? "That runner is not running (HTTP 404)." : `Runner ${runnerId} is not running (HTTP 404).`,
|
|
9490
|
+
runnerIsGone: "It was never launched, or it has since been terminated or idled out.",
|
|
9491
|
+
launchTheRunner: (runnerId) => runnerId === undefined ? "Launch one with qawolf runner launch --id <id>, or name a running one with --runner." : `Launch it with qawolf runner launch --id ${runnerId}, or send this to a different runner with --runner.`,
|
|
9492
|
+
notFound404Run: (runId) => `QA Wolf has no run ${runId ?? "by that id"} on this team (HTTP 404).`,
|
|
9493
|
+
runIdMayBeRunnerLocal: (runId) => `A run id printed by qawolf runner run belongs to that runner rather than to the platform, so this command cannot resolve it. Read that run with qawolf runner events run-status --run ${runId ?? "<id>"}.`,
|
|
9494
|
+
notFound404Record: (noun, id) => `QA Wolf has no ${noun} ${id} (HTTP 404).`,
|
|
9495
|
+
notFound404: (noun) => noun === undefined ? "QA Wolf found nothing matching the request (HTTP 404)." : `QA Wolf found nothing matching the ${noun} request (HTTP 404).`,
|
|
9489
9496
|
failedWithStatus: (status, noun) => `QA Wolf API${noun ? ` ${noun}` : ""} request failed (HTTP ${status}).`,
|
|
9490
9497
|
networkUnreachable: (baseUrl, noun) => `Could not reach the QA Wolf API at ${baseUrl}${noun ? ` to fetch ${noun}` : ""}. Check your network connection and QAWOLF_HOST_URL.`,
|
|
9491
9498
|
timedOut: (timeoutMs, noun) => `The QA Wolf API${noun ? ` ${noun}` : ""} request timed out after ${formatSeconds(timeoutMs)}. The work may still be finishing on the platform.`,
|
|
@@ -9836,7 +9843,14 @@ var lifecycleMessages = {
|
|
|
9836
9843
|
terminated: (id) => `Terminated runner ${id}.`,
|
|
9837
9844
|
runStopped: (id) => `Stopped the run on runner ${id}. The runner is still up, on whatever page the run reached.`,
|
|
9838
9845
|
nothingToStop: (id) => `Runner ${id} had nothing to stop. The run had already finished, or none had been submitted.`,
|
|
9839
|
-
runnerUnreachable: "The runner could not be reached. It may still be starting, or it may have terminated after inactivity. Retry, or launch it again."
|
|
9846
|
+
runnerUnreachable: "The runner could not be reached. It may still be starting, or it may have terminated after inactivity. Retry, or launch it again.",
|
|
9847
|
+
runnerIdCameFrom: (id, source) => ({
|
|
9848
|
+
environment: `The id ${id} came from QAWOLF_RUNNER_ID.`,
|
|
9849
|
+
flag: `The id ${id} came from --runner.`,
|
|
9850
|
+
given: `The id ${id} is the one this call named.`,
|
|
9851
|
+
launched: `Runner ${id} was launched for this command.`,
|
|
9852
|
+
stored: `The id ${id} came from the runner this directory last launched, recorded in .qawolf.`
|
|
9853
|
+
})[source]
|
|
9840
9854
|
};
|
|
9841
9855
|
|
|
9842
9856
|
// src/core/messages/interactiveRunner/list.ts
|
|
@@ -9935,7 +9949,9 @@ ${dir}`,
|
|
|
9935
9949
|
].join(`
|
|
9936
9950
|
`),
|
|
9937
9951
|
outerHopCarriedOver: (names) => `Carried over ${pluralize(names.length, "undeclared package")} from the project node_modules: ${listNames(names)}. Declare them in package.json "dependencies".`,
|
|
9938
|
-
moduleNotFoundHint: (pkg, projectDir) => projectDir === undefined ? `Hint: '${pkg}' could not be resolved. Run from within your flows project so its dependencies can be found.` : `Hint: '${pkg}' could not be resolved. Ensure it is declared in ${projectDir}/package.json "dependencies" and run npm install in that project
|
|
9952
|
+
moduleNotFoundHint: (pkg, projectDir) => projectDir === undefined ? `Hint: '${pkg}' could not be resolved. Run from within your flows project so its dependencies can be found.` : `Hint: '${pkg}' could not be resolved. Ensure it is declared in ${projectDir}/package.json "dependencies" and run npm install in that project.`,
|
|
9953
|
+
tsconfigUnparsedNotice: (projectDir) => `Not resolving path aliases: ${projectDir}/tsconfig.json is not valid JSON. Comments and trailing commas are not supported, here or on the platform. Remove them so "compilerOptions.paths" can be read.`,
|
|
9954
|
+
pathAliasNotFoundHint: (specifier, projectDir) => projectDir === undefined ? `Hint: '${specifier}' looks like a tsconfig path alias. Run from within your flows project so its tsconfig.json can be found.` : `Hint: '${specifier}' looks like a tsconfig path alias. Ensure "compilerOptions.paths" in ${projectDir}/tsconfig.json maps it to a file that exists.`
|
|
9939
9955
|
};
|
|
9940
9956
|
// src/shell/exit.ts
|
|
9941
9957
|
var exitCodes = {
|
|
@@ -9946,7 +9962,8 @@ var exitCodes = {
|
|
|
9946
9962
|
network: 4,
|
|
9947
9963
|
config: 5,
|
|
9948
9964
|
timeout: 6,
|
|
9949
|
-
payment: 7
|
|
9965
|
+
payment: 7,
|
|
9966
|
+
notFound: 8
|
|
9950
9967
|
};
|
|
9951
9968
|
|
|
9952
9969
|
// src/core/sleep.ts
|
|
@@ -10894,41 +10911,70 @@ function isPathAlias(importPath, paths) {
|
|
|
10894
10911
|
// src/core/interactiveRunner/resolveImportPath.ts
|
|
10895
10912
|
import { dirname as dirname2, join, normalize as normalize2 } from "node:path/posix";
|
|
10896
10913
|
|
|
10897
|
-
// src/core/
|
|
10914
|
+
// src/core/aliasImports/tsconfigPaths.ts
|
|
10898
10915
|
function isRecord(value) {
|
|
10899
10916
|
return typeof value === "object" && value !== null;
|
|
10900
10917
|
}
|
|
10901
10918
|
function isTsconfigPaths(value) {
|
|
10902
10919
|
return isRecord(value) && Object.values(value).every((targets) => Array.isArray(targets) && targets.every((target) => typeof target === "string"));
|
|
10903
10920
|
}
|
|
10904
|
-
function
|
|
10921
|
+
function parseTsconfigContent(tsconfigContent) {
|
|
10905
10922
|
let parsed;
|
|
10906
10923
|
try {
|
|
10907
10924
|
parsed = JSON.parse(tsconfigContent);
|
|
10908
10925
|
} catch {
|
|
10909
|
-
return;
|
|
10926
|
+
return { type: "unparseable" };
|
|
10910
10927
|
}
|
|
10911
10928
|
if (!isRecord(parsed))
|
|
10912
|
-
return;
|
|
10929
|
+
return { paths: undefined, type: "parsed" };
|
|
10913
10930
|
const compilerOptions = parsed["compilerOptions"];
|
|
10914
10931
|
if (!isRecord(compilerOptions))
|
|
10915
|
-
return;
|
|
10932
|
+
return { paths: undefined, type: "parsed" };
|
|
10916
10933
|
const paths = compilerOptions["paths"];
|
|
10917
|
-
return
|
|
10934
|
+
return {
|
|
10935
|
+
paths: isTsconfigPaths(paths) ? paths : undefined,
|
|
10936
|
+
type: "parsed"
|
|
10937
|
+
};
|
|
10938
|
+
}
|
|
10939
|
+
function parseTsconfigPaths(tsconfigContent) {
|
|
10940
|
+
const parsed = parseTsconfigContent(tsconfigContent);
|
|
10941
|
+
return parsed.type === "parsed" ? parsed.paths : undefined;
|
|
10942
|
+
}
|
|
10943
|
+
function parseWildcardPattern(pattern) {
|
|
10944
|
+
const wildcard = pattern.indexOf("*");
|
|
10945
|
+
if (wildcard === -1 || wildcard !== pattern.lastIndexOf("*"))
|
|
10946
|
+
return;
|
|
10947
|
+
return {
|
|
10948
|
+
prefix: pattern.slice(0, wildcard),
|
|
10949
|
+
suffix: pattern.slice(wildcard + 1)
|
|
10950
|
+
};
|
|
10951
|
+
}
|
|
10952
|
+
function matchesWildcard(importPath, { prefix, suffix }) {
|
|
10953
|
+
return importPath.length >= prefix.length + suffix.length && importPath.startsWith(prefix) && importPath.endsWith(suffix);
|
|
10954
|
+
}
|
|
10955
|
+
function longestPrefixMatch(importPath, paths) {
|
|
10956
|
+
return Object.entries(paths).flatMap(([pattern, targets]) => {
|
|
10957
|
+
const parsed = parseWildcardPattern(pattern);
|
|
10958
|
+
if (parsed === undefined || !matchesWildcard(importPath, parsed)) {
|
|
10959
|
+
return [];
|
|
10960
|
+
}
|
|
10961
|
+
return [{ pattern: parsed, targets }];
|
|
10962
|
+
}).reduce((best, candidate) => best === undefined || candidate.pattern.prefix.length > best.pattern.prefix.length ? candidate : best, undefined);
|
|
10918
10963
|
}
|
|
10919
10964
|
function resolvePathAlias(importPath, paths) {
|
|
10920
10965
|
if (paths === undefined)
|
|
10921
10966
|
return;
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
|
|
10967
|
+
const [exactTarget] = paths[importPath] ?? [];
|
|
10968
|
+
if (exactTarget !== undefined)
|
|
10969
|
+
return exactTarget;
|
|
10970
|
+
const match = longestPrefixMatch(importPath, paths);
|
|
10971
|
+
if (match === undefined)
|
|
10972
|
+
return;
|
|
10973
|
+
const [target] = match.targets;
|
|
10974
|
+
if (target === undefined)
|
|
10975
|
+
return;
|
|
10976
|
+
const substituted = importPath.slice(match.pattern.prefix.length, importPath.length - match.pattern.suffix.length);
|
|
10977
|
+
return target.replace("*", substituted);
|
|
10932
10978
|
}
|
|
10933
10979
|
|
|
10934
10980
|
// src/core/interactiveRunner/resolveImportPath.ts
|
|
@@ -11366,6 +11412,47 @@ function makeDefaultFs() {
|
|
|
11366
11412
|
};
|
|
11367
11413
|
}
|
|
11368
11414
|
|
|
11415
|
+
// src/core/publicApi/notFoundSubject.ts
|
|
11416
|
+
var runnerRoutesThatNameNoRunner = new Set([
|
|
11417
|
+
"runner.launch",
|
|
11418
|
+
"runner.list"
|
|
11419
|
+
]);
|
|
11420
|
+
var runRoutesThatResolveOneRun = new Set([
|
|
11421
|
+
"run.diagnose",
|
|
11422
|
+
"run.get",
|
|
11423
|
+
"run.reattempt",
|
|
11424
|
+
"run.stop"
|
|
11425
|
+
]);
|
|
11426
|
+
var recordFieldNouns = [
|
|
11427
|
+
["sessionId", "session"],
|
|
11428
|
+
["triggerId", "trigger"],
|
|
11429
|
+
["issueId", "issue"],
|
|
11430
|
+
["flowId", "flow"],
|
|
11431
|
+
["filePath", "file"]
|
|
11432
|
+
];
|
|
11433
|
+
function field(input, name) {
|
|
11434
|
+
if (typeof input !== "object" || input === null)
|
|
11435
|
+
return;
|
|
11436
|
+
const value = input[name];
|
|
11437
|
+
return typeof value === "string" ? value : undefined;
|
|
11438
|
+
}
|
|
11439
|
+
function notFoundSubject(contractName, input) {
|
|
11440
|
+
if (contractName.startsWith("runner.") && !runnerRoutesThatNameNoRunner.has(contractName)) {
|
|
11441
|
+
return { kind: "runner", runnerId: field(input, "id") };
|
|
11442
|
+
}
|
|
11443
|
+
if (runRoutesThatResolveOneRun.has(contractName)) {
|
|
11444
|
+
return { kind: "run", runId: field(input, "runId") };
|
|
11445
|
+
}
|
|
11446
|
+
for (const [name, noun] of recordFieldNouns) {
|
|
11447
|
+
const id = field(input, name);
|
|
11448
|
+
if (id !== undefined)
|
|
11449
|
+
return { id, kind: "record", noun };
|
|
11450
|
+
}
|
|
11451
|
+
if (field(input, "environmentId") !== undefined)
|
|
11452
|
+
return { kind: "environment" };
|
|
11453
|
+
return { kind: "other" };
|
|
11454
|
+
}
|
|
11455
|
+
|
|
11369
11456
|
// src/core/publicApi/flagKind.ts
|
|
11370
11457
|
function flagKind(schema) {
|
|
11371
11458
|
if (schema.type === "string")
|
|
@@ -11536,6 +11623,42 @@ function applyWorkspaceId(inputSchema, input, workspaceId) {
|
|
|
11536
11623
|
return { ...input, workspaceId };
|
|
11537
11624
|
}
|
|
11538
11625
|
|
|
11626
|
+
// src/shell/platform/describeNotFound.ts
|
|
11627
|
+
var m = authMessages.errors.request;
|
|
11628
|
+
var saysNothingMore = (reason) => /^(\w+ )*not ?found\.?$/i.test(reason.trim());
|
|
11629
|
+
function describeNotFound(subject, noun, reason) {
|
|
11630
|
+
const explained = reason && !saysNothingMore(reason) ? reason : undefined;
|
|
11631
|
+
const say = (own) => {
|
|
11632
|
+
const body = [explained ? undefined : own.guess, own.guidance].filter((line) => line);
|
|
11633
|
+
return {
|
|
11634
|
+
error: explained ? `${explained} (HTTP 404)` : own.statement,
|
|
11635
|
+
exitCode: exitCodes.notFound,
|
|
11636
|
+
...body.length > 0 ? { errorBody: body.join(`
|
|
11637
|
+
`) } : {}
|
|
11638
|
+
};
|
|
11639
|
+
};
|
|
11640
|
+
switch (subject?.kind) {
|
|
11641
|
+
case "runner":
|
|
11642
|
+
return say({
|
|
11643
|
+
guess: m.runnerIsGone,
|
|
11644
|
+
guidance: m.launchTheRunner(subject.runnerId),
|
|
11645
|
+
statement: m.notFound404Runner(subject.runnerId)
|
|
11646
|
+
});
|
|
11647
|
+
case "run":
|
|
11648
|
+
return say({
|
|
11649
|
+
guess: m.runIdMayBeRunnerLocal(subject.runId),
|
|
11650
|
+
statement: m.notFound404Run(subject.runId)
|
|
11651
|
+
});
|
|
11652
|
+
case "record":
|
|
11653
|
+
return say({ statement: m.notFound404Record(subject.noun, subject.id) });
|
|
11654
|
+
case "other":
|
|
11655
|
+
return say({ statement: m.notFound404(noun) });
|
|
11656
|
+
case "environment":
|
|
11657
|
+
case undefined:
|
|
11658
|
+
return say({ statement: m.notFound404Environment(noun) });
|
|
11659
|
+
}
|
|
11660
|
+
}
|
|
11661
|
+
|
|
11539
11662
|
// src/shell/platform/parseErrorBody.ts
|
|
11540
11663
|
var defaultMaxLength = 1024;
|
|
11541
11664
|
function asRecord(value) {
|
|
@@ -11578,69 +11701,69 @@ function clip(message, maxLength) {
|
|
|
11578
11701
|
}
|
|
11579
11702
|
|
|
11580
11703
|
// src/shell/platform/describeErrors.ts
|
|
11581
|
-
var
|
|
11704
|
+
var m2 = authMessages.errors;
|
|
11582
11705
|
var inlineReasonMaxLength = 200;
|
|
11583
11706
|
function describeIdentityError(err) {
|
|
11584
11707
|
if (err.kind === "http") {
|
|
11585
11708
|
if (err.status === 401 || err.status === 403) {
|
|
11586
11709
|
return {
|
|
11587
|
-
error:
|
|
11710
|
+
error: m2.identity.invalidOrUnauthorized,
|
|
11588
11711
|
...err.status === 401 ? { exitCode: exitCodes.auth } : {}
|
|
11589
11712
|
};
|
|
11590
11713
|
}
|
|
11591
11714
|
return {
|
|
11592
|
-
error:
|
|
11715
|
+
error: m2.identity.couldNotVerify(parseErrorBody(err.body, inlineReasonMaxLength), err.status)
|
|
11593
11716
|
};
|
|
11594
11717
|
}
|
|
11595
11718
|
if (err.kind === "network") {
|
|
11596
|
-
return { error:
|
|
11719
|
+
return { error: m2.identity.couldNotVerifyNetwork(err.cause.message) };
|
|
11597
11720
|
}
|
|
11598
11721
|
if (err.kind === "timeout") {
|
|
11599
|
-
return { error:
|
|
11722
|
+
return { error: m2.identity.timedOut(err.timeoutMs) };
|
|
11600
11723
|
}
|
|
11601
|
-
return { error:
|
|
11724
|
+
return { error: m2.identity.unexpectedFormat };
|
|
11602
11725
|
}
|
|
11603
|
-
function describeRequestError(err, baseUrl, noun) {
|
|
11726
|
+
function describeRequestError(err, baseUrl, noun, notFound) {
|
|
11604
11727
|
if (err.kind === "http") {
|
|
11605
11728
|
const reason = parseErrorBody(err.body);
|
|
11606
11729
|
const body = reason ? { errorBody: reason } : {};
|
|
11607
11730
|
if (err.status === 401)
|
|
11608
11731
|
return {
|
|
11609
|
-
error:
|
|
11732
|
+
error: m2.request.rejected401(noun),
|
|
11610
11733
|
exitCode: exitCodes.auth,
|
|
11611
11734
|
...body
|
|
11612
11735
|
};
|
|
11613
11736
|
if (err.status === 402)
|
|
11614
11737
|
return {
|
|
11615
|
-
error:
|
|
11738
|
+
error: m2.request.rejected402(noun),
|
|
11616
11739
|
exitCode: exitCodes.payment,
|
|
11617
11740
|
...body
|
|
11618
11741
|
};
|
|
11619
11742
|
if (err.status === 403)
|
|
11620
|
-
return { error:
|
|
11743
|
+
return { error: m2.request.rejected403(noun), ...body };
|
|
11621
11744
|
if (err.status === 404)
|
|
11622
|
-
return
|
|
11623
|
-
return { error:
|
|
11745
|
+
return describeNotFound(notFound, noun, reason);
|
|
11746
|
+
return { error: m2.request.failedWithStatus(err.status, noun), ...body };
|
|
11624
11747
|
}
|
|
11625
11748
|
if (err.kind === "network") {
|
|
11626
|
-
return { error:
|
|
11749
|
+
return { error: m2.request.networkUnreachable(baseUrl, noun) };
|
|
11627
11750
|
}
|
|
11628
11751
|
if (err.kind === "timeout") {
|
|
11629
|
-
return { error:
|
|
11752
|
+
return { error: m2.request.timedOut(err.timeoutMs, noun) };
|
|
11630
11753
|
}
|
|
11631
|
-
return { error:
|
|
11754
|
+
return { error: m2.request.unexpectedResponse(noun) };
|
|
11632
11755
|
}
|
|
11633
11756
|
function describeBundleDownloadError(err) {
|
|
11634
11757
|
if (err.kind === "http") {
|
|
11635
11758
|
if (err.status === 401 || err.status === 403)
|
|
11636
|
-
return
|
|
11637
|
-
return
|
|
11759
|
+
return m2.bundle.linkExpired;
|
|
11760
|
+
return m2.bundle.failedWithStatus(err.status);
|
|
11638
11761
|
}
|
|
11639
11762
|
if (err.kind === "network")
|
|
11640
|
-
return
|
|
11763
|
+
return m2.bundle.networkUnreachable;
|
|
11641
11764
|
if (err.kind === "timeout")
|
|
11642
|
-
return
|
|
11643
|
-
return
|
|
11765
|
+
return m2.bundle.timedOut(err.timeoutMs);
|
|
11766
|
+
return m2.bundle.malformed;
|
|
11644
11767
|
}
|
|
11645
11768
|
function describeTeamStorageDownloadError(path, err) {
|
|
11646
11769
|
if (err.kind === "http") {
|
|
@@ -11667,12 +11790,16 @@ function callPublicApi(trpc, contract, input, options) {
|
|
|
11667
11790
|
return trpc.mutation(path, input, contract.output, options);
|
|
11668
11791
|
}
|
|
11669
11792
|
function makeCallPublicApiMethod(trpc, deps, readBackoffMs) {
|
|
11670
|
-
return async (contract, input, options) =>
|
|
11671
|
-
|
|
11672
|
-
|
|
11673
|
-
|
|
11674
|
-
|
|
11675
|
-
|
|
11793
|
+
return async (contract, input, options) => {
|
|
11794
|
+
const sent = applyWorkspaceId(contract.input, input, deps.workspaceId);
|
|
11795
|
+
const subject = notFoundSubject(contract.name, sent);
|
|
11796
|
+
return requestWithRetry({
|
|
11797
|
+
call: () => callPublicApi(trpc, contract, sent, options),
|
|
11798
|
+
backoffMs: contract.kind === "read" ? readBackoffMs : [],
|
|
11799
|
+
describe: (err) => describeRequestError(err, deps.baseUrl, contract.name, subject),
|
|
11800
|
+
sleep: deps.sleep
|
|
11801
|
+
});
|
|
11802
|
+
};
|
|
11676
11803
|
}
|
|
11677
11804
|
|
|
11678
11805
|
// node_modules/superjson/dist/double-indexed-kv.js
|
|
@@ -13161,25 +13288,36 @@ function createSdkContext(options) {
|
|
|
13161
13288
|
};
|
|
13162
13289
|
}
|
|
13163
13290
|
|
|
13291
|
+
// src/domains/interactiveRunner/runnerRequestFailure.ts
|
|
13292
|
+
function runnerRequestFailure(failure, runner) {
|
|
13293
|
+
const fields = failureFields(failure);
|
|
13294
|
+
if (failure.exitCode !== exitCodes.notFound) {
|
|
13295
|
+
return { ...fields, exitCode: failure.exitCode ?? exitCodes.network };
|
|
13296
|
+
}
|
|
13297
|
+
const cameFrom = interactiveRunnerMessages.runnerIdCameFrom(runner.runnerId, runner.source);
|
|
13298
|
+
return {
|
|
13299
|
+
...fields,
|
|
13300
|
+
errorBody: fields.errorBody ? `${fields.errorBody}
|
|
13301
|
+
${cameFrom}` : cameFrom,
|
|
13302
|
+
exitCode: exitCodes.notFound
|
|
13303
|
+
};
|
|
13304
|
+
}
|
|
13305
|
+
|
|
13164
13306
|
// src/domains/interactiveRunner/readJournal.ts
|
|
13165
13307
|
var unreachableFailure = {
|
|
13166
13308
|
error: interactiveRunnerMessages.runnerUnreachable,
|
|
13167
13309
|
exitCode: exitCodes.network
|
|
13168
13310
|
};
|
|
13169
|
-
async function readJournal(ctx,
|
|
13311
|
+
async function readJournal(ctx, runner, request) {
|
|
13170
13312
|
const result = await ctx.platformClient.callPublicApi(publicContractsV1.runner.readJournal, {
|
|
13171
|
-
id: runnerId,
|
|
13313
|
+
id: runner.runnerId,
|
|
13172
13314
|
stream: request.stream,
|
|
13173
13315
|
...request.runId === undefined ? {} : { runId: request.runId },
|
|
13174
13316
|
...request.sinceSequence === undefined ? {} : { sinceSequence: request.sinceSequence },
|
|
13175
13317
|
...request.tail === undefined ? {} : { tail: request.tail }
|
|
13176
13318
|
}, runnerCallOptions);
|
|
13177
13319
|
if (!result.ok) {
|
|
13178
|
-
return {
|
|
13179
|
-
...failureFields(result),
|
|
13180
|
-
exitCode: exitCodes.network,
|
|
13181
|
-
type: "failed"
|
|
13182
|
-
};
|
|
13320
|
+
return { ...runnerRequestFailure(result, runner), type: "failed" };
|
|
13183
13321
|
}
|
|
13184
13322
|
if (result.value.outcome === "failure") {
|
|
13185
13323
|
result.value.failureReason;
|
|
@@ -13188,9 +13326,24 @@ async function readJournal(ctx, runnerId, request) {
|
|
|
13188
13326
|
return { type: "read", value: result.value };
|
|
13189
13327
|
}
|
|
13190
13328
|
|
|
13329
|
+
// src/runnerSdk/givenRunner.ts
|
|
13330
|
+
var givenRunner = (runnerId) => ({
|
|
13331
|
+
runnerId,
|
|
13332
|
+
source: "given"
|
|
13333
|
+
});
|
|
13334
|
+
|
|
13335
|
+
// src/runnerSdk/toSdkFailure.ts
|
|
13336
|
+
function toSdkFailure(failure) {
|
|
13337
|
+
return {
|
|
13338
|
+
error: failure.error,
|
|
13339
|
+
...failure.errorBody ? { errorDetail: failure.errorBody } : {},
|
|
13340
|
+
ok: false
|
|
13341
|
+
};
|
|
13342
|
+
}
|
|
13343
|
+
|
|
13191
13344
|
// src/runnerSdk/toSdkResult.ts
|
|
13192
13345
|
function toSdkResult(result) {
|
|
13193
|
-
return result.ok ? { ok: true, value: result.value } :
|
|
13346
|
+
return result.ok ? { ok: true, value: result.value } : toSdkFailure(result);
|
|
13194
13347
|
}
|
|
13195
13348
|
|
|
13196
13349
|
// src/runnerSdk/lifecycleVerbs.ts
|
|
@@ -13201,16 +13354,13 @@ function createLifecycleVerbs({ platformClient }) {
|
|
|
13201
13354
|
async keepalive({
|
|
13202
13355
|
runnerId
|
|
13203
13356
|
}) {
|
|
13204
|
-
const read = await readJournal(ctx, runnerId, {
|
|
13357
|
+
const read = await readJournal(ctx, givenRunner(runnerId), {
|
|
13205
13358
|
stream: "run-status",
|
|
13206
13359
|
tail: 1
|
|
13207
13360
|
});
|
|
13208
13361
|
if (read.type === "read")
|
|
13209
13362
|
return { ok: true, value: { id: runnerId } };
|
|
13210
|
-
return {
|
|
13211
|
-
error: read.type === "unreachable" ? "The runner could not be reached." : read.error,
|
|
13212
|
-
ok: false
|
|
13213
|
-
};
|
|
13363
|
+
return read.type === "unreachable" ? { error: "The runner could not be reached.", ok: false } : toSdkFailure(read);
|
|
13214
13364
|
},
|
|
13215
13365
|
async launch({
|
|
13216
13366
|
id,
|
|
@@ -13692,10 +13842,7 @@ async function sendRunFlowRequest(ctx, options, delta) {
|
|
|
13692
13842
|
}, runnerCallOptions);
|
|
13693
13843
|
if (!result.ok) {
|
|
13694
13844
|
return {
|
|
13695
|
-
failure:
|
|
13696
|
-
...failureFields(result),
|
|
13697
|
-
exitCode: result.exitCode ?? exitCodes.network
|
|
13698
|
-
},
|
|
13845
|
+
failure: runnerRequestFailure(result, options.resolved),
|
|
13699
13846
|
type: "failed"
|
|
13700
13847
|
};
|
|
13701
13848
|
}
|
|
@@ -13784,17 +13931,14 @@ function createRunVerbs({ deps, platformClient }) {
|
|
|
13784
13931
|
stream,
|
|
13785
13932
|
window
|
|
13786
13933
|
}) {
|
|
13787
|
-
const read = await readJournal(ctx, runnerId, {
|
|
13934
|
+
const read = await readJournal(ctx, givenRunner(runnerId), {
|
|
13788
13935
|
stream,
|
|
13789
13936
|
...runFilter === "all-runs" ? {} : { runId: runFilter.runId },
|
|
13790
13937
|
...window === "newest" ? {} : ("tail" in window) ? { tail: window.tail } : { sinceSequence: window.sinceSequence }
|
|
13791
13938
|
});
|
|
13792
13939
|
if (read.type === "read")
|
|
13793
13940
|
return { ok: true, value: read.value };
|
|
13794
|
-
return {
|
|
13795
|
-
error: read.type === "unreachable" ? "The runner could not be reached." : read.error,
|
|
13796
|
-
ok: false
|
|
13797
|
-
};
|
|
13941
|
+
return read.type === "unreachable" ? { error: "The runner could not be reached.", ok: false } : toSdkFailure(read);
|
|
13798
13942
|
},
|
|
13799
13943
|
async run({
|
|
13800
13944
|
entryPointPath,
|
|
@@ -13816,11 +13960,11 @@ function createRunVerbs({ deps, platformClient }) {
|
|
|
13816
13960
|
environment: prepared.environment,
|
|
13817
13961
|
environmentId: prepared.environmentId,
|
|
13818
13962
|
files: prepared.files,
|
|
13819
|
-
resolved: { runnerId, type: "resolved" },
|
|
13963
|
+
resolved: { ...givenRunner(runnerId), type: "resolved" },
|
|
13820
13964
|
selection: prepared.selection
|
|
13821
13965
|
}, deps);
|
|
13822
13966
|
if (!submitted.ok)
|
|
13823
|
-
return
|
|
13967
|
+
return toSdkFailure(submitted);
|
|
13824
13968
|
return {
|
|
13825
13969
|
ok: true,
|
|
13826
13970
|
value: {
|
|
@@ -13851,4 +13995,4 @@ export {
|
|
|
13851
13995
|
createRunnerSdk
|
|
13852
13996
|
};
|
|
13853
13997
|
|
|
13854
|
-
//# debugId=
|
|
13998
|
+
//# debugId=C50E262AB8A599ED64756E2164756E21
|
|
@@ -11,6 +11,12 @@ export type RunnerSdkOptions = {
|
|
|
11
11
|
};
|
|
12
12
|
export type SdkResult<Value> = {
|
|
13
13
|
error: string;
|
|
14
|
+
/**
|
|
15
|
+
* What the platform said beyond the headline, and what to do about it:
|
|
16
|
+
* the reason a runner is gone, which of `--runner`, `QAWOLF_RUNNER_ID` or
|
|
17
|
+
* the stored default named it, the command that brings one back.
|
|
18
|
+
*/
|
|
19
|
+
errorDetail?: string;
|
|
14
20
|
ok: false;
|
|
15
21
|
} | {
|
|
16
22
|
ok: true;
|
package/package.json
CHANGED
|
@@ -25,6 +25,14 @@ run
|
|
|
25
25
|
`runId` in the response is canonical and can differ from the id you asked for.
|
|
26
26
|
Use the returned value for follow-up calls.
|
|
27
27
|
|
|
28
|
+
`run get` resolves platform runs only. A run id printed by `qawolf runner run`
|
|
29
|
+
belongs to that runner, so `run get` answers exit `8` and no such run on this
|
|
30
|
+
team. Read one of those with `qawolf runner events run-status --run <id>`.
|
|
31
|
+
|
|
32
|
+
A run that has been requested but not yet created answers exit `8` too, and
|
|
33
|
+
says it is still being created. That one clears on its own, so read the message
|
|
34
|
+
rather than the code before deciding whether to poll.
|
|
35
|
+
|
|
28
36
|
Poll `status` until it reaches `passed`, `failed` or `canceled`. The other
|
|
29
37
|
values mean the run is still going.
|
|
30
38
|
|
|
@@ -30,8 +30,8 @@ then launched without `--id` ends up with a pod it is not addressing. Pass
|
|
|
30
30
|
And a runner id that is set is treated as found, whether or not anything is
|
|
31
31
|
running under it. So exporting `QAWOLF_RUNNER_ID=agent-1` turns off the
|
|
32
32
|
auto-launch described next: instead of starting `agent-1`, commands try to reach
|
|
33
|
-
it and fail with exit code `
|
|
34
|
-
Launch that id once yourself and the rest follows.
|
|
33
|
+
it and fail with exit code `8`, naming the id and saying the variable is what
|
|
34
|
+
chose it. Launch that id once yourself and the rest follows.
|
|
35
35
|
|
|
36
36
|
And launching an id that differs from `QAWOLF_RUNNER_ID` prints a warning on
|
|
37
37
|
stderr naming both ids: the variable still outranks the directory default, so
|
|
@@ -119,11 +119,14 @@ and says so on stderr. Everything else on this page waits for a run.
|
|
|
119
119
|
|
|
120
120
|
Retry on the exit code, not on the message text:
|
|
121
121
|
|
|
122
|
-
- `4` is
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
- `4` is transient. The screen is up but cannot serve this instant: restarting
|
|
123
|
+
after a display-size change, or busy with another request. Retry in a second
|
|
124
|
+
or two, and bound the retries.
|
|
125
|
+
- `8` means there is no such runner. It was never launched, or it was
|
|
126
|
+
terminated, or it idled out. Retrying never brings one back, so stop and
|
|
127
|
+
launch the id or name one that is running. The message says which runner was
|
|
128
|
+
meant and whether `--runner`, `QAWOLF_RUNNER_ID` or this directory's stored
|
|
129
|
+
default chose it — read that line before you pick an id to launch.
|
|
127
130
|
- `2` will not clear on its own. Either nothing has run on this runner yet, so
|
|
128
131
|
run a flow, or the runner has no browser at all, so launch with
|
|
129
132
|
`--name playwright` instead. The message says which.
|
|
@@ -224,7 +227,8 @@ what the page shows.
|
|
|
224
227
|
One failure covers three causes, because a runner cannot tell them apart: no
|
|
225
228
|
live page, no element matching the selector, no variable under that name. All
|
|
226
229
|
three exit `2` and none clears by waiting, so read the message, which carries
|
|
227
|
-
whatever the runner said. An unreachable runner exits `4` and is worth retrying
|
|
230
|
+
whatever the runner said. An unreachable runner exits `4` and is worth retrying;
|
|
231
|
+
a runner that is not running at all exits `8` and is not.
|
|
228
232
|
|
|
229
233
|
Use `inspect` before reaching for `exec`. Reading a value through a snippet
|
|
230
234
|
means printing it and then fishing it back out of the `console` stream, which is
|