@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.
Files changed (33) hide show
  1. package/dist/allure2/index.js +3 -0
  2. package/dist/allure2/model.d.ts +3 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +1 -0
  5. package/dist/xcresult/bundle.d.ts +7 -0
  6. package/dist/xcresult/bundle.js +68 -0
  7. package/dist/xcresult/index.d.ts +2 -0
  8. package/dist/xcresult/index.js +91 -0
  9. package/dist/xcresult/model.d.ts +61 -0
  10. package/dist/xcresult/model.js +1 -0
  11. package/dist/xcresult/utils.d.ts +42 -0
  12. package/dist/xcresult/utils.js +378 -0
  13. package/dist/xcresult/xcresulttool/cli.d.ts +10 -0
  14. package/dist/xcresult/xcresulttool/cli.js +42 -0
  15. package/dist/xcresult/xcresulttool/index.d.ts +7 -0
  16. package/dist/xcresult/xcresulttool/index.js +311 -0
  17. package/dist/xcresult/xcresulttool/legacy/index.d.ts +10 -0
  18. package/dist/xcresult/xcresulttool/legacy/index.js +455 -0
  19. package/dist/xcresult/xcresulttool/legacy/model.d.ts +74 -0
  20. package/dist/xcresult/xcresulttool/legacy/model.js +1 -0
  21. package/dist/xcresult/xcresulttool/legacy/parsing.d.ts +15 -0
  22. package/dist/xcresult/xcresulttool/legacy/parsing.js +41 -0
  23. package/dist/xcresult/xcresulttool/legacy/utils.d.ts +7 -0
  24. package/dist/xcresult/xcresulttool/legacy/utils.js +33 -0
  25. package/dist/xcresult/xcresulttool/legacy/xcModel.d.ts +357 -0
  26. package/dist/xcresult/xcresulttool/legacy/xcModel.js +5 -0
  27. package/dist/xcresult/xcresulttool/model.d.ts +17 -0
  28. package/dist/xcresult/xcresulttool/model.js +6 -0
  29. package/dist/xcresult/xcresulttool/utils.d.ts +3 -0
  30. package/dist/xcresult/xcresulttool/utils.js +74 -0
  31. package/dist/xcresult/xcresulttool/xcModel.d.ts +96 -0
  32. package/dist/xcresult/xcresulttool/xcModel.js +18 -0
  33. package/package.json +10 -8
