xcodebuild-axi 0.1.9 → 0.1.11
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/CHANGELOG.md +152 -1
- package/README.md +25 -57
- package/dist/src/archive.d.ts +35 -6
- package/dist/src/archive.js +63 -21
- package/dist/src/archive.js.map +1 -1
- package/dist/src/commands/coverage.d.ts +13 -2
- package/dist/src/commands/coverage.js +314 -7
- package/dist/src/commands/coverage.js.map +1 -1
- package/dist/src/commands/export.d.ts +4 -4
- package/dist/src/commands/export.js +194 -11
- package/dist/src/commands/export.js.map +1 -1
- package/dist/src/commands/info.d.ts +2 -2
- package/dist/src/commands/info.js +56 -3
- package/dist/src/commands/info.js.map +1 -1
- package/dist/src/commands/result.d.ts +23 -3
- package/dist/src/commands/result.js +654 -7
- package/dist/src/commands/result.js.map +1 -1
- package/dist/src/surface.d.ts +7 -1
- package/dist/src/surface.js +41 -164
- package/dist/src/surface.js.map +1 -1
- package/dist/src/toon.d.ts +2 -0
- package/dist/src/toon.js +15 -0
- package/dist/src/toon.js.map +1 -1
- package/dist/src/xccov.d.ts +94 -0
- package/dist/src/xccov.js +178 -2
- package/dist/src/xccov.js.map +1 -1
- package/dist/src/xcodebuild.d.ts +18 -0
- package/dist/src/xcodebuild.js +38 -1
- package/dist/src/xcodebuild.js.map +1 -1
- package/dist/src/xcresult.d.ts +216 -0
- package/dist/src/xcresult.js +188 -4
- package/dist/src/xcresult.js.map +1 -1
- package/package.json +1 -1
package/dist/src/xccov.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdtempSync, readdirSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
2
5
|
import { AxiError } from "./errors.js";
|
|
3
6
|
/**
|
|
4
7
|
* Code coverage, read out of a result bundle with `xccov`.
|
|
@@ -18,15 +21,30 @@ function xccov(args) {
|
|
|
18
21
|
rejectPromise(new AxiError("That result bundle carries no coverage data", "RESULT_NOT_FOUND", ["Re-run the tests with `xcodebuild-axi test --coverage`"]));
|
|
19
22
|
return;
|
|
20
23
|
}
|
|
21
|
-
rejectPromise(new AxiError(
|
|
24
|
+
rejectPromise(new AxiError(complaint(stderr) || "xccov failed", "RESULT_NOT_FOUND"));
|
|
22
25
|
return;
|
|
23
26
|
}
|
|
24
27
|
resolvePromise(stdout);
|
|
25
28
|
});
|
|
26
29
|
});
|
|
27
30
|
}
|
|
31
|
+
export function coverageSource(path) {
|
|
32
|
+
if (path.endsWith(".xccovreport"))
|
|
33
|
+
return "report";
|
|
34
|
+
if (path.endsWith(".xccovarchive"))
|
|
35
|
+
return "archive";
|
|
36
|
+
return "bundle";
|
|
37
|
+
}
|
|
38
|
+
/** The `view` flags that select the report inside whatever this path is. */
|
|
39
|
+
function reportArgs(path) {
|
|
40
|
+
return coverageSource(path) === "bundle" ? ["view", "--report"] : ["view"];
|
|
41
|
+
}
|
|
42
|
+
/** The `view` flags that select the archive — raw counts, not percentages. */
|
|
43
|
+
function archiveArgs(path) {
|
|
44
|
+
return coverageSource(path) === "bundle" ? ["view", "--archive"] : ["view"];
|
|
45
|
+
}
|
|
28
46
|
export async function readCoverage(resultPath, options = {}) {
|
|
29
|
-
const stdout = await xccov([
|
|
47
|
+
const stdout = await xccov([...reportArgs(resultPath), "--json", resultPath]);
|
|
30
48
|
let parsed;
|
|
31
49
|
try {
|
|
32
50
|
parsed = JSON.parse(stdout);
|
|
@@ -75,4 +93,162 @@ export function percent(fraction) {
|
|
|
75
93
|
function firstLine(text) {
|
|
76
94
|
return text.trim().split("\n")[0] ?? "";
|
|
77
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* xccov's refusals, minus the NSError wrapping.
|
|
98
|
+
*
|
|
99
|
+
* A bad path comes back as `Error: Error Domain=XCCovErrorDomain Code=0
|
|
100
|
+
* "Failed to load result bundle" UserInfo={NSLocalizedDescription=Failed to
|
|
101
|
+
* load result bundle, NSUnderlyingError=0x… {…}}` — 400 characters around a
|
|
102
|
+
* five-word answer that is already in there.
|
|
103
|
+
*/
|
|
104
|
+
function complaint(stderr) {
|
|
105
|
+
const line = firstLine(stderr).replace(/^Error:\s*/, "");
|
|
106
|
+
return line.match(/NSLocalizedDescription=([^,}]+)/)?.[1]?.trim() ?? line;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Per-function coverage for one file.
|
|
110
|
+
*
|
|
111
|
+
* The file is matched by name or by the path it had when the report was
|
|
112
|
+
* written, so it need not exist on disk — which is the point when the report
|
|
113
|
+
* came from CI.
|
|
114
|
+
*/
|
|
115
|
+
export async function readFunctions(path, file) {
|
|
116
|
+
const stdout = await xccov([
|
|
117
|
+
...reportArgs(path),
|
|
118
|
+
"--functions-for-file",
|
|
119
|
+
file,
|
|
120
|
+
"--json",
|
|
121
|
+
path,
|
|
122
|
+
]);
|
|
123
|
+
let parsed;
|
|
124
|
+
try {
|
|
125
|
+
parsed = JSON.parse(stdout);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
throw new AxiError("xccov returned output that could not be read", "RESULT_NOT_FOUND");
|
|
129
|
+
}
|
|
130
|
+
return parsed.map((entry) => ({
|
|
131
|
+
file: entry.file ?? file,
|
|
132
|
+
functions: (entry.functions ?? []).map((fn) => ({
|
|
133
|
+
name: fn.name ?? "unknown",
|
|
134
|
+
lineNumber: fn.lineNumber ?? 0,
|
|
135
|
+
executionCount: fn.executionCount ?? 0,
|
|
136
|
+
lineCoverage: fn.lineCoverage ?? 0,
|
|
137
|
+
coveredLines: fn.coveredLines ?? 0,
|
|
138
|
+
executableLines: fn.executableLines ?? 0,
|
|
139
|
+
})),
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Per-line execution counts for one file, out of the archive rather than the
|
|
144
|
+
* report — the report knows percentages, the archive knows how many times
|
|
145
|
+
* each line ran.
|
|
146
|
+
*/
|
|
147
|
+
export async function readFileLines(path, file) {
|
|
148
|
+
const stdout = await xccov([
|
|
149
|
+
...archiveArgs(path),
|
|
150
|
+
"--file",
|
|
151
|
+
file,
|
|
152
|
+
"--json",
|
|
153
|
+
path,
|
|
154
|
+
]);
|
|
155
|
+
let parsed;
|
|
156
|
+
try {
|
|
157
|
+
parsed = JSON.parse(stdout);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
throw new AxiError("xccov returned output that could not be read", "RESULT_NOT_FOUND");
|
|
161
|
+
}
|
|
162
|
+
return Object.values(parsed)
|
|
163
|
+
.flat()
|
|
164
|
+
.map((line) => ({
|
|
165
|
+
line: line.line ?? 0,
|
|
166
|
+
isExecutable: line.isExecutable === true,
|
|
167
|
+
executionCount: line.executionCount ?? 0,
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
/** Every file the archive holds counts for, which is what `--file` accepts. */
|
|
171
|
+
export async function readArchiveFiles(path) {
|
|
172
|
+
const stdout = await xccov([...archiveArgs(path), "--file-list", path]);
|
|
173
|
+
return stdout
|
|
174
|
+
.split("\n")
|
|
175
|
+
.map((line) => line.trim())
|
|
176
|
+
.filter((line) => line.length > 0);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Two coverage reports measured against each other.
|
|
180
|
+
*
|
|
181
|
+
* `xccov diff` refuses to run without `--json` — its own text form was
|
|
182
|
+
* removed — so there is only one shape to read.
|
|
183
|
+
*/
|
|
184
|
+
export async function readCoverageDiff(before, after) {
|
|
185
|
+
const stdout = await xccov(["diff", "--json", before, after]);
|
|
186
|
+
try {
|
|
187
|
+
return JSON.parse(stdout);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
throw new AxiError("xccov returned a diff that could not be read", "RESULT_NOT_FOUND");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Combine the coverage of several runs into one report and archive.
|
|
195
|
+
*
|
|
196
|
+
* `xccov merge` takes report/archive **pairs**, not result bundles, so each
|
|
197
|
+
* bundle is unpacked with `xcresulttool export coverage` first. That two-step
|
|
198
|
+
* is the whole reason merging coverage across shards is something people give
|
|
199
|
+
* up on.
|
|
200
|
+
*/
|
|
201
|
+
export async function mergeCoverage(paths, outReport, outArchive) {
|
|
202
|
+
const pairs = [];
|
|
203
|
+
for (const path of paths) {
|
|
204
|
+
if (coverageSource(path) !== "bundle") {
|
|
205
|
+
pairs.push(path);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const exported = mkdtempSync(join(tmpdir(), "axi-xccov-"));
|
|
209
|
+
await exportCoverage(path, exported);
|
|
210
|
+
const report = findExported(exported, "CoverageReport");
|
|
211
|
+
const archive = findExported(exported, "CoverageArchive");
|
|
212
|
+
if (!report || !archive) {
|
|
213
|
+
throw new AxiError(`No coverage to merge in ${path}`, "RESULT_NOT_FOUND", ["Re-run those tests with `xcodebuild-axi test --coverage`"]);
|
|
214
|
+
}
|
|
215
|
+
pairs.push(report, archive);
|
|
216
|
+
}
|
|
217
|
+
await xccov([
|
|
218
|
+
"merge",
|
|
219
|
+
"--outReport",
|
|
220
|
+
outReport,
|
|
221
|
+
"--outArchive",
|
|
222
|
+
outArchive,
|
|
223
|
+
...pairs,
|
|
224
|
+
]);
|
|
225
|
+
}
|
|
226
|
+
function findExported(dir, suffix) {
|
|
227
|
+
const match = readdirSync(dir).find((entry) => entry.endsWith(suffix));
|
|
228
|
+
return match ? join(dir, match) : undefined;
|
|
229
|
+
}
|
|
230
|
+
function exportCoverage(path, outputPath) {
|
|
231
|
+
if (!existsSync(path)) {
|
|
232
|
+
throw new AxiError(`No result bundle at ${path}`, "RESULT_NOT_FOUND", [
|
|
233
|
+
"Run `xcodebuild-axi test --coverage` first — it prints the bundle path it wrote",
|
|
234
|
+
]);
|
|
235
|
+
}
|
|
236
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
237
|
+
execFile("xcrun", [
|
|
238
|
+
"xcresulttool",
|
|
239
|
+
"export",
|
|
240
|
+
"coverage",
|
|
241
|
+
"--path",
|
|
242
|
+
path,
|
|
243
|
+
"--output-path",
|
|
244
|
+
outputPath,
|
|
245
|
+
], { maxBuffer: MAX_BUFFER_BYTES, encoding: "utf-8" }, (error, _stdout, stderr) => {
|
|
246
|
+
if (error) {
|
|
247
|
+
rejectPromise(new AxiError(firstLine(stderr) || `Could not read coverage out of ${path}`, "RESULT_NOT_FOUND", ["Re-run those tests with `xcodebuild-axi test --coverage`"]));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
resolvePromise();
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
78
254
|
//# sourceMappingURL=xccov.js.map
|
package/dist/src/xccov.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xccov.js","sourceRoot":"","sources":["../../src/xccov.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;;;GAMG;AAEH,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AA4C1C,SAAS,KAAK,CAAC,IAAc;IAC3B,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,EAAE;QACnD,QAAQ,CACN,OAAO,EACP,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAClB,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,EAClD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxC,4DAA4D;gBAC5D,kDAAkD;gBAClD,IAAI,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBACrC,aAAa,CACX,IAAI,QAAQ,CACV,6CAA6C,EAC7C,kBAAkB,EAClB,CAAC,wDAAwD,CAAC,CAC3D,CACF,CAAC;oBACF,OAAO;gBACT,CAAC;gBACD,aAAa,CACX,IAAI,QAAQ,CACV,SAAS,CAAC,MAAM,CAAC,IAAI,cAAc,EACnC,kBAAkB,CACnB,CACF,CAAC;gBACF,OAAO;YACT,CAAC;YACD,cAAc,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAkB,EAClB,UAA+B,EAAE;IAEjC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"xccov.js","sourceRoot":"","sources":["../../src/xccov.ts"],"names":[],"mappings":"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"}
|
package/dist/src/xcodebuild.d.ts
CHANGED
|
@@ -54,6 +54,24 @@ export declare function globalArtifactDir(): string;
|
|
|
54
54
|
* into the name so two checkouts of the same repo do not collide.
|
|
55
55
|
*/
|
|
56
56
|
export declare function artifactDir(project: ProjectContext): string;
|
|
57
|
+
/**
|
|
58
|
+
* Where something exported out of a result bundle lands.
|
|
59
|
+
*
|
|
60
|
+
* Keyed on the bundle rather than on the project, because `result` takes an
|
|
61
|
+
* arbitrary path and may be pointed at a bundle from anywhere — including a
|
|
62
|
+
* CI artifact in a checked-out repository, which is exactly the tree that must
|
|
63
|
+
* not be dirtied by asking what is in it.
|
|
64
|
+
*/
|
|
65
|
+
export declare function exportDir(bundlePath: string, kind: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Where a merged bundle lands when the caller did not say.
|
|
68
|
+
*
|
|
69
|
+
* Hashed over every input rather than just the first, so merging a different
|
|
70
|
+
* set of shards does not quietly overwrite the last merge of a different set.
|
|
71
|
+
*/
|
|
72
|
+
export declare function mergedBundlePath(paths: string[]): string;
|
|
73
|
+
/** Where a merged coverage report and archive land when nobody said. */
|
|
74
|
+
export declare function mergedCoveragePath(paths: string[]): string;
|
|
57
75
|
/**
|
|
58
76
|
* Strip xcodebuild's fixed preamble.
|
|
59
77
|
*
|
package/dist/src/xcodebuild.js
CHANGED
|
@@ -2,7 +2,7 @@ import { execFile, spawn } from "node:child_process";
|
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { createWriteStream, mkdirSync, rmSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
|
-
import { join } from "node:path";
|
|
5
|
+
import { basename, join } from "node:path";
|
|
6
6
|
import { AxiError, xcodeNotInstalledError } from "./errors.js";
|
|
7
7
|
const MAX_METADATA_BYTES = 8 * 1024 * 1024;
|
|
8
8
|
/** Override the wrapped binary. Unset keeps the PATH lookup. */
|
|
@@ -118,6 +118,43 @@ export function artifactDir(project) {
|
|
|
118
118
|
.slice(0, 8);
|
|
119
119
|
return join(homedir(), "Library", "Caches", "xcodebuild-axi", `${project.name}-${hash}`);
|
|
120
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Where something exported out of a result bundle lands.
|
|
123
|
+
*
|
|
124
|
+
* Keyed on the bundle rather than on the project, because `result` takes an
|
|
125
|
+
* arbitrary path and may be pointed at a bundle from anywhere — including a
|
|
126
|
+
* CI artifact in a checked-out repository, which is exactly the tree that must
|
|
127
|
+
* not be dirtied by asking what is in it.
|
|
128
|
+
*/
|
|
129
|
+
export function exportDir(bundlePath, kind) {
|
|
130
|
+
const hash = createHash("sha256")
|
|
131
|
+
.update(bundlePath)
|
|
132
|
+
.digest("hex")
|
|
133
|
+
.slice(0, 8);
|
|
134
|
+
const stem = basename(bundlePath).replace(/\.xcresult$/, "");
|
|
135
|
+
return join(homedir(), "Library", "Caches", "xcodebuild-axi", "exports", `${stem}-${hash}`, kind);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Where a merged bundle lands when the caller did not say.
|
|
139
|
+
*
|
|
140
|
+
* Hashed over every input rather than just the first, so merging a different
|
|
141
|
+
* set of shards does not quietly overwrite the last merge of a different set.
|
|
142
|
+
*/
|
|
143
|
+
export function mergedBundlePath(paths) {
|
|
144
|
+
const hash = createHash("sha256")
|
|
145
|
+
.update(paths.join("\n"))
|
|
146
|
+
.digest("hex")
|
|
147
|
+
.slice(0, 8);
|
|
148
|
+
return join(homedir(), "Library", "Caches", "xcodebuild-axi", "exports", `merged-${hash}`, "merged.xcresult");
|
|
149
|
+
}
|
|
150
|
+
/** Where a merged coverage report and archive land when nobody said. */
|
|
151
|
+
export function mergedCoveragePath(paths) {
|
|
152
|
+
const hash = createHash("sha256")
|
|
153
|
+
.update(paths.join("\n"))
|
|
154
|
+
.digest("hex")
|
|
155
|
+
.slice(0, 8);
|
|
156
|
+
return join(homedir(), "Library", "Caches", "xcodebuild-axi", "exports", `coverage-${hash}`, "merged.xccovreport");
|
|
157
|
+
}
|
|
121
158
|
/**
|
|
122
159
|
* Strip xcodebuild's fixed preamble.
|
|
123
160
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcodebuild.js","sourceRoot":"","sources":["../../src/xcodebuild.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"xcodebuild.js","sourceRoot":"","sources":["../../src/xcodebuild.ts"],"names":[],"mappings":"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"}
|
package/dist/src/xcresult.d.ts
CHANGED
|
@@ -36,7 +36,11 @@ export interface TestSummary {
|
|
|
36
36
|
export interface TestNode {
|
|
37
37
|
nodeType?: string;
|
|
38
38
|
name?: string;
|
|
39
|
+
/** `Target/Suite/testName()`, the identifier `--only` and `--test` take. */
|
|
40
|
+
nodeIdentifier?: string;
|
|
39
41
|
result?: string;
|
|
42
|
+
/** Pre-formatted by xcresulttool, e.g. `0.028s`. */
|
|
43
|
+
duration?: string;
|
|
40
44
|
sourceLocation?: {
|
|
41
45
|
filePath?: string;
|
|
42
46
|
lineNumber?: number;
|
|
@@ -49,6 +53,90 @@ export interface TestDetails {
|
|
|
49
53
|
testResult?: string;
|
|
50
54
|
testRuns?: TestNode[];
|
|
51
55
|
}
|
|
56
|
+
/** `get test-results tests` — the whole tree of what ran. */
|
|
57
|
+
export interface TestTree {
|
|
58
|
+
devices?: TestDevice[];
|
|
59
|
+
testNodes?: TestNode[];
|
|
60
|
+
}
|
|
61
|
+
/** `get test-results activities` — what one test did, step by step. */
|
|
62
|
+
export interface ActivityNode {
|
|
63
|
+
title?: string;
|
|
64
|
+
startTime?: number;
|
|
65
|
+
attachments?: unknown[];
|
|
66
|
+
childActivities?: ActivityNode[];
|
|
67
|
+
}
|
|
68
|
+
export interface TestActivities {
|
|
69
|
+
testIdentifier?: string;
|
|
70
|
+
testName?: string;
|
|
71
|
+
testRuns?: {
|
|
72
|
+
device?: TestDevice;
|
|
73
|
+
activities?: ActivityNode[];
|
|
74
|
+
}[];
|
|
75
|
+
}
|
|
76
|
+
/** `get test-results insights` — Xcode's own diagnosis of a run. */
|
|
77
|
+
export interface TestInsights {
|
|
78
|
+
commonFailureInsights?: Insight[];
|
|
79
|
+
failureDistributionInsights?: Insight[];
|
|
80
|
+
longestTestRunsInsights?: Insight[];
|
|
81
|
+
}
|
|
82
|
+
export interface Insight {
|
|
83
|
+
category?: string;
|
|
84
|
+
impact?: string;
|
|
85
|
+
text?: string;
|
|
86
|
+
testIdentifier?: string;
|
|
87
|
+
testName?: string;
|
|
88
|
+
totalDuration?: number;
|
|
89
|
+
count?: number;
|
|
90
|
+
}
|
|
91
|
+
/** `get test-results metrics` — what a performance test measured. */
|
|
92
|
+
export interface TestMetric {
|
|
93
|
+
testIdentifier?: string;
|
|
94
|
+
testName?: string;
|
|
95
|
+
measurements?: {
|
|
96
|
+
displayName?: string;
|
|
97
|
+
unit?: string;
|
|
98
|
+
average?: number;
|
|
99
|
+
baselineAverage?: number;
|
|
100
|
+
maxPercentRelativeStandardDeviation?: number;
|
|
101
|
+
}[];
|
|
102
|
+
}
|
|
103
|
+
/** `get content-availability` — what is in the bundle at all. */
|
|
104
|
+
export interface ContentAvailability {
|
|
105
|
+
hasCoverage?: boolean;
|
|
106
|
+
hasDiagnostics?: boolean;
|
|
107
|
+
hasTestResults?: boolean;
|
|
108
|
+
logs?: string[];
|
|
109
|
+
}
|
|
110
|
+
/** `get log` — the build or action log, as a tree of timed sections. */
|
|
111
|
+
export interface LogSection {
|
|
112
|
+
title?: string;
|
|
113
|
+
result?: string;
|
|
114
|
+
duration?: number;
|
|
115
|
+
startTime?: number;
|
|
116
|
+
messages?: {
|
|
117
|
+
title?: string;
|
|
118
|
+
shortTitle?: string;
|
|
119
|
+
}[];
|
|
120
|
+
subsections?: LogSection[];
|
|
121
|
+
commandInvocationDetails?: {
|
|
122
|
+
commandDetails?: string;
|
|
123
|
+
exitCode?: number;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** `metadata get` — the bundle's own storage details. */
|
|
127
|
+
export interface BundleMetadata {
|
|
128
|
+
dateCreated?: string;
|
|
129
|
+
directoryImportMode?: string;
|
|
130
|
+
externalLocations?: unknown[];
|
|
131
|
+
storage?: {
|
|
132
|
+
backend?: string;
|
|
133
|
+
compression?: string;
|
|
134
|
+
};
|
|
135
|
+
version?: {
|
|
136
|
+
major?: number;
|
|
137
|
+
minor?: number;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
52
140
|
export interface RawIssue {
|
|
53
141
|
issueType?: string;
|
|
54
142
|
message?: string;
|
|
@@ -102,7 +190,135 @@ export declare function failureLocation(details: TestDetails): {
|
|
|
102
190
|
file: string;
|
|
103
191
|
line: number | "";
|
|
104
192
|
};
|
|
193
|
+
/** Every test the run knows about, as the tree Xcode groups them into. */
|
|
194
|
+
export declare function readTests(path: string): Promise<TestTree>;
|
|
195
|
+
/**
|
|
196
|
+
* What one test actually did, step by step.
|
|
197
|
+
*
|
|
198
|
+
* The summary says a test failed and `test-details` says where; this is the
|
|
199
|
+
* trail of what it had done by then, which is the only thing that explains a
|
|
200
|
+
* UI test that failed three screens into a flow.
|
|
201
|
+
*/
|
|
202
|
+
export declare function readActivities(path: string, testIdentifier: string): Promise<TestActivities>;
|
|
203
|
+
/** Xcode's own diagnosis of a run: what failed together, and what was slow. */
|
|
204
|
+
export declare function readInsights(path: string): Promise<TestInsights>;
|
|
205
|
+
/** What a performance test measured, and what it measured last time. */
|
|
206
|
+
export declare function readMetrics(path: string, testIdentifier?: string): Promise<TestMetric[]>;
|
|
207
|
+
/**
|
|
208
|
+
* What the bundle actually holds.
|
|
209
|
+
*
|
|
210
|
+
* Worth one subprocess because the alternative is finding out by asking for
|
|
211
|
+
* coverage and reading the failure — an error that looks like a broken tool
|
|
212
|
+
* rather than like an answer.
|
|
213
|
+
*/
|
|
214
|
+
export declare function readContentAvailability(path: string): Promise<ContentAvailability>;
|
|
215
|
+
/** The build, action or console log, as the timed tree the bundle stores. */
|
|
216
|
+
export declare function readLog(path: string, type: string): Promise<LogSection>;
|
|
217
|
+
/** The bundle's own metadata — when it was written, and in what format. */
|
|
218
|
+
export declare function readBundleMetadata(path: string): Promise<BundleMetadata>;
|
|
105
219
|
export declare function readBuildResults(path: string): Promise<BuildResults>;
|
|
220
|
+
/** What `xcresulttool compare` answers: one run measured against another. */
|
|
221
|
+
export interface Differential {
|
|
222
|
+
summary?: DifferentialSummary;
|
|
223
|
+
testFailures?: {
|
|
224
|
+
introduced?: TestFailureDelta[];
|
|
225
|
+
resolved?: TestFailureDelta[];
|
|
226
|
+
};
|
|
227
|
+
testsExecuted?: {
|
|
228
|
+
added?: TestReference[];
|
|
229
|
+
removed?: TestReference[];
|
|
230
|
+
};
|
|
231
|
+
buildWarnings?: IssueDelta;
|
|
232
|
+
analyzerIssues?: IssueDelta;
|
|
233
|
+
}
|
|
234
|
+
export interface DifferentialSummary {
|
|
235
|
+
testFailures?: CountDelta;
|
|
236
|
+
buildWarnings?: CountDelta;
|
|
237
|
+
analyzerIssues?: CountDelta;
|
|
238
|
+
testsExecuted?: {
|
|
239
|
+
itemsInBaseline?: number;
|
|
240
|
+
itemsInCurrent?: number;
|
|
241
|
+
added?: number;
|
|
242
|
+
removed?: number;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
export interface CountDelta {
|
|
246
|
+
itemsInBaseline?: number;
|
|
247
|
+
itemsInCurrent?: number;
|
|
248
|
+
introduced?: number;
|
|
249
|
+
resolved?: number;
|
|
250
|
+
}
|
|
251
|
+
export interface TestReference {
|
|
252
|
+
name?: string;
|
|
253
|
+
testIdentifier?: string;
|
|
254
|
+
}
|
|
255
|
+
export interface TestFailureDelta {
|
|
256
|
+
associatedTest?: TestReference;
|
|
257
|
+
failureMessage?: string;
|
|
258
|
+
}
|
|
259
|
+
export interface IssueDelta {
|
|
260
|
+
introduced?: DifferentialIssue[];
|
|
261
|
+
resolved?: DifferentialIssue[];
|
|
262
|
+
}
|
|
263
|
+
export interface DifferentialIssue {
|
|
264
|
+
message?: string;
|
|
265
|
+
producingTarget?: string;
|
|
266
|
+
issueType?: string;
|
|
267
|
+
}
|
|
268
|
+
/** What an `xcresulttool export` can be asked for. */
|
|
269
|
+
export declare const EXPORT_KINDS: readonly ["attachments", "diagnostics", "metrics", "evaluations"];
|
|
270
|
+
export type ExportKind = (typeof EXPORT_KINDS)[number];
|
|
271
|
+
export interface ExportRequest {
|
|
272
|
+
path: string;
|
|
273
|
+
kind: ExportKind;
|
|
274
|
+
outputPath: string;
|
|
275
|
+
/** Narrow to one test case or suite. Not accepted by `diagnostics`. */
|
|
276
|
+
testId?: string;
|
|
277
|
+
/** Glob against the attachment filename. `attachments` only. */
|
|
278
|
+
filter?: string;
|
|
279
|
+
/** Only what a failure produced. `attachments` and `evaluations` only. */
|
|
280
|
+
onlyFailures?: boolean;
|
|
281
|
+
}
|
|
282
|
+
/** One test's row in an exported `manifest.json`. */
|
|
283
|
+
export interface ExportedAttachment {
|
|
284
|
+
exportedFileName?: string;
|
|
285
|
+
suggestedHumanReadableName?: string;
|
|
286
|
+
isAssociatedWithFailure?: boolean;
|
|
287
|
+
}
|
|
288
|
+
export interface AttachmentManifestEntry {
|
|
289
|
+
testIdentifier?: string;
|
|
290
|
+
attachments?: ExportedAttachment[];
|
|
291
|
+
}
|
|
292
|
+
export interface MetricsManifestEntry {
|
|
293
|
+
testIdentifier?: string;
|
|
294
|
+
metricsFiles?: string[];
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Write part of a bundle out to a directory.
|
|
298
|
+
*
|
|
299
|
+
* Unlike every other read here this one produces files rather than JSON, and
|
|
300
|
+
* it narrates: exporting attachments from a 40-test run prints "Skipped export
|
|
301
|
+
* for <test>: no matching attachments" once per test, which is the answer
|
|
302
|
+
* nobody asked for repeated forty times. The prose is dropped and the caller
|
|
303
|
+
* reports what actually landed on disk instead.
|
|
304
|
+
*/
|
|
305
|
+
export declare function exportBundle(request: ExportRequest): Promise<void>;
|
|
306
|
+
/**
|
|
307
|
+
* One run measured against another.
|
|
308
|
+
*
|
|
309
|
+
* Not routed through `xcresulttool()` because `compare` takes the bundle as a
|
|
310
|
+
* positional rather than as `--path`, and rejects `--compact` outright. It
|
|
311
|
+
* also answers a bare `null` rather than an error when the two bundles have
|
|
312
|
+
* nothing comparable in them — a build bundle against a test one — which is an
|
|
313
|
+
* answer the caller has to be able to tell apart from a clean comparison.
|
|
314
|
+
*/
|
|
315
|
+
export declare function readComparison(path: string, baselinePath: string): Promise<Differential | null>;
|
|
316
|
+
/**
|
|
317
|
+
* Combine bundles into one, which is how a sharded test run gets a single
|
|
318
|
+
* verdict. Writes a bundle rather than printing one, so the caller reports the
|
|
319
|
+
* path and then reads it back like any other.
|
|
320
|
+
*/
|
|
321
|
+
export declare function mergeBundles(paths: string[], outputPath: string): Promise<void>;
|
|
106
322
|
/**
|
|
107
323
|
* Pull `file`, `line` and `col` out of a diagnostic's sourceURL.
|
|
108
324
|
*
|