@uipath/test-manager-tool 1.203.0-preview.233 → 1.203.0-preview.237
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/index.js +1 -1
- package/dist/{tool-0nx90twz.js → tool-a78ywp6r.js} +226 -8
- package/dist/tool.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11180,7 +11180,7 @@ var package_default = {
|
|
|
11180
11180
|
name: "@uipath/test-manager-tool",
|
|
11181
11181
|
author: "UiPath",
|
|
11182
11182
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
11183
|
-
version: "1.203.0-preview.
|
|
11183
|
+
version: "1.203.0-preview.237",
|
|
11184
11184
|
description: "Manage test cases, test sets, executions, and results.",
|
|
11185
11185
|
private: false,
|
|
11186
11186
|
repository: {
|
|
@@ -13579,6 +13579,7 @@ class SuccessOutput {
|
|
|
13579
13579
|
Data;
|
|
13580
13580
|
Pagination;
|
|
13581
13581
|
Instructions;
|
|
13582
|
+
Warning;
|
|
13582
13583
|
Log;
|
|
13583
13584
|
constructor(code, data) {
|
|
13584
13585
|
this.Code = code;
|
|
@@ -14163,7 +14164,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
14163
14164
|
this.instructions = "Pass --limit <n> to choose how many records the filter applies to. " + "To filter over all records, pass the command's maximum accepted --limit (see the option's description in --help).";
|
|
14164
14165
|
}
|
|
14165
14166
|
}
|
|
14166
|
-
function
|
|
14167
|
+
function countRecords(data) {
|
|
14168
|
+
if (Array.isArray(data))
|
|
14169
|
+
return data.length;
|
|
14170
|
+
return data == null ? 0 : 1;
|
|
14171
|
+
}
|
|
14172
|
+
function availableFields(data) {
|
|
14173
|
+
const records = Array.isArray(data) ? data : [data];
|
|
14174
|
+
const keys = new Set;
|
|
14175
|
+
for (const record of records) {
|
|
14176
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
14177
|
+
for (const key of Object.keys(record))
|
|
14178
|
+
keys.add(key);
|
|
14179
|
+
}
|
|
14180
|
+
}
|
|
14181
|
+
return [...keys];
|
|
14182
|
+
}
|
|
14183
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
14184
|
+
const [error, decoded] = catchError(() => JSON.parse(whole));
|
|
14185
|
+
if (!error && typeof decoded === "string")
|
|
14186
|
+
return decoded;
|
|
14187
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
14188
|
+
}
|
|
14189
|
+
function referencedFields(filter) {
|
|
14190
|
+
const top = new Set;
|
|
14191
|
+
const nested = new Set;
|
|
14192
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
14193
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
14194
|
+
const quoted = [];
|
|
14195
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
14196
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
14197
|
+
if (!isAlias) {
|
|
14198
|
+
quoted.push({
|
|
14199
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
14200
|
+
index,
|
|
14201
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
14202
|
+
});
|
|
14203
|
+
}
|
|
14204
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
14205
|
+
});
|
|
14206
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
14207
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
14208
|
+
const place = (name, index, tail) => {
|
|
14209
|
+
if (tail || index >= rootEnd)
|
|
14210
|
+
nested.add(name);
|
|
14211
|
+
else
|
|
14212
|
+
top.add(name);
|
|
14213
|
+
};
|
|
14214
|
+
for (const entry of quoted)
|
|
14215
|
+
place(entry.name, entry.index, entry.tail);
|
|
14216
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
14217
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
14218
|
+
for (const match of identifiers) {
|
|
14219
|
+
const [, name, trailing] = match;
|
|
14220
|
+
if (trailing || reserved.has(name))
|
|
14221
|
+
continue;
|
|
14222
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
14223
|
+
}
|
|
14224
|
+
return {
|
|
14225
|
+
top: [...top],
|
|
14226
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
14227
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
14228
|
+
};
|
|
14229
|
+
}
|
|
14230
|
+
function appearsBelowTopLevel(data, name) {
|
|
14231
|
+
let budget = 2000;
|
|
14232
|
+
const visit = (value, depth) => {
|
|
14233
|
+
if (budget-- <= 0 || depth > 4)
|
|
14234
|
+
return false;
|
|
14235
|
+
if (value === null || typeof value !== "object")
|
|
14236
|
+
return false;
|
|
14237
|
+
if (Array.isArray(value))
|
|
14238
|
+
return value.some((entry) => visit(entry, depth));
|
|
14239
|
+
const record = value;
|
|
14240
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
14241
|
+
return true;
|
|
14242
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
14243
|
+
};
|
|
14244
|
+
return visit(data, 0);
|
|
14245
|
+
}
|
|
14246
|
+
function alwaysNullKeys(records) {
|
|
14247
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
14248
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
14249
|
+
return [];
|
|
14250
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
14251
|
+
if (keys.length === 0)
|
|
14252
|
+
return [];
|
|
14253
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
14254
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
14255
|
+
}
|
|
14256
|
+
function carriesOnlyNulls(value) {
|
|
14257
|
+
if (value === null)
|
|
14258
|
+
return true;
|
|
14259
|
+
if (Array.isArray(value)) {
|
|
14260
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
14261
|
+
}
|
|
14262
|
+
if (typeof value === "object" && value !== undefined) {
|
|
14263
|
+
const values = Object.values(value);
|
|
14264
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
14265
|
+
}
|
|
14266
|
+
return false;
|
|
14267
|
+
}
|
|
14268
|
+
function nameList(names, cap2 = 12) {
|
|
14269
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
14270
|
+
const rest = names.length - shown.length;
|
|
14271
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
14272
|
+
}
|
|
14273
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
14274
|
+
const present = availableFields(data);
|
|
14275
|
+
const refs = referencedFields(filter);
|
|
14276
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
14277
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
14278
|
+
const count = countRecords(data);
|
|
14279
|
+
const scope = `${count} record(s)`;
|
|
14280
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
14281
|
+
const soundness = unchecked.length > 0 ? `${nameList(unchecked)} ${unchecked.length === 1 ? "reads" : "read"} below the top level, so ${unchecked.length === 1 ? "it was" : "they were"} not checked against the record keys` : refs.top.length > 0 ? "every field it names exists" : "";
|
|
14282
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
14283
|
+
let detail;
|
|
14284
|
+
let lede;
|
|
14285
|
+
if (outcome.kind === "null-elements") {
|
|
14286
|
+
lede = "returned only null values";
|
|
14287
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
14288
|
+
if (unknown.length > 0) {
|
|
14289
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
14290
|
+
} else if (unchecked.length > 0) {
|
|
14291
|
+
detail = withSoundness(projected);
|
|
14292
|
+
} else {
|
|
14293
|
+
detail = `${projected}, and every field it names exists — a multi-select list ` + `(\`[A, B]\`) reads each entry against \`Data\` itself, so on a list ` + `result use \`[].[A, B]\` or \`[].{a: A, b: B}\` to read the records`;
|
|
14294
|
+
}
|
|
14295
|
+
} else if (outcome.kind === "null-rows") {
|
|
14296
|
+
lede = "returned only null values";
|
|
14297
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
14298
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
14299
|
+
} else if (outcome.kind === "null-values") {
|
|
14300
|
+
lede = "returned only null values";
|
|
14301
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
14302
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
14303
|
+
if (sameSet) {
|
|
14304
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
14305
|
+
} else if (unknown.length > 0) {
|
|
14306
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
14307
|
+
} else {
|
|
14308
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
14309
|
+
}
|
|
14310
|
+
} else {
|
|
14311
|
+
lede = "returned nothing";
|
|
14312
|
+
if (unknown.length > 0) {
|
|
14313
|
+
detail = isNotAField(unknown);
|
|
14314
|
+
} else {
|
|
14315
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
14316
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
14317
|
+
}
|
|
14318
|
+
}
|
|
14319
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
14320
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
14321
|
+
}
|
|
14322
|
+
function appendWarning(existing, note) {
|
|
14323
|
+
return existing ? `${existing} ${note}` : note;
|
|
14324
|
+
}
|
|
14325
|
+
function applyFilter(data, filter, onWarning) {
|
|
14167
14326
|
const codec = requireJmespath();
|
|
14168
14327
|
let result;
|
|
14169
14328
|
try {
|
|
@@ -14171,9 +14330,34 @@ function applyFilter(data, filter) {
|
|
|
14171
14330
|
} catch (err) {
|
|
14172
14331
|
throw new FilterEvaluationError(filter, err);
|
|
14173
14332
|
}
|
|
14174
|
-
|
|
14333
|
+
const inputCount = countRecords(data);
|
|
14334
|
+
const warn = (outcome) => {
|
|
14335
|
+
if (inputCount === 0)
|
|
14336
|
+
return;
|
|
14337
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
14338
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
14339
|
+
`);
|
|
14340
|
+
onWarning?.(note);
|
|
14341
|
+
};
|
|
14342
|
+
const warnIfAllNull = (records) => {
|
|
14343
|
+
const keys = alwaysNullKeys(records);
|
|
14344
|
+
if (keys.length > 0)
|
|
14345
|
+
warn({ kind: "null-values", keys });
|
|
14346
|
+
};
|
|
14347
|
+
if (result == null) {
|
|
14348
|
+
warn({ kind: "empty" });
|
|
14175
14349
|
return [];
|
|
14350
|
+
}
|
|
14176
14351
|
if (Array.isArray(result)) {
|
|
14352
|
+
if (result.length === 0) {
|
|
14353
|
+
warn({ kind: "empty" });
|
|
14354
|
+
} else if (result.every((entry) => entry === null)) {
|
|
14355
|
+
warn({ kind: "null-elements", count: result.length });
|
|
14356
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
14357
|
+
warn({ kind: "null-rows", count: result.length });
|
|
14358
|
+
} else {
|
|
14359
|
+
warnIfAllNull(result);
|
|
14360
|
+
}
|
|
14177
14361
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
14178
14362
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
14179
14363
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -14181,10 +14365,30 @@ function applyFilter(data, filter) {
|
|
|
14181
14365
|
}
|
|
14182
14366
|
return result;
|
|
14183
14367
|
}
|
|
14184
|
-
if (typeof result === "object")
|
|
14368
|
+
if (typeof result === "object") {
|
|
14369
|
+
warnIfAllNull([result]);
|
|
14185
14370
|
return result;
|
|
14371
|
+
}
|
|
14186
14372
|
return { Value: result };
|
|
14187
14373
|
}
|
|
14374
|
+
function filterFailureData(envelope) {
|
|
14375
|
+
const filter = getOutputFilter();
|
|
14376
|
+
const data = envelope.Data;
|
|
14377
|
+
if (!filter || data == null)
|
|
14378
|
+
return;
|
|
14379
|
+
let note;
|
|
14380
|
+
const [filterError, filtered] = catchError(() => applyFilter(data, filter, (n) => {
|
|
14381
|
+
note = n;
|
|
14382
|
+
}));
|
|
14383
|
+
if (filterError) {
|
|
14384
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
14385
|
+
return;
|
|
14386
|
+
}
|
|
14387
|
+
envelope.Data = filtered;
|
|
14388
|
+
if (note) {
|
|
14389
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
14390
|
+
}
|
|
14391
|
+
}
|
|
14188
14392
|
function defaultErrorCodeForResult(result) {
|
|
14189
14393
|
switch (result) {
|
|
14190
14394
|
case RESULTS.AuthenticationError:
|
|
@@ -14267,8 +14471,14 @@ var OutputFormatter;
|
|
|
14267
14471
|
}
|
|
14268
14472
|
const filter = getOutputFilter();
|
|
14269
14473
|
if (filter) {
|
|
14270
|
-
|
|
14474
|
+
let note;
|
|
14475
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
14476
|
+
note = n;
|
|
14477
|
+
});
|
|
14271
14478
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
14479
|
+
if (note) {
|
|
14480
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
14481
|
+
}
|
|
14272
14482
|
}
|
|
14273
14483
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
14274
14484
|
}
|
|
@@ -14296,6 +14506,7 @@ var OutputFormatter;
|
|
|
14296
14506
|
delete envelope.TelemetryErrorClass;
|
|
14297
14507
|
delete envelope.TelemetryTerminalOutcome;
|
|
14298
14508
|
delete envelope.TelemetryTerminalSignal;
|
|
14509
|
+
filterFailureData(envelope);
|
|
14299
14510
|
if (!suppressTelemetry) {
|
|
14300
14511
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
14301
14512
|
result: data.Result,
|
|
@@ -14344,13 +14555,20 @@ var OutputFormatter;
|
|
|
14344
14555
|
OutputFormatter.log = log;
|
|
14345
14556
|
function formatToString(data) {
|
|
14346
14557
|
const filter = getOutputFilter();
|
|
14558
|
+
const envelope = data;
|
|
14347
14559
|
if ("Data" in data && data.Data != null) {
|
|
14348
14560
|
data.Data = normalizeDataKeys(data.Data);
|
|
14349
14561
|
if (filter) {
|
|
14350
|
-
|
|
14562
|
+
let note;
|
|
14563
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
14564
|
+
note = n;
|
|
14565
|
+
}));
|
|
14566
|
+
if (note) {
|
|
14567
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
14568
|
+
}
|
|
14351
14569
|
}
|
|
14352
14570
|
}
|
|
14353
|
-
const output = normalizeOutputKeys(
|
|
14571
|
+
const output = normalizeOutputKeys(envelope);
|
|
14354
14572
|
const lines = [];
|
|
14355
14573
|
const sink = getOutputSink();
|
|
14356
14574
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -39650,4 +39868,4 @@ var registerCommands = async (program2) => {
|
|
|
39650
39868
|
|
|
39651
39869
|
export { Command, metadata, registerCommands };
|
|
39652
39870
|
|
|
39653
|
-
//# debugId=
|
|
39871
|
+
//# debugId=857CE73A7D674FC564756E2164756E21
|
package/dist/tool.js
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uipath/test-manager-tool",
|
|
3
3
|
"author": "UiPath",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
|
-
"version": "1.203.0-preview.
|
|
5
|
+
"version": "1.203.0-preview.237",
|
|
6
6
|
"description": "Manage test cases, test sets, executions, and results.",
|
|
7
7
|
"private": false,
|
|
8
8
|
"repository": {
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "4ad3e17a66f2c7fb7fe1f0e3e04a5b6175a0a9a3"
|
|
31
31
|
}
|