@@ -0,0 +1,455 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ 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");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _LegacyApiParser_instances, _LegacyApiParser_xcode16Plus, _LegacyApiParser_legacyCliSucceeded, _LegacyApiParser_noLegacyApi, _LegacyApiParser_traverseActionTestSummaries, _LegacyApiParser_visitActionTestMetadata, _LegacyApiParser_visitActionTestSummary, _LegacyApiParser_visitActionTestSummaryGroup, _LegacyApiParser_processActivities, _LegacyApiParser_processFailures, _LegacyApiParser_parseFailureEntries, _LegacyApiParser_parseExpectedFailureEntries, _LegacyApiParser_toFailureMapEntry, _LegacyApiParser_parseAttachments, _LegacyApiParser_getRoot, _LegacyApiParser_getById, _LegacyApiParser_getFileById, _LegacyApiParser_xcresulttoolGetLegacy;
13
+ import { BufferResultFile, ensureObject, isDefined, isObject } from "@allurereport/reader-api";
14
+ import { randomUUID } from "node:crypto";
15
+ import { DEFAULT_BUNDLE_NAME, DEFAULT_EXPECTED_FAILURE_REASON, DEFAULT_STEP_NAME, DEFAULT_SUITE_ID, DEFAULT_SUITE_NAME, DEFAULT_TEST_NAME, applyApiCalls, createTestLabels, getDefaultAttachmentName, getMediaTypeByUti, getTargetDetails, getWorstStatusWithDetails, parseAsAllureApiActivity, prependTitle, secondsToMilliseconds, toSortedSteps, } from "../../utils.js";
16
+ import { xcresulttool, xcresulttoolBinary } from "../cli.js";
17
+ import { XcresultParser } from "../model.js";
18
+ import { mapWellKnownAttachmentName } from "../utils.js";
19
+ import { getBool, getDate, getDouble, getInt, getObjectArray, getRef, getString, getStringArray, getURL, getUnionType, } from "./parsing.js";
20
+ import { convertTraceLine, getTestClassFromSuites, resolveFailureStepStatus, resolveTestStatus, withNewSuite, } from "./utils.js";
21
+ import { XcActionTestSummaryIdentifiableObjectTypes } from "./xcModel.js";
22
+ const IDENTIFIER_URL_PREFIX = "test://com.apple.xcode/";
23
+ const ACTIVITY_TYPE_ATTACHMENT = "com.apple.dt.xctest.activity-type.attachmentContainer";
24
+ class LegacyApiParser extends XcresultParser {
25
+ constructor(options) {
26
+ super(options);
27
+ _LegacyApiParser_instances.add(this);
28
+ _LegacyApiParser_xcode16Plus.set(this, void 0);
29
+ _LegacyApiParser_legacyCliSucceeded.set(this, false);
30
+ _LegacyApiParser_noLegacyApi.set(this, false);
31
+ this.legacyApiSucceeded = () => __classPrivateFieldGet(this, _LegacyApiParser_legacyCliSucceeded, "f") || !__classPrivateFieldGet(this, _LegacyApiParser_noLegacyApi, "f");
32
+ _LegacyApiParser_processActivities.set(this, async (failures, activities) => {
33
+ const steps = [];
34
+ const files = [];
35
+ const apiCalls = [];
36
+ const failureSteps = [];
37
+ for (const activity of activities) {
38
+ const { activityType, title, start, finish, attachments: rawAttachments, subactivities: rawSubactivities, failureSummaryIDs, expectedFailureIDs, } = activity;
39
+ const attachments = getObjectArray(rawAttachments);
40
+ const subactivities = getObjectArray(rawSubactivities);
41
+ const failureIds = getStringArray(failureSummaryIDs);
42
+ const expectedFailureIds = getStringArray(expectedFailureIDs);
43
+ const { steps: thisStepAttachmentSteps, files: thisStepFiles } = await __classPrivateFieldGet(this, _LegacyApiParser_parseAttachments, "f").call(this, attachments);
44
+ if (getString(activityType) === ACTIVITY_TYPE_ATTACHMENT) {
45
+ files.push(...thisStepFiles);
46
+ steps.push(...thisStepAttachmentSteps);
47
+ continue;
48
+ }
49
+ const name = getString(title);
50
+ if (attachments.length === 0 && subactivities.length === 0 && failureIds.length === 0) {
51
+ const parsedAllureApiCall = parseAsAllureApiActivity(name);
52
+ if (isDefined(parsedAllureApiCall)) {
53
+ apiCalls.push(parsedAllureApiCall);
54
+ continue;
55
+ }
56
+ }
57
+ const { steps: activitySubsteps, files: substepFiles, apiCalls: substepApiCalls, failureSteps: substepFailureSteps, } = await __classPrivateFieldGet(this, _LegacyApiParser_processActivities, "f").call(this, failures, subactivities);
58
+ const { directFailureSteps, transitiveFailureSteps, message, trace, status } = resolveStepFailures(failureIds, expectedFailureIds, failures, substepFailureSteps);
59
+ const substeps = toSortedSteps(thisStepAttachmentSteps, activitySubsteps, directFailureSteps);
60
+ steps.push({
61
+ type: "step",
62
+ name: name ?? DEFAULT_STEP_NAME,
63
+ start: getDate(start),
64
+ stop: getDate(finish),
65
+ status: status ?? "passed",
66
+ message,
67
+ trace,
68
+ steps: substeps,
69
+ });
70
+ files.push(...thisStepFiles, ...substepFiles);
71
+ apiCalls.push(...substepApiCalls);
72
+ failureSteps.push(...transitiveFailureSteps);
73
+ }
74
+ fillDefaultAttachmentNames(steps);
75
+ return { steps, files, apiCalls, failureSteps };
76
+ });
77
+ _LegacyApiParser_processFailures.set(this, async (failures, expectedFailures) => {
78
+ const failureEntries = await __classPrivateFieldGet(this, _LegacyApiParser_parseFailureEntries, "f").call(this, failures);
79
+ const expectedFailureEntries = await __classPrivateFieldGet(this, _LegacyApiParser_parseExpectedFailureEntries, "f").call(this, expectedFailures);
80
+ return new Map([...failureEntries, ...expectedFailureEntries]);
81
+ });
82
+ _LegacyApiParser_parseFailureEntries.set(this, async (failures) => {
83
+ const entries = [];
84
+ for (const summary of getObjectArray(failures)) {
85
+ const entry = await __classPrivateFieldGet(this, _LegacyApiParser_toFailureMapEntry, "f").call(this, summary);
86
+ if (entry) {
87
+ entries.push(entry);
88
+ }
89
+ }
90
+ return entries;
91
+ });
92
+ _LegacyApiParser_parseExpectedFailureEntries.set(this, async (expectedFailures) => {
93
+ const entries = [];
94
+ for (const { uuid, failureReason, failureSummary, isTopLevelFailure } of getObjectArray(expectedFailures)) {
95
+ if (isObject(failureSummary)) {
96
+ const mapMessage = (message) => {
97
+ const prefix = getString(failureReason) ?? DEFAULT_EXPECTED_FAILURE_REASON;
98
+ return message ? prependTitle(`${prefix}:`, message, 2) : prefix;
99
+ };
100
+ const entry = await __classPrivateFieldGet(this, _LegacyApiParser_toFailureMapEntry, "f").call(this, failureSummary, {
101
+ uuid,
102
+ status: "passed",
103
+ isTopLevel: getBool(isTopLevelFailure),
104
+ mapMessage,
105
+ });
106
+ if (entry) {
107
+ entries.push(entry);
108
+ }
109
+ }
110
+ }
111
+ return entries;
112
+ });
113
+ _LegacyApiParser_toFailureMapEntry.set(this, async ({ attachments, message: rawMessage, sourceCodeContext, timestamp, uuid: rawUuid, isTopLevelFailure, issueType, }, { uuid: explicitUuid, mapMessage, status: explicitStatus, isTopLevel: explicitTopLevelFlag } = {}) => {
114
+ const { steps, files } = await __classPrivateFieldGet(this, _LegacyApiParser_parseAttachments, "f").call(this, getObjectArray(attachments));
115
+ const message = getString(rawMessage);
116
+ const status = explicitStatus ?? resolveFailureStepStatus(getString(issueType));
117
+ const trace = convertStackTrace(sourceCodeContext);
118
+ const start = getDate(timestamp);
119
+ const uuid = getString(explicitUuid) ?? getString(rawUuid);
120
+ return uuid
121
+ ? [
122
+ uuid,
123
+ {
124
+ step: {
125
+ type: "step",
126
+ start,
127
+ stop: start,
128
+ duration: 0,
129
+ message: mapMessage?.(message) ?? message,
130
+ name: message,
131
+ status,
132
+ steps,
133
+ trace,
134
+ },
135
+ files,
136
+ isTopLevel: explicitTopLevelFlag ?? getBool(isTopLevelFailure),
137
+ },
138
+ ]
139
+ : undefined;
140
+ });
141
+ _LegacyApiParser_parseAttachments.set(this, async (attachments) => {
142
+ const steps = [];
143
+ const files = [];
144
+ for (const attachment of attachments) {
145
+ const { name: rawName, timestamp, uuid: rawUuid, filename: rawFileName, uniformTypeIdentifier, payloadRef, } = attachment;
146
+ const uuid = getString(rawUuid);
147
+ if (uuid) {
148
+ const start = getDate(timestamp);
149
+ const name = getString(rawName);
150
+ const fileName = ensureUniqueFileName(rawFileName);
151
+ const step = {
152
+ type: "attachment",
153
+ originalFileName: fileName,
154
+ name: mapWellKnownAttachmentName(name, start),
155
+ start,
156
+ stop: start,
157
+ contentType: getMediaTypeByUti(getString(uniformTypeIdentifier)),
158
+ };
159
+ const file = (await this.createAttachmentFile?.(uuid, fileName)) ?? (await __classPrivateFieldGet(this, _LegacyApiParser_getFileById, "f").call(this, payloadRef, fileName));
160
+ steps.push(step);
161
+ if (file) {
162
+ files.push(file);
163
+ }
164
+ }
165
+ }
166
+ return { steps, files };
167
+ });
168
+ _LegacyApiParser_getRoot.set(this, () => __classPrivateFieldGet(this, _LegacyApiParser_xcresulttoolGetLegacy, "f").call(this, []));
169
+ _LegacyApiParser_getById.set(this, async (ref) => {
170
+ const id = getRef(ref);
171
+ return id ? await __classPrivateFieldGet(this, _LegacyApiParser_xcresulttoolGetLegacy, "f").call(this, ["--id", id]) : undefined;
172
+ });
173
+ _LegacyApiParser_getFileById.set(this, async (ref, uniqueFileName) => {
174
+ const id = getRef(ref);
175
+ if (id) {
176
+ const legacyFlagArgs = __classPrivateFieldGet(this, _LegacyApiParser_xcode16Plus, "f") ? ["--legacy"] : [];
177
+ const content = await xcresulttoolBinary("get", ...legacyFlagArgs, "--path", this.xcResultPath, "--id", id);
178
+ if (content) {
179
+ return new BufferResultFile(content, uniqueFileName);
180
+ }
181
+ }
182
+ });
183
+ _LegacyApiParser_xcresulttoolGetLegacy.set(this, async (args = []) => {
184
+ if (__classPrivateFieldGet(this, _LegacyApiParser_noLegacyApi, "f")) {
185
+ return undefined;
186
+ }
187
+ const legacyFlagArgs = __classPrivateFieldGet(this, _LegacyApiParser_xcode16Plus, "f") ? ["--legacy"] : [];
188
+ const result = await xcresulttool("get", ...legacyFlagArgs, "--format", "json", "--path", this.xcResultPath, ...args);
189
+ if (typeof result === "undefined") {
190
+ if (!__classPrivateFieldGet(this, _LegacyApiParser_legacyCliSucceeded, "f")) {
191
+ __classPrivateFieldSet(this, _LegacyApiParser_noLegacyApi, true, "f");
192
+ }
193
+ return undefined;
194
+ }
195
+ __classPrivateFieldSet(this, _LegacyApiParser_legacyCliSucceeded, true, "f");
196
+ return result;
197
+ });
198
+ __classPrivateFieldSet(this, _LegacyApiParser_xcode16Plus, options.xcode16Plus, "f");
199
+ }
200
+ async *parse() {
201
+ const root = await __classPrivateFieldGet(this, _LegacyApiParser_getRoot, "f").call(this);
202
+ const actions = getObjectArray(ensureObject(root)?.actions);
203
+ const actionDescriminators = parseActionDiscriminators(actions);
204
+ const multiTarget = isMultiTarget(actionDescriminators);
205
+ const multiTestPlan = isMultiTestPlan(actionDescriminators);
206
+ for (const { actionResult } of actions) {
207
+ const { destination, testPlan } = actionDescriminators.shift();
208
+ const testsRef = ensureObject(actionResult)?.testsRef;
209
+ const testPlanRunSummaries = await __classPrivateFieldGet(this, _LegacyApiParser_getById, "f").call(this, testsRef);
210
+ const summaries = ensureObject(testPlanRunSummaries)?.summaries;
211
+ for (const { testableSummaries } of getObjectArray(summaries)) {
212
+ for (const { name, tests } of getObjectArray(testableSummaries)) {
213
+ const bundle = getString(name) ?? DEFAULT_BUNDLE_NAME;
214
+ yield* __classPrivateFieldGet(this, _LegacyApiParser_instances, "m", _LegacyApiParser_traverseActionTestSummaries).call(this, tests, {
215
+ bundle,
216
+ suites: [],
217
+ destination,
218
+ testPlan,
219
+ multiTarget,
220
+ multiTestPlan,
221
+ });
222
+ }
223
+ }
224
+ }
225
+ }
226
+ }
227
+ _LegacyApiParser_xcode16Plus = new WeakMap(), _LegacyApiParser_legacyCliSucceeded = new WeakMap(), _LegacyApiParser_noLegacyApi = new WeakMap(), _LegacyApiParser_processActivities = new WeakMap(), _LegacyApiParser_processFailures = new WeakMap(), _LegacyApiParser_parseFailureEntries = new WeakMap(), _LegacyApiParser_parseExpectedFailureEntries = new WeakMap(), _LegacyApiParser_toFailureMapEntry = new WeakMap(), _LegacyApiParser_parseAttachments = new WeakMap(), _LegacyApiParser_getRoot = new WeakMap(), _LegacyApiParser_getById = new WeakMap(), _LegacyApiParser_getFileById = new WeakMap(), _LegacyApiParser_xcresulttoolGetLegacy = new WeakMap(), _LegacyApiParser_instances = new WeakSet(), _LegacyApiParser_traverseActionTestSummaries = async function* _LegacyApiParser_traverseActionTestSummaries(array, state) {
228
+ for (const obj of getObjectArray(array)) {
229
+ switch (getUnionType(obj, XcActionTestSummaryIdentifiableObjectTypes)) {
230
+ case "ActionTestMetadata":
231
+ yield* __classPrivateFieldGet(this, _LegacyApiParser_instances, "m", _LegacyApiParser_visitActionTestMetadata).call(this, obj, state);
232
+ break;
233
+ case "ActionTestSummary":
234
+ yield* __classPrivateFieldGet(this, _LegacyApiParser_instances, "m", _LegacyApiParser_visitActionTestSummary).call(this, obj, state);
235
+ break;
236
+ case "ActionTestSummaryGroup":
237
+ yield* __classPrivateFieldGet(this, _LegacyApiParser_instances, "m", _LegacyApiParser_visitActionTestSummaryGroup).call(this, obj, state);
238
+ break;
239
+ }
240
+ }
241
+ }, _LegacyApiParser_visitActionTestMetadata = async function* _LegacyApiParser_visitActionTestMetadata({ summaryRef }, state) {
242
+ const summary = await __classPrivateFieldGet(this, _LegacyApiParser_getById, "f").call(this, summaryRef);
243
+ if (isObject(summary)) {
244
+ yield* __classPrivateFieldGet(this, _LegacyApiParser_instances, "m", _LegacyApiParser_visitActionTestSummary).call(this, summary, state);
245
+ }
246
+ }, _LegacyApiParser_visitActionTestSummary = async function* _LegacyApiParser_visitActionTestSummary({ arguments: args, duration, identifierURL, name: rawName, summary, activitySummaries, tags, trackedIssues, failureSummaries, expectedFailures, testStatus, repetitionPolicySummary, skipNoticeSummary, }, state) {
247
+ const { bundle, suites, destination: { hostName } = {} } = state;
248
+ const fullName = getString(identifierURL) ?? randomUUID();
249
+ const projectName = parseProjectName(fullName);
250
+ const functionName = getString(rawName);
251
+ const name = getString(summary) ?? functionName ?? DEFAULT_TEST_NAME;
252
+ const status = getString(testStatus);
253
+ const labels = createTestLabels({
254
+ hostName,
255
+ projectName,
256
+ bundle,
257
+ functionName,
258
+ suites: suites.map(({ name: suite }) => suite),
259
+ className: getTestClassFromSuites(suites),
260
+ tags: parseTestTags(tags),
261
+ });
262
+ const parameters = getAllTestResultParameters(state, args, repetitionPolicySummary);
263
+ const failures = await __classPrivateFieldGet(this, _LegacyApiParser_processFailures, "f").call(this, failureSummaries, expectedFailures);
264
+ const { steps: activitySteps, files, apiCalls, } = await __classPrivateFieldGet(this, _LegacyApiParser_processActivities, "f").call(this, failures, getObjectArray(activitySummaries));
265
+ const { message, trace, steps: failureSteps, status: worstFailedStepStatus, } = resolveTestFailures(failures, skipNoticeSummary);
266
+ const steps = toSortedSteps(activitySteps, failureSteps);
267
+ const testResult = {
268
+ uuid: randomUUID(),
269
+ fullName,
270
+ name,
271
+ duration: secondsToMilliseconds(getDouble(duration)),
272
+ labels,
273
+ parameters,
274
+ steps,
275
+ links: parseTrackedIssues(trackedIssues),
276
+ message,
277
+ status: resolveTestStatus(status, worstFailedStepStatus),
278
+ trace,
279
+ };
280
+ applyApiCalls(testResult, apiCalls);
281
+ yield* files;
282
+ yield* iterateFailureFiles(failures);
283
+ yield testResult;
284
+ }, _LegacyApiParser_visitActionTestSummaryGroup = async function* _LegacyApiParser_visitActionTestSummaryGroup({ name, identifierURL, summary, subtests }, state) {
285
+ const suiteId = getString(name);
286
+ const suiteName = getString(summary) ?? suiteId ?? DEFAULT_SUITE_NAME;
287
+ const suiteUri = getString(identifierURL);
288
+ const { suites: parentSuites } = state;
289
+ const suites = withNewSuite(parentSuites, suiteId ?? DEFAULT_SUITE_ID, suiteUri, suiteName);
290
+ yield* __classPrivateFieldGet(this, _LegacyApiParser_instances, "m", _LegacyApiParser_traverseActionTestSummaries).call(this, subtests, { ...state, suites });
291
+ };
292
+ export default LegacyApiParser;
293
+ const parseActionDiscriminators = (actions) => {
294
+ return actions.map(({ runDestination, testPlanName }) => ({
295
+ destination: parseDestination(runDestination),
296
+ testPlan: getString(testPlanName),
297
+ }));
298
+ };
299
+ const isMultiTarget = (discriminators) => new Set(discriminators
300
+ .map(({ destination }) => destination)
301
+ .filter(isDefined)
302
+ .map(({ name }) => name)
303
+ .filter(isDefined)).size > 1;
304
+ const isMultiTestPlan = (discriminators) => new Set(discriminators.map(({ testPlan }) => testPlan).filter(isDefined)).size > 1;
305
+ const parseDestination = (element) => {
306
+ if (isObject(element)) {
307
+ const { displayName, targetArchitecture, targetDeviceRecord, localComputerRecord } = element;
308
+ const targetName = getString(displayName);
309
+ const hostName = parseHostName(localComputerRecord);
310
+ const architecture = getString(targetArchitecture);
311
+ const { model, platform, osVersion } = parseTargetDevice(targetDeviceRecord) ?? {};
312
+ return {
313
+ name: targetName,
314
+ hostName,
315
+ targetDetails: getTargetDetails({ architecture, model, platform, osVersion }),
316
+ };
317
+ }
318
+ };
319
+ const parseHostName = (element) => getString(ensureObject(element)?.name);
320
+ const parseTargetDevice = (element) => {
321
+ if (isObject(element)) {
322
+ const { modelName, operatingSystemVersion, platformRecord } = element;
323
+ return {
324
+ model: getString(modelName),
325
+ platform: parsePlatform(platformRecord),
326
+ osVersion: getString(operatingSystemVersion),
327
+ };
328
+ }
329
+ };
330
+ const parsePlatform = (element) => getString(ensureObject(element)?.userDescription);
331
+ const iterateFailureFiles = function* (failures) {
332
+ for (const { files } of failures.values()) {
333
+ yield* files;
334
+ }
335
+ };
336
+ const parseTrackedIssues = (issues) => getObjectArray(issues)
337
+ .map(({ comment, identifier, url: rawUrl }) => {
338
+ const issueId = getString(identifier);
339
+ const name = getString(comment) ?? (issueId ? `Issue ${issueId}` : undefined);
340
+ const url = getURL(rawUrl) ?? issueId;
341
+ return url ? { type: "issue", name, url } : undefined;
342
+ })
343
+ .filter(isDefined);
344
+ const convertStackTrace = (sourceCodeContext) => {
345
+ const callStack = ensureObject(sourceCodeContext)?.callStack;
346
+ return getObjectArray(callStack)
347
+ .map(({ symbolInfo }) => symbolInfo)
348
+ .filter(isObject)
349
+ .map(({ location, symbolName }) => {
350
+ const { filePath, lineNumber } = ensureObject(location) ?? {};
351
+ return convertTraceLine(getString(symbolName), getString(filePath), getInt(lineNumber));
352
+ })
353
+ .filter(isDefined)
354
+ .join("\n");
355
+ };
356
+ const fillDefaultAttachmentNames = (steps) => {
357
+ const attachmentSteps = steps.filter((s) => s.type === "attachment");
358
+ const totalAttachments = attachmentSteps.length;
359
+ attachmentSteps.forEach((s, i) => {
360
+ s.name ?? (s.name = getDefaultAttachmentName(i, totalAttachments));
361
+ });
362
+ };
363
+ const resolveStepFailures = (failureUids, expectedFailureUids, failures, failureStepsOfSubsteps) => {
364
+ const stepFailures = [...failureUids, ...expectedFailureUids].map((uuid) => failures.get(uuid));
365
+ const directFailureSteps = resolveStepFailureSubsteps(stepFailures);
366
+ const transitiveFailureSteps = toSortedSteps(directFailureSteps, failureStepsOfSubsteps);
367
+ const { status, trace, message } = getWorstStatusWithDetails(transitiveFailureSteps) ?? {};
368
+ return { status, message, trace, directFailureSteps, transitiveFailureSteps };
369
+ };
370
+ const resolveTestFailures = (failures, skipNoticeSummary) => {
371
+ const allFailures = Array.from(failures.values());
372
+ const transitiveFailureSteps = allFailures.map(({ step }) => step);
373
+ const { status, trace, message } = getWorstStatusWithDetails(transitiveFailureSteps) ?? {};
374
+ const steps = resolveTestFailureSteps(allFailures);
375
+ if (!message && !trace && isObject(skipNoticeSummary)) {
376
+ const { fileName, lineNumber, message: skipMessage } = skipNoticeSummary;
377
+ return {
378
+ steps,
379
+ status,
380
+ message: getString(skipMessage),
381
+ trace: convertTraceLine(undefined, getString(fileName), getInt(lineNumber)),
382
+ };
383
+ }
384
+ return { status, message, trace, steps };
385
+ };
386
+ const resolveTestFailureSteps = (failures) => failures.filter(({ isTopLevel }) => isTopLevel).map(({ step }) => step);
387
+ const resolveStepFailureSubsteps = (stepFailures) => {
388
+ return stepFailures.map((failure) => failure?.step ??
389
+ {
390
+ type: "step",
391
+ duration: 0,
392
+ message: "An unknown failure has occured",
393
+ status: "broken",
394
+ });
395
+ };
396
+ const ensureUniqueFileName = (fileName) => getString(fileName) ?? randomUUID();
397
+ const getAllTestResultParameters = (state, args, repetition) => [...convertActionParameters(state), convertRepetitionParameter(repetition), ...convertTestParameters(args)].filter(isDefined);
398
+ const convertActionParameters = ({ destination, testPlan, multiTarget, multiTestPlan }) => {
399
+ const parameters = [];
400
+ if (multiTestPlan && testPlan) {
401
+ parameters.push({ name: "Test Plan", value: testPlan, excluded: true });
402
+ }
403
+ if (destination) {
404
+ const { name, targetDetails } = destination;
405
+ if (isDefined(name)) {
406
+ parameters.push({ name: "Device", value: name });
407
+ if (multiTarget && targetDetails) {
408
+ parameters.push({ name: "Device Details", value: targetDetails, excluded: true });
409
+ }
410
+ }
411
+ }
412
+ return parameters;
413
+ };
414
+ const convertTestParameters = (args) => getObjectArray(args).map(({ parameter, value }) => {
415
+ const parameterName = getParameterName(parameter);
416
+ const argumentValue = getArgumentValue(value);
417
+ return isDefined(parameterName) && isDefined(argumentValue)
418
+ ? {
419
+ name: parameterName,
420
+ value: argumentValue,
421
+ }
422
+ : undefined;
423
+ });
424
+ const convertRepetitionParameter = (repetition) => {
425
+ const { iteration, totalIterations } = ensureObject(repetition) ?? {};
426
+ const current = getInt(iteration);
427
+ const total = getInt(totalIterations);
428
+ if (current) {
429
+ return {
430
+ name: "Repetition",
431
+ value: total ? `Repetition ${current} of ${total}` : `Repetition ${current}`,
432
+ excluded: true,
433
+ };
434
+ }
435
+ };
436
+ const parseProjectName = (url) => {
437
+ if (url && url.startsWith(IDENTIFIER_URL_PREFIX)) {
438
+ const urlPath = url.slice(IDENTIFIER_URL_PREFIX.length);
439
+ const projectNameEnd = urlPath.indexOf("/");
440
+ if (projectNameEnd !== -1) {
441
+ const projectName = urlPath.slice(0, projectNameEnd);
442
+ try {
443
+ return decodeURIComponent(projectName);
444
+ }
445
+ catch {
446
+ return projectName;
447
+ }
448
+ }
449
+ }
450
+ };
451
+ const parseTestTags = (tags) => getObjectArray(tags)
452
+ .map(({ name }) => getString(name))
453
+ .filter(isDefined);
454
+ const getParameterName = (parameter) => isObject(parameter) ? (getString(parameter.name) ?? getString(parameter.label)) : undefined;
455
+ const getArgumentValue = (parameter) => isObject(parameter) ? getString(parameter.description) : undefined;
@@ -0,0 +1,74 @@
1
+ import type { ResultFile } from "@allurereport/plugin-api";
2
+ import type { RawStep, RawTestStatus, RawTestStepResult, Unknown } from "@allurereport/reader-api";
3
+ import type { AllureApiCall } from "../../model.js";
4
+ import type { ParsingOptions } from "../model.js";
5
+ import type { XcString } from "./xcModel.js";
6
+ export type LegacyApiParsingOptions = ParsingOptions & {
7
+ xcode16Plus: boolean;
8
+ };
9
+ export type LegacyTestResultData = {
10
+ issues: LegacyIssueTrackingMetadata[];
11
+ trace?: string;
12
+ steps: [];
13
+ };
14
+ export type LegacyIssueTrackingMetadata = {
15
+ url: string;
16
+ title?: string;
17
+ };
18
+ export type LegacyStepResultData = {
19
+ trace?: string;
20
+ steps: [];
21
+ };
22
+ export type LegacyActionDiscriminator = {
23
+ destination: LegacyDestinationData | undefined;
24
+ testPlan: string | undefined;
25
+ };
26
+ export type LegacyDestinationData = {
27
+ name?: string;
28
+ targetDetails?: string;
29
+ hostName?: string;
30
+ };
31
+ export type ActivityProcessingResult = {
32
+ steps: RawStep[];
33
+ files: ResultFile[];
34
+ apiCalls: AllureApiCall[];
35
+ failureSteps: RawTestStepResult[];
36
+ };
37
+ export type Suite = {
38
+ id: string;
39
+ name: string;
40
+ uri: string | undefined;
41
+ };
42
+ export type LegacyParsingState = {
43
+ bundle?: string;
44
+ suites: Suite[];
45
+ destination?: LegacyDestinationData;
46
+ testPlan?: string;
47
+ multiTarget: boolean;
48
+ multiTestPlan: boolean;
49
+ };
50
+ export type ActionParametersInputData = Pick<LegacyParsingState, "destination" | "testPlan" | "multiTarget" | "multiTestPlan">;
51
+ export type ResolvedFailureBase = {
52
+ message?: string;
53
+ trace?: string;
54
+ status?: RawTestStatus;
55
+ };
56
+ export type ResolvedTestFailure = ResolvedFailureBase & {
57
+ steps: RawTestStepResult[];
58
+ };
59
+ export type ResolvedStepFailure = ResolvedFailureBase & {
60
+ directFailureSteps: RawTestStepResult[];
61
+ transitiveFailureSteps: RawTestStepResult[];
62
+ };
63
+ export type FailureMapValue = {
64
+ step: RawTestStepResult;
65
+ files: ResultFile[];
66
+ isTopLevel?: boolean;
67
+ };
68
+ export type FailureMap = Map<string, FailureMapValue>;
69
+ export type FailureOverrides = {
70
+ uuid?: Unknown<XcString>;
71
+ mapMessage?: (message: string | undefined) => string;
72
+ status?: RawTestStatus;
73
+ isTopLevel?: boolean;
74
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { ShallowKnown, Unknown } from "@allurereport/reader-api";
2
+ import type { XcArray, XcBool, XcDate, XcDouble, XcInt, XcObject, XcReference, XcString, XcURL, XcValue } from "./xcModel.js";
3
+ export declare const getType: <Type extends string>({ _type }: ShallowKnown<XcObject<Type>>) => string | undefined;
4
+ export declare const getUnionType: <Type extends string, const L extends readonly string[]>({ _type }: ShallowKnown<XcObject<Type>>, options: L) => ShallowKnown<L[number]> | undefined;
5
+ export declare const getValue: <Type extends string>(value: Unknown<XcValue<Type>>) => string | undefined;
6
+ export declare const getBool: (value: Unknown<XcBool>) => boolean;
7
+ export declare const getInt: (value: Unknown<XcInt>) => number | undefined;
8
+ export declare const getDouble: (value: Unknown<XcDouble>) => number | undefined;
9
+ export declare const getString: (value: Unknown<XcString>) => string | undefined;
10
+ export declare const getDate: (value: Unknown<XcDate>) => number | undefined;
11
+ export declare const getURL: (value: Unknown<XcURL>) => string | undefined;
12
+ export declare const getRef: (ref: Unknown<XcReference>) => string | undefined;
13
+ export declare const getArray: <Type extends string, Element extends XcObject<Type>>(array: Unknown<XcArray<Element>>) => Unknown<Element>[];
14
+ export declare const getStringArray: (array: Unknown<XcArray<XcString>>) => string[];
15
+ export declare const getObjectArray: <Type extends string, Element extends XcObject<Type>>(array: Unknown<XcArray<Element>>) => ShallowKnown<Element>[];
@@ -0,0 +1,41 @@
1
+ import { ensureArray, ensureFloat, ensureInt, ensureLiteral, ensureObject, ensureString, isDefined, isObject, } from "@allurereport/reader-api";
2
+ export const getType = ({ _type }) => isObject(_type) ? ensureString(_type._name) : undefined;
3
+ export const getUnionType = ({ _type }, options) => (isObject(_type) ? ensureLiteral(_type._name, options) : undefined);
4
+ export const getValue = (value) => {
5
+ const obj = ensureObject(value);
6
+ return obj ? ensureString(obj._value) : undefined;
7
+ };
8
+ export const getBool = (value) => {
9
+ const text = getValue(value);
10
+ return text === "true";
11
+ };
12
+ export const getInt = (value) => {
13
+ const text = getValue(value);
14
+ return text ? ensureInt(text) : undefined;
15
+ };
16
+ export const getDouble = (value) => {
17
+ const text = getValue(value);
18
+ return text ? ensureFloat(text) : undefined;
19
+ };
20
+ export const getString = (value) => getValue(value);
21
+ export const getDate = (value) => {
22
+ const text = getValue(value);
23
+ if (text) {
24
+ const parsed = Date.parse(text);
25
+ return isNaN(parsed) ? undefined : parsed;
26
+ }
27
+ };
28
+ export const getURL = (value) => getValue(value);
29
+ export const getRef = (ref) => {
30
+ const obj = ensureObject(ref);
31
+ return obj ? getString(obj.id) : undefined;
32
+ };
33
+ export const getArray = (array) => {
34
+ const arrayObject = ensureObject(array);
35
+ return arrayObject ? (ensureArray(arrayObject._values) ?? []) : [];
36
+ };
37
+ const getValueArray = (array, getElement) => getArray(array).map(getElement).filter(isDefined);
38
+ export const getStringArray = (array) => getValueArray(array, getString);
39
+ export const getObjectArray = (array) => {
40
+ return getArray(array).filter((v) => isObject(v));
41
+ };
@@ -0,0 +1,7 @@
1
+ import type { RawTestStatus } from "@allurereport/reader-api";
2
+ import type { Suite } from "./model.js";
3
+ export declare const withNewSuite: (suites: readonly Suite[], id: string, uri: string | undefined, name: string) => Suite[];
4
+ export declare const getTestClassFromSuites: (suites: readonly Suite[]) => string;
5
+ export declare const resolveTestStatus: (status: string | undefined, worstStepStatus: RawTestStatus | undefined) => RawTestStatus;
6
+ export declare const resolveFailureStepStatus: (issueType: string | undefined) => RawTestStatus;
7
+ export declare const convertTraceLine: (symbolName: string | undefined, filename: string | undefined, line: number | undefined) => string | undefined;
@@ -0,0 +1,33 @@
1
+ import { isDefined } from "@allurereport/reader-api";
2
+ export const withNewSuite = (suites, id, uri, name) => {
3
+ return [...suites.filter(({ uri: parentUri }) => !parentUri || !uri || uri.startsWith(parentUri)), { id, uri, name }];
4
+ };
5
+ export const getTestClassFromSuites = (suites) => suites.map(({ id }) => id).join(".");
6
+ export const resolveTestStatus = (status, worstStepStatus) => {
7
+ switch (status) {
8
+ case "Success":
9
+ case "Expected Failure":
10
+ return "passed";
11
+ case "Failure":
12
+ return worstStepStatus === "broken" ? "broken" : "failed";
13
+ case "Skipped":
14
+ return "skipped";
15
+ default:
16
+ return "unknown";
17
+ }
18
+ };
19
+ export const resolveFailureStepStatus = (issueType) => issueType === "Thrown Error" ? "broken" : "failed";
20
+ export const convertTraceLine = (symbolName, filename, line) => {
21
+ if (filename === "/<compiler-generated>") {
22
+ return undefined;
23
+ }
24
+ const symbolPart = symbolName ? `In ${symbolName}` : undefined;
25
+ const locationPart = filename && isDefined(line) ? `${filename}:${line}` : filename;
26
+ return symbolPart
27
+ ? locationPart
28
+ ? `${symbolName} at ${locationPart}`
29
+ : symbolPart
30
+ : locationPart
31
+ ? `At ${locationPart}`
32
+ : undefined;
33
+ };