@empiricalrun/playwright-utils 0.10.0 → 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,16 @@
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
+
3
14
  ## 0.10.0
4
15
 
5
16
  ### Minor Changes
@@ -40,7 +40,11 @@ declare class HtmlReporter implements ReporterV2 {
40
40
  private _port;
41
41
  private _host;
42
42
  private _testCount;
43
- private pendingUploads;
43
+ private uploadExecutionQueue;
44
+ private uploadWaitingQueue;
45
+ private uploadMaxQueueSize;
46
+ private processQueue;
47
+ private waitForAllTasksToFinish;
44
48
  private _buildResult;
45
49
  private _topLevelErrors;
46
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;IAC/B,OAAO,CAAC,cAAc,CAAsB;IAE5C,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;IAyCxD,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;IAqFxB,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,7 +47,42 @@ class HtmlReporter {
47
47
  _port;
48
48
  _host;
49
49
  _testCount = 1;
50
- pendingUploads = [];
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
+ }
51
86
  _buildResult;
52
87
  _topLevelErrors = [];
53
88
  constructor(options) {
@@ -69,8 +104,6 @@ class HtmlReporter {
69
104
  this._testCount += 1;
70
105
  }
71
106
  onTestEnd(test, result) {
72
- // upload folder to R2
73
- // iterate over attachments
74
107
  try {
75
108
  result.attachments.forEach(async (attachment) => {
76
109
  if (!attachment.path)
@@ -83,8 +116,7 @@ class HtmlReporter {
83
116
  return;
84
117
  }
85
118
  try {
86
- const res = (0, r2_uploader_1.uploadDirectory)({
87
- // upload the exact file individually
119
+ const uploadTask = async () => (0, r2_uploader_1.uploadDirectory)({
88
120
  fileList: [attachment.path],
89
121
  sourceDir: this._outputFolder + "/data/" + folderName,
90
122
  destinationDir: process.env.PROJECT_NAME +
@@ -94,9 +126,26 @@ class HtmlReporter {
94
126
  folderName,
95
127
  uploadBucket: "test-report",
96
128
  });
97
- this.pendingUploads.push(res);
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
+ }
98
146
  }
99
147
  catch (e) {
148
+ console.log("Error while uploading attachment", e);
100
149
  // tests shouldn't stop no matter whatever error we get
101
150
  }
102
151
  });
@@ -160,35 +209,38 @@ class HtmlReporter {
160
209
  second: "2-digit",
161
210
  }).format(startTime));
162
211
  try {
163
- await Promise.allSettled([
164
- (0, r2_uploader_1.uploadDirectory)({
165
- sourceDir: this._outputFolder + "/trace",
166
- destinationDir: process.env.PROJECT_NAME +
167
- "/" +
168
- process.env.TEST_RUN_GITHUB_ACTION_ID +
169
- "/trace",
170
- uploadBucket: "test-report",
171
- }),
172
- // upload index.html
173
- (0, r2_uploader_1.uploadDirectory)({
174
- sourceDir: this._outputFolder,
175
- fileList: [path_1.default.join(this._outputFolder, "index.html")],
176
- destinationDir: process.env.PROJECT_NAME +
177
- "/" +
178
- process.env.TEST_RUN_GITHUB_ACTION_ID,
179
- uploadBucket: "test-report",
180
- }),
181
- // upload summary.json
182
- (0, r2_uploader_1.uploadDirectory)({
183
- sourceDir: this._outputFolder,
184
- fileList: [path_1.default.join(this._outputFolder, "summary.json")],
185
- destinationDir: process.env.PROJECT_NAME +
186
- "/" +
187
- process.env.TEST_RUN_GITHUB_ACTION_ID,
188
- uploadBucket: "test-report",
189
- }),
190
- ...this.pendingUploads,
191
- ]);
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();
192
244
  const endTime = new Date().getTime();
193
245
  console.log("Finished final report upload at: ", new Intl.DateTimeFormat("en-US", {
194
246
  hour: "2-digit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/playwright-utils",
3
- "version": "0.10.0",
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.2"
40
+ "@empiricalrun/r2-uploader": "^0.1.3"
41
41
  },
42
42
  "scripts": {
43
43
  "dev": "tsc --build --watch",