@empiricalrun/playwright-utils 0.9.3 → 0.11.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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @empiricalrun/playwright-utils
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ae142a5: feat: queue uploads in reporter
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [ae142a5]
12
+ - @empiricalrun/r2-uploader@0.1.3
13
+
14
+ ## 0.10.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 9d5ef6d: fix: revert to using html and json reporters
19
+
20
+ ### Patch Changes
21
+
22
+ - 7a51a93: fix: upload individual attachments per test and add logs
23
+ - 539d304: fix: undo revert from main
24
+ - Updated dependencies [7a51a93]
25
+ - @empiricalrun/r2-uploader@0.1.2
26
+
3
27
  ## 0.9.3
4
28
 
5
29
  ### Patch Changes
@@ -40,6 +40,11 @@ declare class HtmlReporter implements ReporterV2 {
40
40
  private _port;
41
41
  private _host;
42
42
  private _testCount;
43
+ private uploadExecutionQueue;
44
+ private uploadWaitingQueue;
45
+ private uploadMaxQueueSize;
46
+ private processQueue;
47
+ private waitForAllTasksToFinish;
43
48
  private _buildResult;
44
49
  private _topLevelErrors;
45
50
  constructor(options: HtmlReporterOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../src/reporter/custom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EAEV,KAAK,EACL,QAAQ,IAAI,cAAc,EAC1B,SAAS,EACT,UAAU,IAAI,gBAAgB,EAE/B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAML,UAAU,EAMX,MAAM,2BAA2B,CAAC;AAgBnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAiC/C,QAAA,MAAM,iBAAiB,UAAoC,CAAC;AAC5D,KAAK,oBAAoB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAM/D,KAAK,mBAAmB,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,cAAM,YAAa,YAAW,UAAU;IACtC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,mBAAmB,CAAU;IACrC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;IAE/B,OAAO,CAAC,YAAY,CAEN;IACd,OAAO,CAAC,eAAe,CAAmB;gBAE9B,OAAO,EAAE,mBAAmB;IAIxC,aAAa;IAIb,QAAQ;IAER,QAAQ;IAER,WAAW;IAEX,SAAS;IAET,OAAO,IAAI,IAAI;IAIf,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAQvC,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB;IAsCxD,WAAW,CAAC,MAAM,EAAE,UAAU;IAI9B,OAAO,CAAC,KAAK,EAAE,KAAK;IAYpB,eAAe,IAAI;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,oBAAoB,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;KAC1B;IAsBD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IASxD,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAIzB,KAAK,CAAC,MAAM,EAAE,UAAU;IAoFxB,MAAM;CA8Bb;AAkCD,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,GAAE,MAAoB,EAC1B,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,iBAqBhB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAsBhE;AAqiBD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../src/reporter/custom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EAEV,KAAK,EACL,QAAQ,IAAI,cAAc,EAC1B,SAAS,EACT,UAAU,IAAI,gBAAgB,EAE/B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAML,UAAU,EAMX,MAAM,2BAA2B,CAAC;AAgBnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAiC/C,QAAA,MAAM,iBAAiB,UAAoC,CAAC;AAC5D,KAAK,oBAAoB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAM/D,KAAK,mBAAmB,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,cAAM,YAAa,YAAW,UAAU;IACtC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,mBAAmB,CAAU;IACrC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,oBAAoB,CAAiC;IAC7D,OAAO,CAAC,kBAAkB,CAAkC;IAC5D,OAAO,CAAC,kBAAkB,CAAK;IAE/B,OAAO,CAAC,YAAY;YA8BN,uBAAuB;IAQrC,OAAO,CAAC,YAAY,CAEN;IACd,OAAO,CAAC,eAAe,CAAmB;gBAE9B,OAAO,EAAE,mBAAmB;IAIxC,aAAa;IAIb,QAAQ;IAER,QAAQ;IAER,WAAW;IAEX,SAAS;IAET,OAAO,IAAI,IAAI;IAIf,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAQvC,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB;IAyDxD,WAAW,CAAC,MAAM,EAAE,UAAU;IAI9B,OAAO,CAAC,KAAK,EAAE,KAAK;IAYpB,eAAe,IAAI;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,oBAAoB,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;KAC1B;IAsBD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IASxD,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAIzB,KAAK,CAAC,MAAM,EAAE,UAAU;IA8FxB,MAAM;CA8Bb;AAkCD,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,GAAE,MAAoB,EAC1B,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,iBAqBhB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAsBhE;AAqiBD,eAAe,YAAY,CAAC"}
@@ -47,6 +47,42 @@ class HtmlReporter {
47
47
  _port;
48
48
  _host;
49
49
  _testCount = 1;
50
+ uploadExecutionQueue = [];
51
+ uploadWaitingQueue = [];
52
+ uploadMaxQueueSize = 2;
53
+ processQueue() {
54
+ try {
55
+ // console.log("Execution queue length: ", this.uploadExecutionQueue.length);
56
+ // console.log("Waiting queue length: ", this.uploadWaitingQueue.length);
57
+ while (this.uploadExecutionQueue.length < this.uploadMaxQueueSize &&
58
+ this.uploadWaitingQueue.length > 0) {
59
+ const task = this.uploadWaitingQueue.shift();
60
+ if (task) {
61
+ const promise = task()
62
+ .catch((e) => {
63
+ // this.retryTask(task); // Handle retries ?
64
+ console.log("Upload failed ", e);
65
+ })
66
+ .finally(() => {
67
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
68
+ this.uploadExecutionQueue = this.uploadExecutionQueue.filter((p) => p !== promise);
69
+ this.processQueue();
70
+ });
71
+ this.uploadExecutionQueue.push(promise);
72
+ }
73
+ }
74
+ }
75
+ catch (e) {
76
+ console.error("Error while processing queue", e);
77
+ }
78
+ }
79
+ async waitForAllTasksToFinish() {
80
+ return Promise.allSettled(this.uploadExecutionQueue).then(async () => {
81
+ if (this.uploadExecutionQueue.length > 0) {
82
+ await this.waitForAllTasksToFinish();
83
+ }
84
+ });
85
+ }
50
86
  _buildResult;
51
87
  _topLevelErrors = [];
52
88
  constructor(options) {
@@ -68,8 +104,6 @@ class HtmlReporter {
68
104
  this._testCount += 1;
69
105
  }
70
106
  onTestEnd(test, result) {
71
- // upload folder to R2
72
- // iterate over attachments
73
107
  try {
74
108
  result.attachments.forEach(async (attachment) => {
75
109
  if (!attachment.path)
@@ -82,7 +116,8 @@ class HtmlReporter {
82
116
  return;
83
117
  }
84
118
  try {
85
- await (0, r2_uploader_1.uploadDirectory)({
119
+ const uploadTask = async () => (0, r2_uploader_1.uploadDirectory)({
120
+ fileList: [attachment.path],
86
121
  sourceDir: this._outputFolder + "/data/" + folderName,
87
122
  destinationDir: process.env.PROJECT_NAME +
88
123
  "/" +
@@ -91,8 +126,26 @@ class HtmlReporter {
91
126
  folderName,
92
127
  uploadBucket: "test-report",
93
128
  });
129
+ if (this.uploadExecutionQueue.length < this.uploadMaxQueueSize) {
130
+ const promise = uploadTask()
131
+ .catch((e) => {
132
+ console.error("R2 upload failed for", attachment.path, e);
133
+ // this.retryTask(uploadTask); // Retry logic
134
+ })
135
+ .finally(() => {
136
+ console.log("Upload finished for ", attachment.path);
137
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
138
+ this.uploadExecutionQueue = this.uploadExecutionQueue.filter((p) => p !== promise);
139
+ this.processQueue(); // Keep processing queue
140
+ });
141
+ this.uploadExecutionQueue.push(promise);
142
+ }
143
+ else {
144
+ this.uploadWaitingQueue.push(uploadTask);
145
+ }
94
146
  }
95
147
  catch (e) {
148
+ console.log("Error while uploading attachment", e);
96
149
  // tests shouldn't stop no matter whatever error we get
97
150
  }
98
151
  });
@@ -156,34 +209,38 @@ class HtmlReporter {
156
209
  second: "2-digit",
157
210
  }).format(startTime));
158
211
  try {
159
- await Promise.allSettled([
160
- (0, r2_uploader_1.uploadDirectory)({
161
- sourceDir: this._outputFolder + "/trace",
162
- destinationDir: process.env.PROJECT_NAME +
163
- "/" +
164
- process.env.TEST_RUN_GITHUB_ACTION_ID +
165
- "/trace",
166
- uploadBucket: "test-report",
167
- }),
168
- // upload index.html
169
- (0, r2_uploader_1.uploadDirectory)({
170
- sourceDir: this._outputFolder,
171
- fileList: [path_1.default.join(this._outputFolder, "index.html")],
172
- destinationDir: process.env.PROJECT_NAME +
173
- "/" +
174
- process.env.TEST_RUN_GITHUB_ACTION_ID,
175
- uploadBucket: "test-report",
176
- }),
177
- // upload summary.json
178
- (0, r2_uploader_1.uploadDirectory)({
179
- sourceDir: this._outputFolder,
180
- fileList: [path_1.default.join(this._outputFolder, "summary.json")],
181
- destinationDir: process.env.PROJECT_NAME +
182
- "/" +
183
- process.env.TEST_RUN_GITHUB_ACTION_ID,
184
- uploadBucket: "test-report",
185
- }),
186
- ]);
212
+ // await Promise.allSettled([
213
+ const uploadTraceTask = async () => (0, r2_uploader_1.uploadDirectory)({
214
+ sourceDir: this._outputFolder + "/trace",
215
+ destinationDir: process.env.PROJECT_NAME +
216
+ "/" +
217
+ process.env.TEST_RUN_GITHUB_ACTION_ID +
218
+ "/trace",
219
+ uploadBucket: "test-report",
220
+ });
221
+ // upload index.html
222
+ const uploadIndexTask = async () => (0, r2_uploader_1.uploadDirectory)({
223
+ sourceDir: this._outputFolder,
224
+ fileList: [path_1.default.join(this._outputFolder, "index.html")],
225
+ destinationDir: process.env.PROJECT_NAME +
226
+ "/" +
227
+ process.env.TEST_RUN_GITHUB_ACTION_ID,
228
+ uploadBucket: "test-report",
229
+ });
230
+ // upload summary.json
231
+ const uploadSummaryTask = async () => (0, r2_uploader_1.uploadDirectory)({
232
+ sourceDir: this._outputFolder,
233
+ fileList: [path_1.default.join(this._outputFolder, "summary.json")],
234
+ destinationDir: process.env.PROJECT_NAME +
235
+ "/" +
236
+ process.env.TEST_RUN_GITHUB_ACTION_ID,
237
+ uploadBucket: "test-report",
238
+ });
239
+ this.uploadWaitingQueue.push(uploadTraceTask);
240
+ this.uploadWaitingQueue.push(uploadIndexTask);
241
+ this.uploadWaitingQueue.push(uploadSummaryTask);
242
+ // await Promise.allSettled(this.uploadExecutionQueue);
243
+ await this.waitForAllTasksToFinish();
187
244
  const endTime = new Date().getTime();
188
245
  console.log("Finished final report upload at: ", new Intl.DateTimeFormat("en-US", {
189
246
  hour: "2-digit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/playwright-utils",
3
- "version": "0.9.3",
3
+ "version": "0.11.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -37,7 +37,7 @@
37
37
  "mime": "3.0.0",
38
38
  "playwright-core": "^1.46.1",
39
39
  "@empiricalrun/llm": "^0.9.1",
40
- "@empiricalrun/r2-uploader": "^0.1.1"
40
+ "@empiricalrun/r2-uploader": "^0.1.3"
41
41
  },
42
42
  "scripts": {
43
43
  "dev": "tsc --build --watch",