@allurereport/reader 3.0.0-beta.9 → 3.0.1
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/allure2/index.js +3 -0
- package/dist/allure2/model.d.ts +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/xcresult/bundle.d.ts +7 -0
- package/dist/xcresult/bundle.js +68 -0
- package/dist/xcresult/index.d.ts +2 -0
- package/dist/xcresult/index.js +91 -0
- package/dist/xcresult/model.d.ts +61 -0
- package/dist/xcresult/model.js +1 -0
- package/dist/xcresult/utils.d.ts +42 -0
- package/dist/xcresult/utils.js +378 -0
- package/dist/xcresult/xcresulttool/cli.d.ts +10 -0
- package/dist/xcresult/xcresulttool/cli.js +42 -0
- package/dist/xcresult/xcresulttool/index.d.ts +7 -0
- package/dist/xcresult/xcresulttool/index.js +311 -0
- package/dist/xcresult/xcresulttool/legacy/index.d.ts +10 -0
- package/dist/xcresult/xcresulttool/legacy/index.js +455 -0
- package/dist/xcresult/xcresulttool/legacy/model.d.ts +74 -0
- package/dist/xcresult/xcresulttool/legacy/model.js +1 -0
- package/dist/xcresult/xcresulttool/legacy/parsing.d.ts +15 -0
- package/dist/xcresult/xcresulttool/legacy/parsing.js +41 -0
- package/dist/xcresult/xcresulttool/legacy/utils.d.ts +7 -0
- package/dist/xcresult/xcresulttool/legacy/utils.js +33 -0
- package/dist/xcresult/xcresulttool/legacy/xcModel.d.ts +357 -0
- package/dist/xcresult/xcresulttool/legacy/xcModel.js +5 -0
- package/dist/xcresult/xcresulttool/model.d.ts +17 -0
- package/dist/xcresult/xcresulttool/model.js +6 -0
- package/dist/xcresult/xcresulttool/utils.d.ts +3 -0
- package/dist/xcresult/xcresulttool/utils.js +74 -0
- package/dist/xcresult/xcresulttool/xcModel.d.ts +96 -0
- package/dist/xcresult/xcresulttool/xcModel.js +18 -0
- package/package.json +10 -8
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var _NewApiParser_instances, _NewApiParser_processXcNodes, _NewApiParser_processXcResultNode, _NewApiParser_processXcBundleNode, _NewApiParser_processXcTestSuiteNode, _NewApiParser_processXcTestCaseNode;
|
|
7
|
+
import { ensureArray, ensureArrayWithItems, ensureInt, ensureLiteral, ensureObject, ensureString, isArray, isLiteral, isNumber, isObject, isString, } from "@allurereport/reader-api";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
import { DEFAULT_BUNDLE_NAME, DEFAULT_SUITE_NAME, DEFAULT_TEST_NAME, createTestRunLookup, getTargetDetails, lookupNextTestAttempt, secondsToMilliseconds, } from "../utils.js";
|
|
10
|
+
import { getTestActivities, getTestDetails, getTests } from "./cli.js";
|
|
11
|
+
import { XcresultParser } from "./model.js";
|
|
12
|
+
import { XcTestNodeTypeValues, XcTestResultValues } from "./xcModel.js";
|
|
13
|
+
const DURATION_PATTERN = /\d+\.\d+/;
|
|
14
|
+
const ATTACHMENT_NAME_INFIX_PATTERN = /_\d+_[\dA-F]{8}-[\dA-F]{4}-[\dA-F]{4}-[\dA-F]{4}-[\dA-F]{12}/g;
|
|
15
|
+
class NewApiParser extends XcresultParser {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
_NewApiParser_instances.add(this);
|
|
19
|
+
}
|
|
20
|
+
async *parse() {
|
|
21
|
+
const tests = await getTests(this.xcResultPath);
|
|
22
|
+
const testNodes = ensureObject(tests)?.testNodes;
|
|
23
|
+
if (isArray(testNodes)) {
|
|
24
|
+
yield* __classPrivateFieldGet(this, _NewApiParser_instances, "m", _NewApiParser_processXcNodes).call(this, testNodes, { suites: [] });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
_NewApiParser_instances = new WeakSet(), _NewApiParser_processXcNodes = async function* _NewApiParser_processXcNodes(children, state) {
|
|
29
|
+
for (const child of children) {
|
|
30
|
+
if (isObject(child)) {
|
|
31
|
+
yield* __classPrivateFieldGet(this, _NewApiParser_instances, "m", _NewApiParser_processXcResultNode).call(this, child, state);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}, _NewApiParser_processXcResultNode = async function* _NewApiParser_processXcResultNode(node, state) {
|
|
35
|
+
const { nodeType } = node;
|
|
36
|
+
switch (ensureLiteral(nodeType, XcTestNodeTypeValues)) {
|
|
37
|
+
case "Unit test bundle":
|
|
38
|
+
case "UI test bundle":
|
|
39
|
+
yield* __classPrivateFieldGet(this, _NewApiParser_instances, "m", _NewApiParser_processXcBundleNode).call(this, node, state);
|
|
40
|
+
case "Test Suite":
|
|
41
|
+
yield* __classPrivateFieldGet(this, _NewApiParser_instances, "m", _NewApiParser_processXcTestSuiteNode).call(this, node, state);
|
|
42
|
+
case "Test Case":
|
|
43
|
+
yield* __classPrivateFieldGet(this, _NewApiParser_instances, "m", _NewApiParser_processXcTestCaseNode).call(this, node, state);
|
|
44
|
+
}
|
|
45
|
+
}, _NewApiParser_processXcBundleNode = async function* _NewApiParser_processXcBundleNode(node, state) {
|
|
46
|
+
const { children, name } = node;
|
|
47
|
+
yield* __classPrivateFieldGet(this, _NewApiParser_instances, "m", _NewApiParser_processXcNodes).call(this, ensureArray(children) ?? [], {
|
|
48
|
+
...state,
|
|
49
|
+
bundle: ensureString(name) ?? DEFAULT_BUNDLE_NAME,
|
|
50
|
+
});
|
|
51
|
+
}, _NewApiParser_processXcTestSuiteNode = async function* _NewApiParser_processXcTestSuiteNode(node, state) {
|
|
52
|
+
const { children, name } = node;
|
|
53
|
+
const { suites } = state;
|
|
54
|
+
yield* __classPrivateFieldGet(this, _NewApiParser_instances, "m", _NewApiParser_processXcNodes).call(this, ensureArray(children) ?? [], {
|
|
55
|
+
...state,
|
|
56
|
+
suites: [...suites, ensureString(name) ?? DEFAULT_SUITE_NAME],
|
|
57
|
+
});
|
|
58
|
+
}, _NewApiParser_processXcTestCaseNode = async function* _NewApiParser_processXcTestCaseNode(node, { bundle, suites }) {
|
|
59
|
+
const { nodeIdentifier, name: displayName } = node;
|
|
60
|
+
if (isString(nodeIdentifier)) {
|
|
61
|
+
const testDetails = await getTestDetails(this.xcResultPath, nodeIdentifier);
|
|
62
|
+
const testActivities = await getTestActivities(this.xcResultPath, nodeIdentifier);
|
|
63
|
+
const { testName, tags, testRuns: detailsTestRuns, devices: testDetailsDevices, } = ensureObject(testDetails) ?? {};
|
|
64
|
+
const crossDeviceTesting = isArray(testDetailsDevices) && testDetailsDevices.length > 1;
|
|
65
|
+
const detailsRunLookup = createTestDetailsRunLookup(detailsTestRuns);
|
|
66
|
+
const name = ensureString(displayName) ?? ensureString(testName) ?? DEFAULT_TEST_NAME;
|
|
67
|
+
const fullName = convertFullName(nodeIdentifier, bundle);
|
|
68
|
+
const testCaseLabels = convertTestCaseLabels(bundle, suites, nodeIdentifier, tags);
|
|
69
|
+
const { testRuns: activityTestRuns } = ensureObject(testActivities) ?? {};
|
|
70
|
+
for (const activityTestRun of ensureArrayWithItems(activityTestRuns, isObject) ?? []) {
|
|
71
|
+
const { device: activityTestRunDevice, arguments: activityTestRunArguments, testPlanConfiguration: activityTestRunTestPlan, activities, } = activityTestRun;
|
|
72
|
+
const { labels: deviceLabels, parameters: deviceParameters, deviceId, } = processActivityTestRunDevice(activityTestRunDevice, crossDeviceTesting);
|
|
73
|
+
const { configurationId } = ensureObject(activityTestRunTestPlan) ?? {};
|
|
74
|
+
const args = convertActivitiesTestRunArgs(activityTestRunArguments);
|
|
75
|
+
const { duration, parameters = [], result = "unknown", } = findNextAttemptDataFromTestDetails(detailsRunLookup, {
|
|
76
|
+
device: deviceId,
|
|
77
|
+
testPlan: ensureString(configurationId),
|
|
78
|
+
args,
|
|
79
|
+
}) ?? {};
|
|
80
|
+
const createAttachmentFile = this.createAttachmentFile;
|
|
81
|
+
const { steps, attachmentFiles } = createAttachmentFile
|
|
82
|
+
? await convertXcActivitiesToAllureSteps(this.createAttachmentFile, activities)
|
|
83
|
+
: { attachmentFiles: [] };
|
|
84
|
+
yield* attachmentFiles;
|
|
85
|
+
yield {
|
|
86
|
+
uuid: randomUUID(),
|
|
87
|
+
fullName,
|
|
88
|
+
name,
|
|
89
|
+
start: 0,
|
|
90
|
+
duration: duration,
|
|
91
|
+
status: convertXcResultToAllureStatus(result),
|
|
92
|
+
message: "",
|
|
93
|
+
trace: "",
|
|
94
|
+
steps,
|
|
95
|
+
labels: [...testCaseLabels, ...deviceLabels],
|
|
96
|
+
links: [],
|
|
97
|
+
parameters: [...deviceParameters, ...pairParameterNamesWithValues(parameters, args)],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
export default NewApiParser;
|
|
103
|
+
const convertXcActivitiesToAllureSteps = async (createAttachmentFile, activities, parentActivityAttachments = [].values()) => {
|
|
104
|
+
const attachmentFiles = [];
|
|
105
|
+
const steps = [];
|
|
106
|
+
let nextAttachmentOfParentActivity = parentActivityAttachments.next();
|
|
107
|
+
for (const { title: unvalidatedTitle, attachments, childActivities, startTime } of ensureArrayWithItems(activities, isObject) ?? []) {
|
|
108
|
+
const title = ensureString(unvalidatedTitle);
|
|
109
|
+
const start = isNumber(startTime) ? secondsToMilliseconds(startTime) : undefined;
|
|
110
|
+
const { potentialNames: potentialAttachmentNames, uuid: attachmentFileName, xcName, } = nextAttachmentOfParentActivity.done ? {} : nextAttachmentOfParentActivity.value;
|
|
111
|
+
const isAttachment = isString(title) && isAttachmentActivity(potentialAttachmentNames, title, childActivities, attachments);
|
|
112
|
+
if (isAttachment && attachmentFileName && xcName) {
|
|
113
|
+
const file = await createAttachmentFile(attachmentFileName, xcName);
|
|
114
|
+
if (file) {
|
|
115
|
+
attachmentFiles.push(file);
|
|
116
|
+
}
|
|
117
|
+
nextAttachmentOfParentActivity = parentActivityAttachments.next();
|
|
118
|
+
const attachmentStep = {
|
|
119
|
+
type: "attachment",
|
|
120
|
+
start,
|
|
121
|
+
name: title,
|
|
122
|
+
originalFileName: xcName,
|
|
123
|
+
};
|
|
124
|
+
steps.push(attachmentStep);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const stepAttachments = (ensureArrayWithItems(attachments, isObject) ?? [])
|
|
128
|
+
.map(({ name, uuid }) => (isString(name) && isString(uuid) ? { potentialNames: getPotentialFileNamesFromXcSuggestedName(name), uuid, xcName: name } : undefined))
|
|
129
|
+
.filter((entry) => typeof entry !== "undefined");
|
|
130
|
+
const { steps: substeps, attachmentFiles: substepAttachmentFiles } = await convertXcActivitiesToAllureSteps(createAttachmentFile, childActivities, stepAttachments.values());
|
|
131
|
+
const step = {
|
|
132
|
+
type: "step",
|
|
133
|
+
duration: 0,
|
|
134
|
+
message: "",
|
|
135
|
+
name: title,
|
|
136
|
+
parameters: [],
|
|
137
|
+
start,
|
|
138
|
+
status: "passed",
|
|
139
|
+
steps: substeps,
|
|
140
|
+
stop: 0,
|
|
141
|
+
trace: "",
|
|
142
|
+
};
|
|
143
|
+
attachmentFiles.push(...substepAttachmentFiles);
|
|
144
|
+
steps.push(step);
|
|
145
|
+
}
|
|
146
|
+
return { steps, attachmentFiles };
|
|
147
|
+
};
|
|
148
|
+
const isAttachmentActivity = (potentialAttachmentNames, title, childActivities, attachments) => typeof childActivities === "undefined" &&
|
|
149
|
+
typeof attachments === "undefined" &&
|
|
150
|
+
(potentialAttachmentNames?.has(title) ?? false);
|
|
151
|
+
const getPotentialFileNamesFromXcSuggestedName = (xcSuggestedAttachmentName) => new Set([...xcSuggestedAttachmentName.matchAll(ATTACHMENT_NAME_INFIX_PATTERN)].map(({ 0: { length }, index }) => xcSuggestedAttachmentName.slice(0, index) + xcSuggestedAttachmentName.slice(index + length)));
|
|
152
|
+
const convertXcResultToAllureStatus = (xcResult) => {
|
|
153
|
+
switch (xcResult) {
|
|
154
|
+
case "Expected Failure":
|
|
155
|
+
return "passed";
|
|
156
|
+
case "Failed":
|
|
157
|
+
return "failed";
|
|
158
|
+
case "Passed":
|
|
159
|
+
return "passed";
|
|
160
|
+
case "Skipped":
|
|
161
|
+
return "skipped";
|
|
162
|
+
default:
|
|
163
|
+
return "unknown";
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const pairParameterNamesWithValues = (names, values) => names
|
|
167
|
+
.slice(0, values.length)
|
|
168
|
+
.map((p, i) => {
|
|
169
|
+
const value = values[i];
|
|
170
|
+
return typeof p !== "undefined" && typeof value !== "undefined" ? { name: p, value } : undefined;
|
|
171
|
+
})
|
|
172
|
+
.filter((p) => typeof p !== "undefined");
|
|
173
|
+
const convertActivitiesTestRunArgs = (args) => isArray(args) ? args.map((a) => (isObject(a) && isString(a.value) ? a.value : undefined)) : [];
|
|
174
|
+
const createTestDetailsRunLookup = (nodes) => createTestRunLookup(collectRunsFromTestDetails(nodes));
|
|
175
|
+
const findNextAttemptDataFromTestDetails = (lookup, selector) => {
|
|
176
|
+
const attempt = lookupNextTestAttempt(lookup, selector, ({ emitted }) => !emitted);
|
|
177
|
+
if (attempt) {
|
|
178
|
+
attempt.emitted = true;
|
|
179
|
+
}
|
|
180
|
+
return attempt;
|
|
181
|
+
};
|
|
182
|
+
const collectRunsFromTestDetails = (nodes, coordinates = {}) => {
|
|
183
|
+
return (ensureArrayWithItems(nodes, isObject) ?? []).flatMap((node) => {
|
|
184
|
+
const { children, duration, nodeIdentifier, name: nodeName, result } = node;
|
|
185
|
+
let coordinateCreated = true;
|
|
186
|
+
let repetition;
|
|
187
|
+
switch (ensureLiteral(node.nodeType, XcTestNodeTypeValues)) {
|
|
188
|
+
case "Device":
|
|
189
|
+
if (isString(nodeIdentifier)) {
|
|
190
|
+
coordinates = { ...coordinates, device: nodeIdentifier };
|
|
191
|
+
}
|
|
192
|
+
case "Repetition":
|
|
193
|
+
repetition = ensureInt(nodeIdentifier);
|
|
194
|
+
if (repetition) {
|
|
195
|
+
coordinates = { ...coordinates, attempt: repetition };
|
|
196
|
+
}
|
|
197
|
+
case "Arguments":
|
|
198
|
+
if ("args" in coordinates) {
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
if (isString(nodeName)) {
|
|
202
|
+
coordinates = { ...coordinates, args: extractArguments(children) };
|
|
203
|
+
}
|
|
204
|
+
case "Test Plan Configuration":
|
|
205
|
+
if (isString(nodeIdentifier)) {
|
|
206
|
+
coordinates = { ...coordinates, testPlan: nodeIdentifier };
|
|
207
|
+
}
|
|
208
|
+
default:
|
|
209
|
+
coordinateCreated = false;
|
|
210
|
+
}
|
|
211
|
+
const runs = collectRunsFromTestDetails(children, coordinates);
|
|
212
|
+
return runs.length
|
|
213
|
+
? runs
|
|
214
|
+
: coordinateCreated
|
|
215
|
+
? [
|
|
216
|
+
coordinates,
|
|
217
|
+
{
|
|
218
|
+
duration: parseDuration(duration),
|
|
219
|
+
parameters: coordinates.args?.map((arg) => arg?.parameter) ?? [],
|
|
220
|
+
result: ensureLiteral(result, XcTestResultValues) ?? "unknown",
|
|
221
|
+
},
|
|
222
|
+
]
|
|
223
|
+
: [];
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
const extractArguments = (nodes) => {
|
|
227
|
+
if (isArray(nodes)) {
|
|
228
|
+
const argumentsNodeIndex = nodes.findIndex((node) => isObject(node) && isLiteral(node.nodeType, ["Arguments"]));
|
|
229
|
+
const { children } = nodes.splice(argumentsNodeIndex, 1)[0];
|
|
230
|
+
return (ensureArrayWithItems(children, isObject) ?? [])
|
|
231
|
+
.filter(({ nodeType }) => isLiteral(nodeType, ["Test Value"]))
|
|
232
|
+
.map(({ name }) => {
|
|
233
|
+
if (isString(name) && name) {
|
|
234
|
+
const colonIndex = name.indexOf(":");
|
|
235
|
+
if (colonIndex !== -1) {
|
|
236
|
+
return {
|
|
237
|
+
parameter: name.slice(0, colonIndex).trim(),
|
|
238
|
+
value: name.slice(colonIndex + 1).trim(),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return [];
|
|
245
|
+
};
|
|
246
|
+
const convertFullName = (testId, testBundle) => testBundle ? `${testBundle}/${testId}` : testId;
|
|
247
|
+
const convertTestCaseLabels = (bundle, suites, testId, tags) => {
|
|
248
|
+
const labels = [];
|
|
249
|
+
if (bundle) {
|
|
250
|
+
labels.push({ name: "package", value: bundle });
|
|
251
|
+
}
|
|
252
|
+
const [testClass, testMethod] = convertTestClassAndMethod(testId);
|
|
253
|
+
if (testClass) {
|
|
254
|
+
labels.push({ name: "testClass", value: testClass });
|
|
255
|
+
}
|
|
256
|
+
if (testMethod) {
|
|
257
|
+
labels.push({ name: "testMethod", value: testMethod });
|
|
258
|
+
}
|
|
259
|
+
if (suites.length) {
|
|
260
|
+
if (suites.length === 1) {
|
|
261
|
+
labels.push({ name: "suite", value: suites[0] });
|
|
262
|
+
}
|
|
263
|
+
if (suites.length === 2) {
|
|
264
|
+
labels.push({ name: "suite", value: suites[0] }, { name: "subSuite", value: suites[1] });
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const [parentSuite, suite, ...subSuites] = suites;
|
|
268
|
+
labels.push({ name: "parentSuite", value: parentSuite }, { name: "suite", value: suite }, { name: "subSuite", value: subSuites.join(" > ") });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
labels.push(...(ensureArrayWithItems(tags, isString)?.map((t) => ({ name: "tag", value: t })) ?? []));
|
|
272
|
+
return labels;
|
|
273
|
+
};
|
|
274
|
+
const processActivityTestRunDevice = (device, showDevice) => {
|
|
275
|
+
const labels = [];
|
|
276
|
+
const parameters = [];
|
|
277
|
+
const { architecture, deviceId, deviceName, modelName, osVersion, platform } = ensureObject(device) ?? {};
|
|
278
|
+
const host = convertHost(device);
|
|
279
|
+
if (isString(deviceName) && deviceName) {
|
|
280
|
+
labels.push({ name: "host", value: host });
|
|
281
|
+
parameters.push({ name: "Target", value: deviceName, hidden: !showDevice });
|
|
282
|
+
if (showDevice) {
|
|
283
|
+
const targetDetails = getTargetDetails({
|
|
284
|
+
architecture: ensureString(architecture),
|
|
285
|
+
model: ensureString(modelName),
|
|
286
|
+
platform: ensureString(platform),
|
|
287
|
+
osVersion: ensureString(osVersion),
|
|
288
|
+
});
|
|
289
|
+
if (targetDetails) {
|
|
290
|
+
parameters.push({ name: "Target details", value: targetDetails, excluded: true });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return { labels, parameters, deviceId: ensureString(deviceId) };
|
|
295
|
+
};
|
|
296
|
+
const convertHost = (device) => {
|
|
297
|
+
const { deviceName, deviceId } = ensureObject(device) ?? {};
|
|
298
|
+
return ensureString(deviceName) ?? ensureString(deviceId);
|
|
299
|
+
};
|
|
300
|
+
const convertTestClassAndMethod = (testId) => {
|
|
301
|
+
const parts = testId.split("/");
|
|
302
|
+
return [parts.slice(0, -1).join("."), parts.at(-1)];
|
|
303
|
+
};
|
|
304
|
+
const parseDuration = (duration) => {
|
|
305
|
+
if (isString(duration)) {
|
|
306
|
+
const match = DURATION_PATTERN.exec(duration);
|
|
307
|
+
if (match) {
|
|
308
|
+
return secondsToMilliseconds(parseFloat(match[0]));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResultFile } from "@allurereport/plugin-api";
|
|
2
|
+
import type { RawTestResult } from "@allurereport/reader-api";
|
|
3
|
+
import { XcresultParser } from "../model.js";
|
|
4
|
+
import type { LegacyApiParsingOptions } from "./model.js";
|
|
5
|
+
export default class LegacyApiParser extends XcresultParser {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(options: LegacyApiParsingOptions);
|
|
8
|
+
legacyApiSucceeded: () => boolean;
|
|
9
|
+
parse(): AsyncGenerator<ResultFile | RawTestResult, void, unknown>;
|
|
10
|
+
}
|