@flakiness/sdk 2.2.2 → 2.4.0
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/README.md +3 -1
- package/lib/browser.js +4 -150
- package/lib/index.js +117 -163
- package/package.json +11 -5
- package/types/src/index.d.ts +1 -0
- package/types/src/index.d.ts.map +1 -1
- package/types/src/showReportCommand.d.ts +19 -0
- package/types/src/showReportCommand.d.ts.map +1 -0
- package/types/src/stripAnsi.d.ts +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@ The Flakiness SDK provides a comprehensive set of tools for creating and managin
|
|
|
10
10
|
npm i @flakiness/sdk @flakiness/flakiness-report
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
Requires Node.js ^20.17.0 or >=22.9.0.
|
|
14
|
+
|
|
13
15
|
## Quick Start
|
|
14
16
|
|
|
15
17
|
Here's a minimal example of creating a Flakiness JSON Report:
|
|
@@ -96,6 +98,7 @@ Use this entry point when you need to process or manipulate reports in browser-b
|
|
|
96
98
|
### Working with Reports
|
|
97
99
|
- **`readReport()`** - Read a Flakiness report and its attachments from disk
|
|
98
100
|
- **`showReport()`** - Start a local server and open the report in your browser
|
|
101
|
+
- **`showReportCommand()`** - Build a shell command for opening the report later with the Flakiness CLI
|
|
99
102
|
- **`uploadReport()`** - Upload reports and attachments to Flakiness.io
|
|
100
103
|
- **`writeReport()`** - Write reports to disk in the standard Flakiness report format
|
|
101
104
|
|
|
@@ -125,4 +128,3 @@ Use this entry point when you need to process or manipulate reports in browser-b
|
|
|
125
128
|
```
|
|
126
129
|
|
|
127
130
|
If neither method is available, the upload is skipped with a `'skipped'` status.
|
|
128
|
-
|
package/lib/browser.js
CHANGED
|
@@ -13,155 +13,8 @@ __export(reportUtilsBrowser_exports, {
|
|
|
13
13
|
visitTests: () => visitTests
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
// node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/flakinessReport.js
|
|
17
|
-
var FlakinessReport;
|
|
18
|
-
((FlakinessReport22) => {
|
|
19
|
-
FlakinessReport22.CATEGORY_PLAYWRIGHT = "playwright";
|
|
20
|
-
FlakinessReport22.CATEGORY_PYTEST = "pytest";
|
|
21
|
-
FlakinessReport22.CATEGORY_JUNIT = "junit";
|
|
22
|
-
FlakinessReport22.STREAM_STDOUT = 1;
|
|
23
|
-
FlakinessReport22.STREAM_STDERR = 2;
|
|
24
|
-
})(FlakinessReport || (FlakinessReport = {}));
|
|
25
|
-
|
|
26
|
-
// node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/schema.js
|
|
27
|
-
import z from "zod/v4";
|
|
28
|
-
var Schema;
|
|
29
|
-
((Schema2) => {
|
|
30
|
-
Schema2.CommitId = z.string().min(40).max(40);
|
|
31
|
-
Schema2.AttachmentId = z.string().min(1).max(1024);
|
|
32
|
-
Schema2.UnixTimestampMS = z.number().min(0);
|
|
33
|
-
Schema2.DurationMS = z.number().min(0);
|
|
34
|
-
Schema2.Number1Based = z.number();
|
|
35
|
-
Schema2.GitFilePath = z.string().min(0);
|
|
36
|
-
Schema2.Location = z.object({
|
|
37
|
-
file: Schema2.GitFilePath,
|
|
38
|
-
line: Schema2.Number1Based,
|
|
39
|
-
// Note: Locations for file suites are (0, 0).
|
|
40
|
-
column: Schema2.Number1Based
|
|
41
|
-
});
|
|
42
|
-
Schema2.TestStatus = z.enum(["passed", "failed", "timedOut", "skipped", "interrupted"]);
|
|
43
|
-
Schema2.Environment = z.object({
|
|
44
|
-
name: z.string().min(1).max(512),
|
|
45
|
-
systemData: z.object({
|
|
46
|
-
osName: z.string().optional(),
|
|
47
|
-
osVersion: z.string().optional(),
|
|
48
|
-
osArch: z.string().optional()
|
|
49
|
-
}).optional(),
|
|
50
|
-
metadata: z.any().optional(),
|
|
51
|
-
userSuppliedData: z.any().optional()
|
|
52
|
-
});
|
|
53
|
-
Schema2.STDIOEntry = z.union([
|
|
54
|
-
z.object({ text: z.string() }),
|
|
55
|
-
z.object({ buffer: z.string() })
|
|
56
|
-
]);
|
|
57
|
-
Schema2.STREAM_STDOUT = z.literal(FlakinessReport.STREAM_STDOUT);
|
|
58
|
-
Schema2.STREAM_STDERR = z.literal(FlakinessReport.STREAM_STDERR);
|
|
59
|
-
Schema2.TimedSTDIOEntry = z.object({
|
|
60
|
-
stream: z.union([Schema2.STREAM_STDOUT, Schema2.STREAM_STDERR]).optional(),
|
|
61
|
-
dts: Schema2.DurationMS
|
|
62
|
-
}).and(z.union([
|
|
63
|
-
z.object({ text: z.string() }),
|
|
64
|
-
z.object({ buffer: z.string() })
|
|
65
|
-
]));
|
|
66
|
-
Schema2.ReportError = z.object({
|
|
67
|
-
location: Schema2.Location.optional(),
|
|
68
|
-
message: z.string().optional(),
|
|
69
|
-
stack: z.string().optional(),
|
|
70
|
-
snippet: z.string().optional(),
|
|
71
|
-
value: z.string().optional()
|
|
72
|
-
});
|
|
73
|
-
Schema2.SuiteType = z.enum(["file", "anonymous suite", "suite"]);
|
|
74
|
-
Schema2.TestStep = z.object({
|
|
75
|
-
title: z.string(),
|
|
76
|
-
duration: Schema2.DurationMS.optional(),
|
|
77
|
-
location: Schema2.Location.optional(),
|
|
78
|
-
snippet: z.string().optional(),
|
|
79
|
-
error: Schema2.ReportError.optional(),
|
|
80
|
-
get steps() {
|
|
81
|
-
return z.array(Schema2.TestStep).optional();
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
Schema2.Attachment = z.object({
|
|
85
|
-
name: z.string(),
|
|
86
|
-
contentType: z.string(),
|
|
87
|
-
id: Schema2.AttachmentId
|
|
88
|
-
});
|
|
89
|
-
Schema2.Annotation = z.object({
|
|
90
|
-
type: z.string(),
|
|
91
|
-
description: z.string().optional(),
|
|
92
|
-
location: Schema2.Location.optional()
|
|
93
|
-
});
|
|
94
|
-
Schema2.RunAttempt = z.object({
|
|
95
|
-
// Index of the environment in the environments array (must be >= 0).
|
|
96
|
-
environmentIdx: z.number().min(0).optional(),
|
|
97
|
-
expectedStatus: Schema2.TestStatus.optional(),
|
|
98
|
-
status: Schema2.TestStatus.optional(),
|
|
99
|
-
startTimestamp: Schema2.UnixTimestampMS,
|
|
100
|
-
duration: Schema2.DurationMS.optional(),
|
|
101
|
-
timeout: Schema2.DurationMS.optional(),
|
|
102
|
-
annotations: z.array(Schema2.Annotation).optional(),
|
|
103
|
-
errors: z.array(Schema2.ReportError).optional(),
|
|
104
|
-
parallelIndex: z.number().optional(),
|
|
105
|
-
steps: z.array(Schema2.TestStep).optional(),
|
|
106
|
-
stdio: z.array(Schema2.TimedSTDIOEntry).optional(),
|
|
107
|
-
stdout: z.array(Schema2.STDIOEntry).optional(),
|
|
108
|
-
stderr: z.array(Schema2.STDIOEntry).optional(),
|
|
109
|
-
attachments: z.array(Schema2.Attachment).optional()
|
|
110
|
-
});
|
|
111
|
-
Schema2.Suite = z.object({
|
|
112
|
-
type: Schema2.SuiteType,
|
|
113
|
-
title: z.string(),
|
|
114
|
-
location: Schema2.Location.optional(),
|
|
115
|
-
get suites() {
|
|
116
|
-
return z.array(Schema2.Suite).optional();
|
|
117
|
-
},
|
|
118
|
-
get tests() {
|
|
119
|
-
return z.array(Schema2.Test).optional();
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
Schema2.Test = z.object({
|
|
123
|
-
title: z.string(),
|
|
124
|
-
location: Schema2.Location.optional(),
|
|
125
|
-
tags: z.array(z.string()).optional(),
|
|
126
|
-
attempts: z.array(Schema2.RunAttempt)
|
|
127
|
-
});
|
|
128
|
-
Schema2.SystemUtilizationSample = z.object({
|
|
129
|
-
dts: Schema2.DurationMS,
|
|
130
|
-
// Must be between 0 and 100 (inclusive). Can be a rational number.
|
|
131
|
-
cpuUtilization: z.number().min(0).max(100),
|
|
132
|
-
// Must be between 0 and 100 (inclusive). Can be a rational number.
|
|
133
|
-
memoryUtilization: z.number().min(0).max(100)
|
|
134
|
-
});
|
|
135
|
-
Schema2.SystemUtilization = z.object({
|
|
136
|
-
totalMemoryBytes: z.number().min(0),
|
|
137
|
-
startTimestamp: Schema2.UnixTimestampMS,
|
|
138
|
-
samples: z.array(Schema2.SystemUtilizationSample)
|
|
139
|
-
});
|
|
140
|
-
Schema2.UtilizationTelemetry = z.tuple([Schema2.DurationMS, z.number().min(0).max(100)]);
|
|
141
|
-
Schema2.FlakinessProject = z.string();
|
|
142
|
-
Schema2.Report = z.object({
|
|
143
|
-
flakinessProject: Schema2.FlakinessProject.optional(),
|
|
144
|
-
category: z.string().min(1).max(100),
|
|
145
|
-
commitId: Schema2.CommitId,
|
|
146
|
-
relatedCommitIds: z.array(Schema2.CommitId).optional(),
|
|
147
|
-
configPath: Schema2.GitFilePath.optional(),
|
|
148
|
-
url: z.string().optional(),
|
|
149
|
-
environments: z.array(Schema2.Environment).min(1),
|
|
150
|
-
suites: z.array(Schema2.Suite).optional(),
|
|
151
|
-
tests: z.array(Schema2.Test).optional(),
|
|
152
|
-
unattributedErrors: z.array(Schema2.ReportError).optional(),
|
|
153
|
-
startTimestamp: Schema2.UnixTimestampMS,
|
|
154
|
-
duration: Schema2.DurationMS,
|
|
155
|
-
systemUtilization: z.optional(Schema2.SystemUtilization),
|
|
156
|
-
cpuCount: z.number().min(0).optional(),
|
|
157
|
-
cpuAvg: z.array(Schema2.UtilizationTelemetry).optional(),
|
|
158
|
-
cpuMax: z.array(Schema2.UtilizationTelemetry).optional(),
|
|
159
|
-
ram: z.array(Schema2.UtilizationTelemetry).optional(),
|
|
160
|
-
ramBytes: z.number().min(0).optional()
|
|
161
|
-
});
|
|
162
|
-
})(Schema || (Schema = {}));
|
|
163
|
-
|
|
164
16
|
// src/normalizeReport.ts
|
|
17
|
+
import { FlakinessReport } from "@flakiness/flakiness-report";
|
|
165
18
|
import stableObjectHash from "stable-hash";
|
|
166
19
|
var Multimap = class {
|
|
167
20
|
_map = /* @__PURE__ */ new Map();
|
|
@@ -320,7 +173,8 @@ function computeTestId(test, suiteId) {
|
|
|
320
173
|
}
|
|
321
174
|
|
|
322
175
|
// src/validateReport.ts
|
|
323
|
-
import
|
|
176
|
+
import { Schema } from "@flakiness/flakiness-report";
|
|
177
|
+
import z from "zod/v4";
|
|
324
178
|
function validateReport(report) {
|
|
325
179
|
const validation = Schema.Report.safeParse(report);
|
|
326
180
|
if (!validation.success) {
|
|
@@ -328,7 +182,7 @@ function validateReport(report) {
|
|
|
328
182
|
const allIssues = validation.error.issues;
|
|
329
183
|
const shownIssues = allIssues.slice(0, MAX_ISSUES);
|
|
330
184
|
const remaining = allIssues.length - shownIssues.length;
|
|
331
|
-
const base = [
|
|
185
|
+
const base = [z.prettifyError(new z.ZodError(shownIssues))];
|
|
332
186
|
if (remaining > 0)
|
|
333
187
|
base.push(`... and ${remaining} more issue${remaining === 1 ? "" : "s"} ...`);
|
|
334
188
|
return base.join("\n");
|
package/lib/index.js
CHANGED
|
@@ -679,155 +679,8 @@ function createEnvironment(options) {
|
|
|
679
679
|
};
|
|
680
680
|
}
|
|
681
681
|
|
|
682
|
-
// node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/flakinessReport.js
|
|
683
|
-
var FlakinessReport;
|
|
684
|
-
((FlakinessReport22) => {
|
|
685
|
-
FlakinessReport22.CATEGORY_PLAYWRIGHT = "playwright";
|
|
686
|
-
FlakinessReport22.CATEGORY_PYTEST = "pytest";
|
|
687
|
-
FlakinessReport22.CATEGORY_JUNIT = "junit";
|
|
688
|
-
FlakinessReport22.STREAM_STDOUT = 1;
|
|
689
|
-
FlakinessReport22.STREAM_STDERR = 2;
|
|
690
|
-
})(FlakinessReport || (FlakinessReport = {}));
|
|
691
|
-
|
|
692
|
-
// node_modules/.pnpm/@flakiness+flakiness-report@0.27.0_zod@4.3.5/node_modules/@flakiness/flakiness-report/lib/schema.js
|
|
693
|
-
import z from "zod/v4";
|
|
694
|
-
var Schema;
|
|
695
|
-
((Schema2) => {
|
|
696
|
-
Schema2.CommitId = z.string().min(40).max(40);
|
|
697
|
-
Schema2.AttachmentId = z.string().min(1).max(1024);
|
|
698
|
-
Schema2.UnixTimestampMS = z.number().min(0);
|
|
699
|
-
Schema2.DurationMS = z.number().min(0);
|
|
700
|
-
Schema2.Number1Based = z.number();
|
|
701
|
-
Schema2.GitFilePath = z.string().min(0);
|
|
702
|
-
Schema2.Location = z.object({
|
|
703
|
-
file: Schema2.GitFilePath,
|
|
704
|
-
line: Schema2.Number1Based,
|
|
705
|
-
// Note: Locations for file suites are (0, 0).
|
|
706
|
-
column: Schema2.Number1Based
|
|
707
|
-
});
|
|
708
|
-
Schema2.TestStatus = z.enum(["passed", "failed", "timedOut", "skipped", "interrupted"]);
|
|
709
|
-
Schema2.Environment = z.object({
|
|
710
|
-
name: z.string().min(1).max(512),
|
|
711
|
-
systemData: z.object({
|
|
712
|
-
osName: z.string().optional(),
|
|
713
|
-
osVersion: z.string().optional(),
|
|
714
|
-
osArch: z.string().optional()
|
|
715
|
-
}).optional(),
|
|
716
|
-
metadata: z.any().optional(),
|
|
717
|
-
userSuppliedData: z.any().optional()
|
|
718
|
-
});
|
|
719
|
-
Schema2.STDIOEntry = z.union([
|
|
720
|
-
z.object({ text: z.string() }),
|
|
721
|
-
z.object({ buffer: z.string() })
|
|
722
|
-
]);
|
|
723
|
-
Schema2.STREAM_STDOUT = z.literal(FlakinessReport.STREAM_STDOUT);
|
|
724
|
-
Schema2.STREAM_STDERR = z.literal(FlakinessReport.STREAM_STDERR);
|
|
725
|
-
Schema2.TimedSTDIOEntry = z.object({
|
|
726
|
-
stream: z.union([Schema2.STREAM_STDOUT, Schema2.STREAM_STDERR]).optional(),
|
|
727
|
-
dts: Schema2.DurationMS
|
|
728
|
-
}).and(z.union([
|
|
729
|
-
z.object({ text: z.string() }),
|
|
730
|
-
z.object({ buffer: z.string() })
|
|
731
|
-
]));
|
|
732
|
-
Schema2.ReportError = z.object({
|
|
733
|
-
location: Schema2.Location.optional(),
|
|
734
|
-
message: z.string().optional(),
|
|
735
|
-
stack: z.string().optional(),
|
|
736
|
-
snippet: z.string().optional(),
|
|
737
|
-
value: z.string().optional()
|
|
738
|
-
});
|
|
739
|
-
Schema2.SuiteType = z.enum(["file", "anonymous suite", "suite"]);
|
|
740
|
-
Schema2.TestStep = z.object({
|
|
741
|
-
title: z.string(),
|
|
742
|
-
duration: Schema2.DurationMS.optional(),
|
|
743
|
-
location: Schema2.Location.optional(),
|
|
744
|
-
snippet: z.string().optional(),
|
|
745
|
-
error: Schema2.ReportError.optional(),
|
|
746
|
-
get steps() {
|
|
747
|
-
return z.array(Schema2.TestStep).optional();
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
Schema2.Attachment = z.object({
|
|
751
|
-
name: z.string(),
|
|
752
|
-
contentType: z.string(),
|
|
753
|
-
id: Schema2.AttachmentId
|
|
754
|
-
});
|
|
755
|
-
Schema2.Annotation = z.object({
|
|
756
|
-
type: z.string(),
|
|
757
|
-
description: z.string().optional(),
|
|
758
|
-
location: Schema2.Location.optional()
|
|
759
|
-
});
|
|
760
|
-
Schema2.RunAttempt = z.object({
|
|
761
|
-
// Index of the environment in the environments array (must be >= 0).
|
|
762
|
-
environmentIdx: z.number().min(0).optional(),
|
|
763
|
-
expectedStatus: Schema2.TestStatus.optional(),
|
|
764
|
-
status: Schema2.TestStatus.optional(),
|
|
765
|
-
startTimestamp: Schema2.UnixTimestampMS,
|
|
766
|
-
duration: Schema2.DurationMS.optional(),
|
|
767
|
-
timeout: Schema2.DurationMS.optional(),
|
|
768
|
-
annotations: z.array(Schema2.Annotation).optional(),
|
|
769
|
-
errors: z.array(Schema2.ReportError).optional(),
|
|
770
|
-
parallelIndex: z.number().optional(),
|
|
771
|
-
steps: z.array(Schema2.TestStep).optional(),
|
|
772
|
-
stdio: z.array(Schema2.TimedSTDIOEntry).optional(),
|
|
773
|
-
stdout: z.array(Schema2.STDIOEntry).optional(),
|
|
774
|
-
stderr: z.array(Schema2.STDIOEntry).optional(),
|
|
775
|
-
attachments: z.array(Schema2.Attachment).optional()
|
|
776
|
-
});
|
|
777
|
-
Schema2.Suite = z.object({
|
|
778
|
-
type: Schema2.SuiteType,
|
|
779
|
-
title: z.string(),
|
|
780
|
-
location: Schema2.Location.optional(),
|
|
781
|
-
get suites() {
|
|
782
|
-
return z.array(Schema2.Suite).optional();
|
|
783
|
-
},
|
|
784
|
-
get tests() {
|
|
785
|
-
return z.array(Schema2.Test).optional();
|
|
786
|
-
}
|
|
787
|
-
});
|
|
788
|
-
Schema2.Test = z.object({
|
|
789
|
-
title: z.string(),
|
|
790
|
-
location: Schema2.Location.optional(),
|
|
791
|
-
tags: z.array(z.string()).optional(),
|
|
792
|
-
attempts: z.array(Schema2.RunAttempt)
|
|
793
|
-
});
|
|
794
|
-
Schema2.SystemUtilizationSample = z.object({
|
|
795
|
-
dts: Schema2.DurationMS,
|
|
796
|
-
// Must be between 0 and 100 (inclusive). Can be a rational number.
|
|
797
|
-
cpuUtilization: z.number().min(0).max(100),
|
|
798
|
-
// Must be between 0 and 100 (inclusive). Can be a rational number.
|
|
799
|
-
memoryUtilization: z.number().min(0).max(100)
|
|
800
|
-
});
|
|
801
|
-
Schema2.SystemUtilization = z.object({
|
|
802
|
-
totalMemoryBytes: z.number().min(0),
|
|
803
|
-
startTimestamp: Schema2.UnixTimestampMS,
|
|
804
|
-
samples: z.array(Schema2.SystemUtilizationSample)
|
|
805
|
-
});
|
|
806
|
-
Schema2.UtilizationTelemetry = z.tuple([Schema2.DurationMS, z.number().min(0).max(100)]);
|
|
807
|
-
Schema2.FlakinessProject = z.string();
|
|
808
|
-
Schema2.Report = z.object({
|
|
809
|
-
flakinessProject: Schema2.FlakinessProject.optional(),
|
|
810
|
-
category: z.string().min(1).max(100),
|
|
811
|
-
commitId: Schema2.CommitId,
|
|
812
|
-
relatedCommitIds: z.array(Schema2.CommitId).optional(),
|
|
813
|
-
configPath: Schema2.GitFilePath.optional(),
|
|
814
|
-
url: z.string().optional(),
|
|
815
|
-
environments: z.array(Schema2.Environment).min(1),
|
|
816
|
-
suites: z.array(Schema2.Suite).optional(),
|
|
817
|
-
tests: z.array(Schema2.Test).optional(),
|
|
818
|
-
unattributedErrors: z.array(Schema2.ReportError).optional(),
|
|
819
|
-
startTimestamp: Schema2.UnixTimestampMS,
|
|
820
|
-
duration: Schema2.DurationMS,
|
|
821
|
-
systemUtilization: z.optional(Schema2.SystemUtilization),
|
|
822
|
-
cpuCount: z.number().min(0).optional(),
|
|
823
|
-
cpuAvg: z.array(Schema2.UtilizationTelemetry).optional(),
|
|
824
|
-
cpuMax: z.array(Schema2.UtilizationTelemetry).optional(),
|
|
825
|
-
ram: z.array(Schema2.UtilizationTelemetry).optional(),
|
|
826
|
-
ramBytes: z.number().min(0).optional()
|
|
827
|
-
});
|
|
828
|
-
})(Schema || (Schema = {}));
|
|
829
|
-
|
|
830
682
|
// src/normalizeReport.ts
|
|
683
|
+
import { FlakinessReport } from "@flakiness/flakiness-report";
|
|
831
684
|
import stableObjectHash from "stable-hash";
|
|
832
685
|
var Multimap = class {
|
|
833
686
|
_map = /* @__PURE__ */ new Map();
|
|
@@ -986,7 +839,8 @@ function computeTestId(test, suiteId) {
|
|
|
986
839
|
}
|
|
987
840
|
|
|
988
841
|
// src/validateReport.ts
|
|
989
|
-
import
|
|
842
|
+
import { Schema } from "@flakiness/flakiness-report";
|
|
843
|
+
import z from "zod/v4";
|
|
990
844
|
function validateReport(report) {
|
|
991
845
|
const validation = Schema.Report.safeParse(report);
|
|
992
846
|
if (!validation.success) {
|
|
@@ -994,7 +848,7 @@ function validateReport(report) {
|
|
|
994
848
|
const allIssues = validation.error.issues;
|
|
995
849
|
const shownIssues = allIssues.slice(0, MAX_ISSUES);
|
|
996
850
|
const remaining = allIssues.length - shownIssues.length;
|
|
997
|
-
const base = [
|
|
851
|
+
const base = [z.prettifyError(new z.ZodError(shownIssues))];
|
|
998
852
|
if (remaining > 0)
|
|
999
853
|
base.push(`... and ${remaining} more issue${remaining === 1 ? "" : "s"} ...`);
|
|
1000
854
|
return base.join("\n");
|
|
@@ -1279,7 +1133,7 @@ async function listFilesRecursively(dir, result = []) {
|
|
|
1279
1133
|
}
|
|
1280
1134
|
|
|
1281
1135
|
// src/showReport.ts
|
|
1282
|
-
import
|
|
1136
|
+
import { styleText } from "node:util";
|
|
1283
1137
|
import open from "open";
|
|
1284
1138
|
|
|
1285
1139
|
// src/staticServer.ts
|
|
@@ -1442,7 +1296,7 @@ async function showReport(reportFolder, options) {
|
|
|
1442
1296
|
const url = new URL(reportViewerUrl);
|
|
1443
1297
|
url.searchParams.set("port", String(server.port()));
|
|
1444
1298
|
url.searchParams.set("token", token);
|
|
1445
|
-
console.log(
|
|
1299
|
+
console.log(styleText("cyan", `
|
|
1446
1300
|
Serving Flakiness report at ${url.toString()}
|
|
1447
1301
|
Press Ctrl+C to quit.`));
|
|
1448
1302
|
await open(url.toString());
|
|
@@ -1450,24 +1304,123 @@ async function showReport(reportFolder, options) {
|
|
|
1450
1304
|
});
|
|
1451
1305
|
}
|
|
1452
1306
|
|
|
1307
|
+
// src/showReportCommand.ts
|
|
1308
|
+
import fs7 from "node:fs";
|
|
1309
|
+
import path3 from "node:path";
|
|
1310
|
+
import which from "which";
|
|
1311
|
+
var DEFAULT_REPORT_FOLDER = "flakiness-report";
|
|
1312
|
+
var FLAKINESS_CLI_COMMANDS = {
|
|
1313
|
+
GLOBAL: "flakiness",
|
|
1314
|
+
PNPM: "pnpm dlx flakiness",
|
|
1315
|
+
NPM: "npx flakiness"
|
|
1316
|
+
};
|
|
1317
|
+
function showReportCommand(reportFolder) {
|
|
1318
|
+
const userCwd = path3.resolve(process.env.INIT_CWD || process.cwd());
|
|
1319
|
+
const flakinessCLI = detectFlakinessCLIFromEnv() ?? detectFlakinessCLIFromFilesystem(userCwd) ?? detectFlakinessCLIFromPath() ?? FLAKINESS_CLI_COMMANDS.NPM;
|
|
1320
|
+
const absoluteReportFolder = path3.resolve(reportFolder);
|
|
1321
|
+
const reportFolderArg = formatReportFolderArg(absoluteReportFolder, userCwd);
|
|
1322
|
+
return `${flakinessCLI} show${reportFolderArg ? ` ${reportFolderArg}` : ""}`;
|
|
1323
|
+
}
|
|
1324
|
+
function detectFlakinessCLIFromEnv() {
|
|
1325
|
+
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
1326
|
+
if (userAgent.startsWith("pnpm/"))
|
|
1327
|
+
return FLAKINESS_CLI_COMMANDS.PNPM;
|
|
1328
|
+
if (userAgent.startsWith("npm/"))
|
|
1329
|
+
return FLAKINESS_CLI_COMMANDS.NPM;
|
|
1330
|
+
const execPath = process.env.npm_execpath ?? "";
|
|
1331
|
+
const execName = execPath ? path3.basename(execPath).toLowerCase() : "";
|
|
1332
|
+
if (execName.startsWith("pnpm"))
|
|
1333
|
+
return FLAKINESS_CLI_COMMANDS.PNPM;
|
|
1334
|
+
return void 0;
|
|
1335
|
+
}
|
|
1336
|
+
function detectFlakinessCLIFromFilesystem(userCwd) {
|
|
1337
|
+
for (const dir of ancestorDirectories(userCwd)) {
|
|
1338
|
+
const packageManager = parsePackageJSON(dir);
|
|
1339
|
+
if (packageManager === "pnpm")
|
|
1340
|
+
return FLAKINESS_CLI_COMMANDS.PNPM;
|
|
1341
|
+
if (packageManager === "npm" || packageManager === "other")
|
|
1342
|
+
return FLAKINESS_CLI_COMMANDS.NPM;
|
|
1343
|
+
if (fs7.existsSync(path3.join(dir, "pnpm-lock.yaml")))
|
|
1344
|
+
return FLAKINESS_CLI_COMMANDS.PNPM;
|
|
1345
|
+
if (fs7.existsSync(path3.join(dir, "pnpm-workspace.yaml")))
|
|
1346
|
+
return FLAKINESS_CLI_COMMANDS.PNPM;
|
|
1347
|
+
}
|
|
1348
|
+
return void 0;
|
|
1349
|
+
}
|
|
1350
|
+
function detectFlakinessCLIFromPath() {
|
|
1351
|
+
if (which.sync("flakiness", { nothrow: true }))
|
|
1352
|
+
return FLAKINESS_CLI_COMMANDS.GLOBAL;
|
|
1353
|
+
if (which.sync("npx", { nothrow: true }))
|
|
1354
|
+
return FLAKINESS_CLI_COMMANDS.NPM;
|
|
1355
|
+
if (which.sync("pnpm", { nothrow: true }))
|
|
1356
|
+
return FLAKINESS_CLI_COMMANDS.PNPM;
|
|
1357
|
+
return void 0;
|
|
1358
|
+
}
|
|
1359
|
+
function parsePackageJSON(dir) {
|
|
1360
|
+
const packageJsonPath = path3.join(dir, "package.json");
|
|
1361
|
+
if (!fs7.existsSync(packageJsonPath))
|
|
1362
|
+
return void 0;
|
|
1363
|
+
try {
|
|
1364
|
+
const packageJson = JSON.parse(fs7.readFileSync(packageJsonPath, "utf8"));
|
|
1365
|
+
if (typeof packageJson.packageManager !== "string")
|
|
1366
|
+
return void 0;
|
|
1367
|
+
if (packageJson.packageManager.startsWith("pnpm@"))
|
|
1368
|
+
return "pnpm";
|
|
1369
|
+
if (packageJson.packageManager.startsWith("npm@"))
|
|
1370
|
+
return "npm";
|
|
1371
|
+
return "other";
|
|
1372
|
+
} catch {
|
|
1373
|
+
return void 0;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
function ancestorDirectories(startDir) {
|
|
1377
|
+
const directories = [];
|
|
1378
|
+
let current = path3.resolve(startDir);
|
|
1379
|
+
while (true) {
|
|
1380
|
+
directories.push(current);
|
|
1381
|
+
const parent = path3.dirname(current);
|
|
1382
|
+
if (parent === current)
|
|
1383
|
+
return directories;
|
|
1384
|
+
current = parent;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
function formatReportFolderArg(reportFolder, userCwd) {
|
|
1388
|
+
if (isSamePath(reportFolder, path3.resolve(userCwd, DEFAULT_REPORT_FOLDER)))
|
|
1389
|
+
return "";
|
|
1390
|
+
const relativePath = path3.relative(userCwd, reportFolder) || ".";
|
|
1391
|
+
return quoteShellArgument(relativePath);
|
|
1392
|
+
}
|
|
1393
|
+
function isSamePath(left, right) {
|
|
1394
|
+
const normalizedLeft = path3.resolve(left);
|
|
1395
|
+
const normalizedRight = path3.resolve(right);
|
|
1396
|
+
if (process.platform === "win32")
|
|
1397
|
+
return normalizedLeft.toLowerCase() === normalizedRight.toLowerCase();
|
|
1398
|
+
return normalizedLeft === normalizedRight;
|
|
1399
|
+
}
|
|
1400
|
+
function quoteShellArgument(argument) {
|
|
1401
|
+
if (/^[A-Za-z0-9_./:@%+=,-]+$/u.test(argument))
|
|
1402
|
+
return argument;
|
|
1403
|
+
return JSON.stringify(argument);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1453
1406
|
// src/writeReport.ts
|
|
1454
|
-
import
|
|
1455
|
-
import
|
|
1407
|
+
import fs8 from "fs";
|
|
1408
|
+
import path4 from "path";
|
|
1456
1409
|
async function writeReport(report, attachments, outputFolder) {
|
|
1457
|
-
const reportPath =
|
|
1458
|
-
const attachmentsFolder =
|
|
1459
|
-
await
|
|
1460
|
-
await
|
|
1461
|
-
await
|
|
1410
|
+
const reportPath = path4.join(outputFolder, "report.json");
|
|
1411
|
+
const attachmentsFolder = path4.join(outputFolder, "attachments");
|
|
1412
|
+
await fs8.promises.rm(outputFolder, { recursive: true, force: true });
|
|
1413
|
+
await fs8.promises.mkdir(outputFolder, { recursive: true });
|
|
1414
|
+
await fs8.promises.writeFile(reportPath, JSON.stringify(report), "utf-8");
|
|
1462
1415
|
if (attachments.length)
|
|
1463
|
-
await
|
|
1416
|
+
await fs8.promises.mkdir(attachmentsFolder);
|
|
1464
1417
|
const movedAttachments = [];
|
|
1465
1418
|
for (const attachment of attachments) {
|
|
1466
|
-
const attachmentPath =
|
|
1419
|
+
const attachmentPath = path4.join(attachmentsFolder, attachment.id);
|
|
1467
1420
|
if (attachment.type === "file")
|
|
1468
|
-
await
|
|
1421
|
+
await fs8.promises.cp(attachment.path, attachmentPath);
|
|
1469
1422
|
else if (attachment.type === "buffer")
|
|
1470
|
-
await
|
|
1423
|
+
await fs8.promises.writeFile(attachmentPath, attachment.body);
|
|
1471
1424
|
movedAttachments.push({
|
|
1472
1425
|
type: "file",
|
|
1473
1426
|
contentType: attachment.contentType,
|
|
@@ -1486,6 +1439,7 @@ export {
|
|
|
1486
1439
|
reportUtils_exports as ReportUtils,
|
|
1487
1440
|
readReport,
|
|
1488
1441
|
showReport,
|
|
1442
|
+
showReportCommand,
|
|
1489
1443
|
uploadReport,
|
|
1490
1444
|
writeReport
|
|
1491
1445
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flakiness/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,12 +24,16 @@
|
|
|
24
24
|
"keywords": [],
|
|
25
25
|
"author": "Degu Labs, Inc",
|
|
26
26
|
"license": "MIT",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": "^20.17.0 || >=22.9.0"
|
|
29
|
+
},
|
|
27
30
|
"devDependencies": {
|
|
28
|
-
"@flakiness/flakiness-report": "^0.
|
|
29
|
-
"@flakiness/playwright": "^1.3.
|
|
31
|
+
"@flakiness/flakiness-report": "^0.28.0",
|
|
32
|
+
"@flakiness/playwright": "^1.3.3",
|
|
30
33
|
"@playwright/test": "^1.58.2",
|
|
31
34
|
"@types/debug": "^4.1.12",
|
|
32
35
|
"@types/node": "^25.0.3",
|
|
36
|
+
"@types/which": "^3.0.4",
|
|
33
37
|
"esbuild": "^0.27.0",
|
|
34
38
|
"kubik": "^0.24.0",
|
|
35
39
|
"tsx": "^4.21.0",
|
|
@@ -39,14 +43,16 @@
|
|
|
39
43
|
"@flakiness/flakiness-report": ">=0.26.0 <1.0.0"
|
|
40
44
|
},
|
|
41
45
|
"dependencies": {
|
|
42
|
-
"chalk": "^5.6.2",
|
|
43
46
|
"debug": "^4.4.3",
|
|
44
47
|
"open": "^10.2.0",
|
|
45
48
|
"stable-hash": "^0.0.6",
|
|
49
|
+
"which": "^6.0.1",
|
|
46
50
|
"zod": "^4.3.5"
|
|
47
51
|
},
|
|
48
52
|
"scripts": {
|
|
49
53
|
"minor": "./version.mjs minor",
|
|
50
|
-
"patch": "./version.mjs patch"
|
|
54
|
+
"patch": "./version.mjs patch",
|
|
55
|
+
"test": "pnpm playwright test",
|
|
56
|
+
"build": "kubik ./build.mts"
|
|
51
57
|
}
|
|
52
58
|
}
|
package/types/src/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { GithubOIDC } from './githubOIDC.js';
|
|
|
6
6
|
export * as ReportUtils from './reportUtils.js';
|
|
7
7
|
export { readReport } from './readReport.js';
|
|
8
8
|
export { showReport } from './showReport.js';
|
|
9
|
+
export { showReportCommand } from './showReportCommand.js';
|
|
9
10
|
export { uploadReport } from './uploadReport.js';
|
|
10
11
|
export { writeReport } from './writeReport.js';
|
|
11
12
|
//# sourceMappingURL=index.d.ts.map
|
package/types/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a command that opens a Flakiness report with the Flakiness CLI.
|
|
3
|
+
*
|
|
4
|
+
* The command is tailored for the shell directory from which the current process
|
|
5
|
+
* was originally invoked. This matters when package managers like pnpm change the
|
|
6
|
+
* working directory while running scripts.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} reportFolder - Absolute or relative path to the report folder.
|
|
9
|
+
*
|
|
10
|
+
* @returns {string} A shell command such as `pnpm dlx flakiness show`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const command = showReportCommand('./flakiness-report');
|
|
15
|
+
* // Returns: "npx flakiness show"
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function showReportCommand(reportFolder: string): string;
|
|
19
|
+
//# sourceMappingURL=showReportCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"showReportCommand.d.ts","sourceRoot":"","sources":["../../src/showReportCommand.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAM9D"}
|
package/types/src/stripAnsi.d.ts
CHANGED