@uipath/test-manager-tool 1.202.1-preview.220 → 1.202.1-preview.238
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-gy4x3aqe.js → tool-y79tt9p5.js} +226 -8
- package/dist/tool.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11179,7 +11179,7 @@ var require_lib3 = __commonJS(function(exports, module) {
|
|
|
11179
11179
|
var package_default = {
|
|
11180
11180
|
name: "@uipath/test-manager-tool",
|
|
11181
11181
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
11182
|
-
version: "1.202.1-preview.
|
|
11182
|
+
version: "1.202.1-preview.238",
|
|
11183
11183
|
description: "Manage test cases, test sets, executions, and results.",
|
|
11184
11184
|
private: false,
|
|
11185
11185
|
repository: {
|
|
@@ -13557,6 +13557,7 @@ class SuccessOutput {
|
|
|
13557
13557
|
Data;
|
|
13558
13558
|
Pagination;
|
|
13559
13559
|
Instructions;
|
|
13560
|
+
Warning;
|
|
13560
13561
|
Log;
|
|
13561
13562
|
constructor(code, data) {
|
|
13562
13563
|
this.Code = code;
|
|
@@ -13916,7 +13917,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
13916
13917
|
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).";
|
|
13917
13918
|
}
|
|
13918
13919
|
}
|
|
13919
|
-
function
|
|
13920
|
+
function countRecords(data) {
|
|
13921
|
+
if (Array.isArray(data))
|
|
13922
|
+
return data.length;
|
|
13923
|
+
return data == null ? 0 : 1;
|
|
13924
|
+
}
|
|
13925
|
+
function availableFields(data) {
|
|
13926
|
+
const records = Array.isArray(data) ? data : [data];
|
|
13927
|
+
const keys = new Set;
|
|
13928
|
+
for (const record of records) {
|
|
13929
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
13930
|
+
for (const key of Object.keys(record))
|
|
13931
|
+
keys.add(key);
|
|
13932
|
+
}
|
|
13933
|
+
}
|
|
13934
|
+
return [...keys];
|
|
13935
|
+
}
|
|
13936
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
13937
|
+
const [error, decoded] = catchError(() => JSON.parse(whole));
|
|
13938
|
+
if (!error && typeof decoded === "string")
|
|
13939
|
+
return decoded;
|
|
13940
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
13941
|
+
}
|
|
13942
|
+
function referencedFields(filter) {
|
|
13943
|
+
const top = new Set;
|
|
13944
|
+
const nested = new Set;
|
|
13945
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
13946
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
13947
|
+
const quoted = [];
|
|
13948
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
13949
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
13950
|
+
if (!isAlias) {
|
|
13951
|
+
quoted.push({
|
|
13952
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
13953
|
+
index,
|
|
13954
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
13955
|
+
});
|
|
13956
|
+
}
|
|
13957
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
13958
|
+
});
|
|
13959
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
13960
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
13961
|
+
const place = (name, index, tail) => {
|
|
13962
|
+
if (tail || index >= rootEnd)
|
|
13963
|
+
nested.add(name);
|
|
13964
|
+
else
|
|
13965
|
+
top.add(name);
|
|
13966
|
+
};
|
|
13967
|
+
for (const entry of quoted)
|
|
13968
|
+
place(entry.name, entry.index, entry.tail);
|
|
13969
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
13970
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
13971
|
+
for (const match of identifiers) {
|
|
13972
|
+
const [, name, trailing] = match;
|
|
13973
|
+
if (trailing || reserved.has(name))
|
|
13974
|
+
continue;
|
|
13975
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
13976
|
+
}
|
|
13977
|
+
return {
|
|
13978
|
+
top: [...top],
|
|
13979
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
13980
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
13981
|
+
};
|
|
13982
|
+
}
|
|
13983
|
+
function appearsBelowTopLevel(data, name) {
|
|
13984
|
+
let budget = 2000;
|
|
13985
|
+
const visit = (value, depth) => {
|
|
13986
|
+
if (budget-- <= 0 || depth > 4)
|
|
13987
|
+
return false;
|
|
13988
|
+
if (value === null || typeof value !== "object")
|
|
13989
|
+
return false;
|
|
13990
|
+
if (Array.isArray(value))
|
|
13991
|
+
return value.some((entry) => visit(entry, depth));
|
|
13992
|
+
const record = value;
|
|
13993
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
13994
|
+
return true;
|
|
13995
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
13996
|
+
};
|
|
13997
|
+
return visit(data, 0);
|
|
13998
|
+
}
|
|
13999
|
+
function alwaysNullKeys(records) {
|
|
14000
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
14001
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
14002
|
+
return [];
|
|
14003
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
14004
|
+
if (keys.length === 0)
|
|
14005
|
+
return [];
|
|
14006
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
14007
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
14008
|
+
}
|
|
14009
|
+
function carriesOnlyNulls(value) {
|
|
14010
|
+
if (value === null)
|
|
14011
|
+
return true;
|
|
14012
|
+
if (Array.isArray(value)) {
|
|
14013
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
14014
|
+
}
|
|
14015
|
+
if (typeof value === "object" && value !== undefined) {
|
|
14016
|
+
const values = Object.values(value);
|
|
14017
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
14018
|
+
}
|
|
14019
|
+
return false;
|
|
14020
|
+
}
|
|
14021
|
+
function nameList(names, cap2 = 12) {
|
|
14022
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
14023
|
+
const rest = names.length - shown.length;
|
|
14024
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
14025
|
+
}
|
|
14026
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
14027
|
+
const present = availableFields(data);
|
|
14028
|
+
const refs = referencedFields(filter);
|
|
14029
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
14030
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
14031
|
+
const count = countRecords(data);
|
|
14032
|
+
const scope = `${count} record(s)`;
|
|
14033
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
14034
|
+
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" : "";
|
|
14035
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
14036
|
+
let detail;
|
|
14037
|
+
let lede;
|
|
14038
|
+
if (outcome.kind === "null-elements") {
|
|
14039
|
+
lede = "returned only null values";
|
|
14040
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
14041
|
+
if (unknown.length > 0) {
|
|
14042
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
14043
|
+
} else if (unchecked.length > 0) {
|
|
14044
|
+
detail = withSoundness(projected);
|
|
14045
|
+
} else {
|
|
14046
|
+
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`;
|
|
14047
|
+
}
|
|
14048
|
+
} else if (outcome.kind === "null-rows") {
|
|
14049
|
+
lede = "returned only null values";
|
|
14050
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
14051
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
14052
|
+
} else if (outcome.kind === "null-values") {
|
|
14053
|
+
lede = "returned only null values";
|
|
14054
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
14055
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
14056
|
+
if (sameSet) {
|
|
14057
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
14058
|
+
} else if (unknown.length > 0) {
|
|
14059
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
14060
|
+
} else {
|
|
14061
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
14062
|
+
}
|
|
14063
|
+
} else {
|
|
14064
|
+
lede = "returned nothing";
|
|
14065
|
+
if (unknown.length > 0) {
|
|
14066
|
+
detail = isNotAField(unknown);
|
|
14067
|
+
} else {
|
|
14068
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
14069
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
14070
|
+
}
|
|
14071
|
+
}
|
|
14072
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
14073
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
14074
|
+
}
|
|
14075
|
+
function appendWarning(existing, note) {
|
|
14076
|
+
return existing ? `${existing} ${note}` : note;
|
|
14077
|
+
}
|
|
14078
|
+
function applyFilter(data, filter, onWarning) {
|
|
13920
14079
|
const codec = requireJmespath();
|
|
13921
14080
|
let result;
|
|
13922
14081
|
try {
|
|
@@ -13924,9 +14083,34 @@ function applyFilter(data, filter) {
|
|
|
13924
14083
|
} catch (err) {
|
|
13925
14084
|
throw new FilterEvaluationError(filter, err);
|
|
13926
14085
|
}
|
|
13927
|
-
|
|
14086
|
+
const inputCount = countRecords(data);
|
|
14087
|
+
const warn = (outcome) => {
|
|
14088
|
+
if (inputCount === 0)
|
|
14089
|
+
return;
|
|
14090
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
14091
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
14092
|
+
`);
|
|
14093
|
+
onWarning?.(note);
|
|
14094
|
+
};
|
|
14095
|
+
const warnIfAllNull = (records) => {
|
|
14096
|
+
const keys = alwaysNullKeys(records);
|
|
14097
|
+
if (keys.length > 0)
|
|
14098
|
+
warn({ kind: "null-values", keys });
|
|
14099
|
+
};
|
|
14100
|
+
if (result == null) {
|
|
14101
|
+
warn({ kind: "empty" });
|
|
13928
14102
|
return [];
|
|
14103
|
+
}
|
|
13929
14104
|
if (Array.isArray(result)) {
|
|
14105
|
+
if (result.length === 0) {
|
|
14106
|
+
warn({ kind: "empty" });
|
|
14107
|
+
} else if (result.every((entry) => entry === null)) {
|
|
14108
|
+
warn({ kind: "null-elements", count: result.length });
|
|
14109
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
14110
|
+
warn({ kind: "null-rows", count: result.length });
|
|
14111
|
+
} else {
|
|
14112
|
+
warnIfAllNull(result);
|
|
14113
|
+
}
|
|
13930
14114
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
13931
14115
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
13932
14116
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -13934,10 +14118,30 @@ function applyFilter(data, filter) {
|
|
|
13934
14118
|
}
|
|
13935
14119
|
return result;
|
|
13936
14120
|
}
|
|
13937
|
-
if (typeof result === "object")
|
|
14121
|
+
if (typeof result === "object") {
|
|
14122
|
+
warnIfAllNull([result]);
|
|
13938
14123
|
return result;
|
|
14124
|
+
}
|
|
13939
14125
|
return { Value: result };
|
|
13940
14126
|
}
|
|
14127
|
+
function filterFailureData(envelope) {
|
|
14128
|
+
const filter = getOutputFilter();
|
|
14129
|
+
const data = envelope.Data;
|
|
14130
|
+
if (!filter || data == null)
|
|
14131
|
+
return;
|
|
14132
|
+
let note;
|
|
14133
|
+
const [filterError, filtered] = catchError(() => applyFilter(data, filter, (n) => {
|
|
14134
|
+
note = n;
|
|
14135
|
+
}));
|
|
14136
|
+
if (filterError) {
|
|
14137
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
14138
|
+
return;
|
|
14139
|
+
}
|
|
14140
|
+
envelope.Data = filtered;
|
|
14141
|
+
if (note) {
|
|
14142
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
14143
|
+
}
|
|
14144
|
+
}
|
|
13941
14145
|
function defaultErrorCodeForResult(result) {
|
|
13942
14146
|
switch (result) {
|
|
13943
14147
|
case RESULTS.AuthenticationError:
|
|
@@ -14020,8 +14224,14 @@ var OutputFormatter;
|
|
|
14020
14224
|
}
|
|
14021
14225
|
const filter = getOutputFilter();
|
|
14022
14226
|
if (filter) {
|
|
14023
|
-
|
|
14227
|
+
let note;
|
|
14228
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
14229
|
+
note = n;
|
|
14230
|
+
});
|
|
14024
14231
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
14232
|
+
if (note) {
|
|
14233
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
14234
|
+
}
|
|
14025
14235
|
}
|
|
14026
14236
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
14027
14237
|
}
|
|
@@ -14049,6 +14259,7 @@ var OutputFormatter;
|
|
|
14049
14259
|
delete envelope.TelemetryErrorClass;
|
|
14050
14260
|
delete envelope.TelemetryTerminalOutcome;
|
|
14051
14261
|
delete envelope.TelemetryTerminalSignal;
|
|
14262
|
+
filterFailureData(envelope);
|
|
14052
14263
|
if (!suppressTelemetry) {
|
|
14053
14264
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
14054
14265
|
result: data.Result,
|
|
@@ -14097,13 +14308,20 @@ var OutputFormatter;
|
|
|
14097
14308
|
OutputFormatter.log = log;
|
|
14098
14309
|
function formatToString(data) {
|
|
14099
14310
|
const filter = getOutputFilter();
|
|
14311
|
+
const envelope = data;
|
|
14100
14312
|
if ("Data" in data && data.Data != null) {
|
|
14101
14313
|
data.Data = normalizeDataKeys(data.Data);
|
|
14102
14314
|
if (filter) {
|
|
14103
|
-
|
|
14315
|
+
let note;
|
|
14316
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
14317
|
+
note = n;
|
|
14318
|
+
}));
|
|
14319
|
+
if (note) {
|
|
14320
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
14321
|
+
}
|
|
14104
14322
|
}
|
|
14105
14323
|
}
|
|
14106
|
-
const output = normalizeOutputKeys(
|
|
14324
|
+
const output = normalizeOutputKeys(envelope);
|
|
14107
14325
|
const lines = [];
|
|
14108
14326
|
const sink = getOutputSink();
|
|
14109
14327
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -39287,4 +39505,4 @@ var registerCommands = async (program2) => {
|
|
|
39287
39505
|
|
|
39288
39506
|
export { Command, metadata, registerCommands };
|
|
39289
39507
|
|
|
39290
|
-
//# debugId=
|
|
39508
|
+
//# debugId=37324363C42034AB64756E2164756E21
|
package/dist/tool.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/test-manager-tool",
|
|
3
3
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
4
|
-
"version": "1.202.1-preview.
|
|
4
|
+
"version": "1.202.1-preview.238",
|
|
5
5
|
"description": "Manage test cases, test sets, executions, and results.",
|
|
6
6
|
"private": false,
|
|
7
7
|
"repository": {
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"files": [
|
|
27
27
|
"dist"
|
|
28
28
|
],
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "537e43df1d3583633cfd3a0b88634f9ce3ba9d6b"
|
|
30
30
|
}
|