@muuktest/amikoo-reporter 1.1.0 → 1.2.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.
@@ -11,12 +11,48 @@ interface UploadOptions {
11
11
  signedUrlEndpoint?: string;
12
12
  repoRoot: string;
13
13
  }
14
+ /**
15
+ * Scans a Playwright TestResult for attachments tagged as amikoo artifacts
16
+ * and converts them into `AmikooArtifact` records the uploader understands.
17
+ *
18
+ * Convention: any attachment whose `name` starts with `amikoo-` is treated as
19
+ * a failure-data artifact. The `amikoo-` prefix is stripped from the name so
20
+ * the file lands in the zip with its "real" name (e.g. `amikoo-trace.json`
21
+ * becomes `failure-data/trace.json`).
22
+ *
23
+ * @param result - Playwright TestResult with `attachments`.
24
+ * @param testId - Hash identifying the test (used as the grouping key when
25
+ * multiple artifacts belong to the same test).
26
+ * @param fullTitle - Full test title including parent describe blocks; used
27
+ * to derive a human-readable slug for the S3 path.
28
+ * @param specFile - Absolute path to the .spec file; included so the
29
+ * uploader can also zip the test source + its imports.
30
+ * @returns Zero or more artifact records ready to be queued for upload.
31
+ */
14
32
  export declare function collectAmikooArtifacts(result: {
15
33
  attachments?: Array<{
16
34
  name?: string;
17
35
  path?: string;
18
36
  }>;
19
37
  }, testId: string, fullTitle: string, specFile: string): AmikooArtifact[];
38
+ /**
39
+ * Top-level entry point: groups artifacts by test, then uploads each group
40
+ * to S3 in parallel (bounded by `ARTIFACT_UPLOAD_CONCURRENCY`).
41
+ *
42
+ * Flow:
43
+ * 1. Bail out early if there's nothing to upload or no `AMIKOO_KEY`.
44
+ * 2. Group artifacts by `hash` so all files for one test land in a single
45
+ * zip (one S3 object per test, not per attachment).
46
+ * 3. Spawn N worker promises that pull from a shared cursor; each worker
47
+ * processes one test's group end-to-end (zip → signed URL → upload →
48
+ * upsert backend record).
49
+ * 4. Collect per-test results and print a single summary line. Individual
50
+ * failures are logged but do not abort the batch.
51
+ *
52
+ * @param files - All artifacts collected across the whole run.
53
+ * @param opts - Backend token, amikoo key, optional endpoint override, and
54
+ * the repo root used when zipping test source files.
55
+ */
20
56
  export declare function uploadAmikooArtifacts(files: AmikooArtifact[], opts: UploadOptions): Promise<void>;
21
57
  export {};
22
58
  //# sourceMappingURL=amikooArtifacts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"amikooArtifacts.d.ts","sourceRoot":"","sources":["../controlHub/amikooArtifacts.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAcD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE;IAAE,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,EACjE,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAclB;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,cAAc,EAAE,EACvB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
1
+ {"version":3,"file":"amikooArtifacts.d.ts","sourceRoot":"","sources":["../controlHub/amikooArtifacts.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AA2BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE;IAAE,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,EACjE,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAclB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,cAAc,EAAE,EACvB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Cf"}
@@ -11,10 +11,39 @@ const os_1 = __importDefault(require("os"));
11
11
  const apiUtils_1 = require("./apiUtils");
12
12
  const zipUtils_1 = require("./zipUtils");
13
13
  const s3Upload_1 = require("./s3Upload");
14
+ // How many artifact zips are built + uploaded to S3 in parallel.
15
+ //
16
+ // Each "worker" does: build zip on disk → request signed URL → PUT stream to S3.
17
+ // Higher values finish faster on fast networks but hold more open sockets,
18
+ // more `archiver` deflate state, and more disk I/O at once.
19
+ // Lower values (1–2) are gentler on memory and network — useful on
20
+ // constrained CI runners.
21
+ //
22
+ // Trade-off (per concurrent worker, approx):
23
+ // - 1 open HTTPS socket to S3 (TLS state ~1–2 MB)
24
+ // - 1 active `archiver` zip stream (small, but allocates deflate buffers)
25
+ // - 1 temp zip file open on disk (streamed, not buffered)
26
+ //
27
+ // Default: 10 (good balance for typical CI). Override with
28
+ // AMIKOO_ARTIFACT_UPLOAD_CONCURRENCY=<n>.
29
+ const ARTIFACT_UPLOAD_CONCURRENCY = Math.max(1, parseInt(process.env.AMIKOO_ARTIFACT_UPLOAD_CONCURRENCY || '', 10) || 10);
14
30
  const SIGNED_URL_ENDPOINTS = {
15
31
  prod: 'https://prgm4fborb.execute-api.us-east-2.amazonaws.com/prod/mcp/getSignedUrl',
16
32
  staging: 'https://prgm4fborb.execute-api.us-east-2.amazonaws.com/staging/mcp/getSignedUrl',
17
33
  };
34
+ /**
35
+ * Resolves the endpoint that hands out presigned S3 URLs for artifact uploads.
36
+ *
37
+ * Resolution order:
38
+ * 1. `AMIKOO_SIGNED_URL_ENDPOINT` env var, if set. Use this to point the
39
+ * reporter at a localhost endpoint (e.g. `http://localhost:3000/mcp/getSignedUrl`)
40
+ * or any custom deployment during development.
41
+ * 2. Otherwise, picks prod vs staging automatically based on which Control
42
+ * Hub URL the reporter is talking to (`getControlHubUrl()`).
43
+ *
44
+ * @returns Fully-qualified endpoint that returns a presigned S3 URL for
45
+ * uploading an artifact zip. May be localhost, staging, or prod.
46
+ */
18
47
  function resolveSignedUrlEndpoint() {
19
48
  if (process.env.AMIKOO_SIGNED_URL_ENDPOINT)
20
49
  return process.env.AMIKOO_SIGNED_URL_ENDPOINT;
@@ -22,6 +51,24 @@ function resolveSignedUrlEndpoint() {
22
51
  ? SIGNED_URL_ENDPOINTS.prod
23
52
  : SIGNED_URL_ENDPOINTS.staging;
24
53
  }
54
+ /**
55
+ * Scans a Playwright TestResult for attachments tagged as amikoo artifacts
56
+ * and converts them into `AmikooArtifact` records the uploader understands.
57
+ *
58
+ * Convention: any attachment whose `name` starts with `amikoo-` is treated as
59
+ * a failure-data artifact. The `amikoo-` prefix is stripped from the name so
60
+ * the file lands in the zip with its "real" name (e.g. `amikoo-trace.json`
61
+ * becomes `failure-data/trace.json`).
62
+ *
63
+ * @param result - Playwright TestResult with `attachments`.
64
+ * @param testId - Hash identifying the test (used as the grouping key when
65
+ * multiple artifacts belong to the same test).
66
+ * @param fullTitle - Full test title including parent describe blocks; used
67
+ * to derive a human-readable slug for the S3 path.
68
+ * @param specFile - Absolute path to the .spec file; included so the
69
+ * uploader can also zip the test source + its imports.
70
+ * @returns Zero or more artifact records ready to be queued for upload.
71
+ */
25
72
  function collectAmikooArtifacts(result, testId, fullTitle, specFile) {
26
73
  const out = [];
27
74
  for (const att of result.attachments || []) {
@@ -37,11 +84,29 @@ function collectAmikooArtifacts(result, testId, fullTitle, specFile) {
37
84
  }
38
85
  return out;
39
86
  }
87
+ /**
88
+ * Top-level entry point: groups artifacts by test, then uploads each group
89
+ * to S3 in parallel (bounded by `ARTIFACT_UPLOAD_CONCURRENCY`).
90
+ *
91
+ * Flow:
92
+ * 1. Bail out early if there's nothing to upload or no `AMIKOO_KEY`.
93
+ * 2. Group artifacts by `hash` so all files for one test land in a single
94
+ * zip (one S3 object per test, not per attachment).
95
+ * 3. Spawn N worker promises that pull from a shared cursor; each worker
96
+ * processes one test's group end-to-end (zip → signed URL → upload →
97
+ * upsert backend record).
98
+ * 4. Collect per-test results and print a single summary line. Individual
99
+ * failures are logged but do not abort the batch.
100
+ *
101
+ * @param files - All artifacts collected across the whole run.
102
+ * @param opts - Backend token, amikoo key, optional endpoint override, and
103
+ * the repo root used when zipping test source files.
104
+ */
40
105
  async function uploadAmikooArtifacts(files, opts) {
41
106
  if (!files.length)
42
107
  return;
43
108
  if (!opts.amikooKey) {
44
- console.warn('[amikoo-upload] AMIKOO_KEY missing; skipping artifact upload');
109
+ console.warn(' AMIKOO_KEY missing; skipping artifact upload');
45
110
  return;
46
111
  }
47
112
  const groups = new Map();
@@ -50,12 +115,54 @@ async function uploadAmikooArtifacts(files, opts) {
50
115
  bucket.push(f);
51
116
  groups.set(f.hash, bucket);
52
117
  }
53
- console.log(`[amikoo-upload] uploading ${groups.size} test(s)`);
54
- const results = await Promise.allSettled(Array.from(groups.entries()).map(([hash, group]) => uploadSingleTest(hash, group, opts)));
118
+ console.log(`📁 Uploading ${groups.size} artifact(s) to S3 (concurrency=${ARTIFACT_UPLOAD_CONCURRENCY})...`);
119
+ const entries = Array.from(groups.entries());
120
+ const results = [];
121
+ let cursor = 0;
122
+ const worker = async () => {
123
+ while (cursor < entries.length) {
124
+ const index = cursor++;
125
+ const [hash, group] = entries[index];
126
+ try {
127
+ await uploadSingleTest(hash, group, opts);
128
+ results.push({ status: 'fulfilled', value: undefined });
129
+ }
130
+ catch (reason) {
131
+ results.push({ status: 'rejected', reason });
132
+ }
133
+ }
134
+ };
135
+ const workerCount = Math.min(ARTIFACT_UPLOAD_CONCURRENCY, entries.length);
136
+ await Promise.all(Array.from({ length: workerCount }, () => worker()));
55
137
  const succeeded = results.filter(r => r.status === 'fulfilled').length;
56
138
  const failed = results.length - succeeded;
57
- console.log(`[amikoo-upload] summary: ${succeeded}/${results.length} succeeded, ${failed} failed`);
139
+ if (failed) {
140
+ console.warn(`⚠ Uploaded ${succeeded}/${results.length} artifact(s) to S3 (${failed} failed)`);
141
+ }
142
+ else {
143
+ console.log(`✔ Uploaded ${succeeded}/${results.length} artifact(s) to S3`);
144
+ }
58
145
  }
146
+ /**
147
+ * Builds a zip for a single test's artifacts, uploads it to S3, and records
148
+ * the resulting S3 path on the backend via `/test_execution_data/upsert`.
149
+ *
150
+ * Steps:
151
+ * 1. Build a zip in the OS temp dir containing:
152
+ * - `failure-data/*` → the amikoo artifact files
153
+ * - `test-files/*` → the spec file and its local imports
154
+ * 2. Request a fresh presigned S3 URL scoped to this test slug.
155
+ * 3. Stream the zip to S3 (see `uploadZipToS3` — streaming, not buffered).
156
+ * 4. Tell the backend where the zip landed so the UI can link to it.
157
+ * 5. Always delete the temp zip in `finally`, even on failure.
158
+ *
159
+ * Errors are logged with a clear per-test message and re-thrown so the
160
+ * parent batcher records the failure in its summary.
161
+ *
162
+ * @param hash - Test hash, used as the grouping key and S3 key fragment.
163
+ * @param group - All artifacts belonging to this test.
164
+ * @param opts - Upload options (token, amikoo key, repo root, endpoint).
165
+ */
59
166
  async function uploadSingleTest(hash, group, opts) {
60
167
  const testTitle = group[0].testTitle;
61
168
  const specFile = group[0].specFile;
@@ -73,11 +180,10 @@ async function uploadSingleTest(hash, group, opts) {
73
180
  if (!upsertResponse.success) {
74
181
  throw new Error(`upsert failed: ${upsertResponse.error}`);
75
182
  }
76
- console.log(`[amikoo-upload] ${slug} uploaded to ${sourcePath}`);
77
183
  }
78
184
  catch (error) {
79
185
  const msg = error instanceof Error ? error.message : String(error);
80
- console.error(`[amikoo-upload] ${slug} failed: ${msg}`);
186
+ console.error(` ✖ Artifact upload failed for ${slug}: ${msg}`);
81
187
  throw error;
82
188
  }
83
189
  finally {
@@ -87,6 +193,18 @@ async function uploadSingleTest(hash, group, opts) {
87
193
  catch { /* ignore */ }
88
194
  }
89
195
  }
196
+ /**
197
+ * Converts a free-form test title into an S3-safe slug.
198
+ *
199
+ * Rules:
200
+ * - lowercase
201
+ * - spaces → underscores
202
+ * - anything that isn't `[a-z0-9_-]` → underscore
203
+ * - collapse runs of underscores and trim leading/trailing ones
204
+ *
205
+ * Used as a path segment in the S3 key so artifacts are easy to spot when
206
+ * browsing the bucket.
207
+ */
90
208
  function sanitizeSlug(title) {
91
209
  return title
92
210
  .toLowerCase()
@@ -1 +1 @@
1
- {"version":3,"file":"amikooArtifacts.js","sourceRoot":"","sources":["../controlHub/amikooArtifacts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"amikooArtifacts.js","sourceRoot":"","sources":["../controlHub/amikooArtifacts.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ declare class MyReporter implements Reporter {
21
21
  private owner;
22
22
  private key;
23
23
  private testsInfo;
24
- private onBeginDonePromises;
24
+ private initPromise;
25
25
  onBegin(config: any, suite: any): Promise<void>;
26
26
  onTestBegin(test: any): Promise<void>;
27
27
  onError(error: any): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"controlHubReporter.d.ts","sourceRoot":"","sources":["../controlHub/controlHubReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAKrD,OAAO,EAAyB,cAAc,EAA0B,MAAM,mBAAmB,CAAC;AAKlG,cAAM,UAAW,YAAW,QAAQ;IAElC,iBAAiB,EAAE,GAAG,EAAE,CAAM;IAC9B,MAAM,EAAE,GAAG,EAAE,CAAM;IACnB,WAAW,EAAE,cAAc,EAAE,CAAM;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,cAAc,EAAE,MAAM,CAAM;IAC5B,eAAe,EAAE,MAAM,CAAK;IAC5B,OAAO,EAAE,GAAG,EAAE,CAAM;IACpB,kBAAkB,EAAE,MAAM,CAAK;IAC/B,OAAO,EAAE,MAAM,CAAgB;IAC/B,gBAAgB,EAAE,OAAO,CAAS;IAClC,yBAAyB,EAAE,GAAG,EAAE,CAAM;IACtC,GAAG,EAAE,GAAG,CAAC;IACT,eAAe,EAAE,GAAG,EAAE,CAAM;IAE5B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,mBAAmB,CAAuB;IAE5C,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG;IA+C/B,WAAW,CAAC,IAAI,EAAE,GAAG;IAIrB,OAAO,CAAC,KAAK,EAAE,GAAG;IAalB,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG;IA8EhC,KAAK,CAAC,MAAM,EAAE,GAAG;CA+ExB;AACD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"controlHubReporter.d.ts","sourceRoot":"","sources":["../controlHub/controlHubReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAKrD,OAAO,EAAyB,cAAc,EAA0B,MAAM,mBAAmB,CAAC;AAKlG,cAAM,UAAW,YAAW,QAAQ;IAElC,iBAAiB,EAAE,GAAG,EAAE,CAAM;IAC9B,MAAM,EAAE,GAAG,EAAE,CAAM;IACnB,WAAW,EAAE,cAAc,EAAE,CAAM;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,cAAc,EAAE,MAAM,CAAM;IAC5B,eAAe,EAAE,MAAM,CAAK;IAC5B,OAAO,EAAE,GAAG,EAAE,CAAM;IACpB,kBAAkB,EAAE,MAAM,CAAK;IAC/B,OAAO,EAAE,MAAM,CAAgB;IAC/B,gBAAgB,EAAE,OAAO,CAAS;IAClC,yBAAyB,EAAE,GAAG,EAAE,CAAM;IACtC,GAAG,EAAE,GAAG,CAAC;IACT,eAAe,EAAE,GAAG,EAAE,CAAM;IAE5B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,WAAW,CAA8B;IAE3C,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG;IA6C/B,WAAW,CAAC,IAAI,EAAE,GAAG;IAIrB,OAAO,CAAC,KAAK,EAAE,GAAG;IAalB,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG;IAgFhC,KAAK,CAAC,MAAM,EAAE,GAAG;CAqFxB;AACD,eAAe,UAAU,CAAC"}
@@ -25,12 +25,12 @@ class MyReporter {
25
25
  this.filesWithCompilationError = [];
26
26
  this.testEndPromises = [];
27
27
  this.testsInfo = [];
28
- this.onBeginDonePromises = [];
28
+ this.initPromise = null;
29
29
  }
30
30
  async onBegin(config, suite) {
31
31
  (0, reporterOrder_1.checkReporterOrder)(config);
32
- // Store initialization work as a promise that onTestEnd will await
33
- const initPromise = (async () => {
32
+ // Store initialization work as a single promise that onTestEnd will await
33
+ this.initPromise = (async () => {
34
34
  try {
35
35
  // We need to obtain a token from control hub so we can send API requests.
36
36
  this.key = process.env.AMIKOO_KEY || '';
@@ -67,7 +67,6 @@ class MyReporter {
67
67
  console.error('\n✖ Error during reporter initialization:', error);
68
68
  }
69
69
  })();
70
- this.onBeginDonePromises.push(initPromise);
71
70
  }
72
71
  async onTestBegin(test) {
73
72
  console.log(` ▶ Starting execution of test : ${test.title}`);
@@ -86,11 +85,13 @@ class MyReporter {
86
85
  }
87
86
  async onTestEnd(test, result) {
88
87
  // Wait for onBegin to complete before processing test results
89
- try {
90
- await Promise.all(this.onBeginDonePromises);
91
- }
92
- catch (error) {
93
- console.error(' ✖ Error waiting for initialization:', error);
88
+ if (this.initPromise) {
89
+ try {
90
+ await this.initPromise;
91
+ }
92
+ catch (error) {
93
+ console.error(' ✖ Error waiting for initialization:', error);
94
+ }
94
95
  }
95
96
  const statusIcon = result.status === 'passed' ? '✔' : '✖';
96
97
  const statusText = result.status === 'passed' ? 'Passed' : 'Failed';
@@ -134,8 +135,8 @@ class MyReporter {
134
135
  executionAt: new Date().toISOString(),
135
136
  result: result.status === "passed" ? true : false,
136
137
  error: errorData,
137
- systemOutput: (result.stdout) ? result.stdout.join(' ') : '',
138
- systemError: (result.stderr) ? result.stderr.join(' ') : '',
138
+ systemOutput: '',
139
+ systemError: '',
139
140
  };
140
141
  this.testExecutionData.push(payload);
141
142
  // Collect video for later batch processing
@@ -155,12 +156,18 @@ class MyReporter {
155
156
  async onEnd(result) {
156
157
  console.log('\n⏳ Waiting for all tests to complete...');
157
158
  try {
158
- await Promise.all([...this.onBeginDonePromises, ...this.testEndPromises]);
159
+ const pending = [...this.testEndPromises];
160
+ if (this.initPromise)
161
+ pending.push(this.initPromise);
162
+ await Promise.all(pending);
159
163
  }
160
164
  catch (error) {
161
165
  console.error('✖ Error waiting for test promises:', error);
162
166
  }
163
167
  console.log('✔ All tests completed\n');
168
+ // Release references to large per-test data structures we no longer need
169
+ this.testEndPromises = [];
170
+ this.testsInfo = [];
164
171
  if (this.executionNumber) {
165
172
  // Process videos and get presigned URLs
166
173
  const videoResult = await (0, videoUtils_1.processVideos)(this.videos, this.organizationId, this.executionNumber, this.access_token);
@@ -1 +1 @@
1
- {"version":3,"file":"controlHubReporter.js","sourceRoot":"","sources":["../controlHub/controlHubReporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"controlHubReporter.js","sourceRoot":"","sources":["../controlHub/controlHubReporter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"gitUtils.d.ts","sourceRoot":"","sources":["../controlHub/gitUtils.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAmCD,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2B7E"}
1
+ {"version":3,"file":"gitUtils.d.ts","sourceRoot":"","sources":["../controlHub/gitUtils.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAwHD,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2B7E"}
package/dist/gitUtils.js CHANGED
@@ -8,11 +8,66 @@ const child_process_1 = require("child_process");
8
8
  const dotenv_1 = __importDefault(require("dotenv"));
9
9
  const apiUtils_1 = require("./apiUtils");
10
10
  dotenv_1.default.config();
11
+ // Parse Azure DevOps repository URL to extract its components
12
+ // Supports formats:
13
+ // - https://username@dev.azure.com/organization/project/_git/repository
14
+ // - https://dev.azure.com/organization/project/_git/repository
15
+ // - https://organization.visualstudio.com/project/_git/repository
16
+ // params:
17
+ // - url (string) - Azure DevOps repository URL
18
+ // returns:
19
+ // - AzureRepoUrlParts object with extracted components, or null if invalid URL
20
+ function parseAzureRepoUrl(url) {
21
+ if (!url) {
22
+ return null;
23
+ }
24
+ try {
25
+ const urlObj = new URL(url);
26
+ const hostname = urlObj.hostname;
27
+ const pathname = urlObj.pathname;
28
+ const username = urlObj.username || undefined;
29
+ if (hostname === 'dev.azure.com') {
30
+ const parts = pathname.split('/').filter((p) => p);
31
+ if (parts.length >= 4 && parts[2] === '_git') {
32
+ const organization = decodeURIComponent(parts[0]);
33
+ const project = decodeURIComponent(parts[1]);
34
+ const repository = decodeURIComponent(parts[3]);
35
+ return {
36
+ username,
37
+ organization,
38
+ project,
39
+ repository,
40
+ baseUrl: `https://dev.azure.com/${organization}`
41
+ };
42
+ }
43
+ }
44
+ if (hostname.endsWith('.visualstudio.com')) {
45
+ const organization = hostname.replace('.visualstudio.com', '');
46
+ const parts = pathname.split('/').filter((p) => p);
47
+ if (parts.length >= 3 && parts[1] === '_git') {
48
+ const project = decodeURIComponent(parts[0]);
49
+ const repository = decodeURIComponent(parts[2]);
50
+ return {
51
+ username,
52
+ organization,
53
+ project,
54
+ repository,
55
+ baseUrl: `https://${hostname}`
56
+ };
57
+ }
58
+ }
59
+ }
60
+ catch {
61
+ // Not a valid URL or not Azure format.
62
+ }
63
+ return null;
64
+ }
11
65
  /**
12
66
  * Parses a git remote URL to extract owner and repo name.
13
- * Supports both HTTPS and SSH formats:
14
- * - https://github.com/owner/repo.git
15
- * - git@github.com:owner/repo.git
67
+ * Supports HTTPS and SSH formats:
68
+ * - GitHub: https://github.com/owner/repo.git
69
+ * - GitHub SSH: git@github.com:owner/repo.git
70
+ * - Azure DevOps: https://[username@]dev.azure.com/organization/project/_git/repository
16
71
  */
17
72
  function parseGitRemoteUrl(remoteUrl) {
18
73
  const response = {
@@ -21,6 +76,15 @@ function parseGitRemoteUrl(remoteUrl) {
21
76
  };
22
77
  // Remove trailing .git if present
23
78
  const cleanUrl = remoteUrl.replace(/\.git$/, '');
79
+ const parsedAzure = parseAzureRepoUrl(cleanUrl);
80
+ if (parsedAzure) {
81
+ return {
82
+ owner: parsedAzure.username || '',
83
+ repo: parsedAzure.repository,
84
+ organizationName: parsedAzure.organization,
85
+ projectName: parsedAzure.project
86
+ };
87
+ }
24
88
  // Match HTTPS format: https://github.com/owner/repo
25
89
  const httpsMatch = cleanUrl.match(/https?:\/\/[^\/]+\/([^\/]+)\/([^\/]+)/);
26
90
  if (httpsMatch) {
@@ -59,7 +123,7 @@ async function getGitContext(access_token) {
59
123
  repositoryId: repoData?.id?.toString() || "0",
60
124
  repositoryName: repo,
61
125
  branch,
62
- owner: owner || 'unknown-owner'
126
+ owner: repoData?.owner || 'unknown-owner'
63
127
  };
64
128
  }
65
129
  //# sourceMappingURL=gitUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gitUtils.js","sourceRoot":"","sources":["../controlHub/gitUtils.ts"],"names":[],"mappings":";;;;;AA8CA,sCA2BC;AAzED,iDAAyC;AACzC,oDAA4B;AAC5B,yCAAiC;AAEjC,gBAAM,CAAC,MAAM,EAAE,CAAC;AAShB;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,SAAiB;IAE1C,MAAM,QAAQ,GAAG;QACf,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,EAAE;KACT,CAAA;IACD,kCAAkC;IAClC,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEjD,oDAAoD;IACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3E,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,CAAC;IAED,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC5D,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC7B,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,6GAA6G;AAC7G,wHAAwH;AACjH,KAAK,UAAU,aAAa,CAAC,YAAoB;IACtD,IAAI,MAAc,CAAC;IACnB,IAAI,SAAiB,CAAC;IAEtB,IAAI,CAAC;QACH,MAAM,GAAG,IAAA,wBAAQ,EAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,gBAAgB,CAAC;QAChI,SAAS,GAAG,IAAA,wBAAQ,EAAC,oCAAoC,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;IACpH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;QACzF,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;IAC5G,CAAC;IAED,yCAAyC;IACzC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG;QACX,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,IAAI;KACb,CAAA;IACD,MAAM,QAAQ,GAAG,MAAM,cAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,YAAY,EAAG,IAAI,CAAC,CAAC;IACxE,MAAM,QAAQ,GAAG,MAAM,QAAQ,EAAE,IAAI,CAAC;IACtC,OAAO;QACL,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG;QAC7C,cAAc,EAAE,IAAI;QACpB,MAAM;QACN,KAAK,EAAE,KAAK,IAAI,eAAe;KAChC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"gitUtils.js","sourceRoot":"","sources":["../controlHub/gitUtils.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,39 @@
1
+ /**
2
+ * Requests a presigned S3 URL from the amikoo signed-URL service so we can
3
+ * PUT an artifact zip directly to S3 without going through the backend.
4
+ *
5
+ * The service decides the final S3 key from `test_name` (slug) and returns
6
+ * both the destination path we should record in our DB (`sourcePath`) and
7
+ * the time-limited PUT URL.
8
+ *
9
+ * @param endpoint - Full HTTPS URL of the signed-URL service
10
+ * (prod/staging differ — see `resolveSignedUrlEndpoint`).
11
+ * @param amikooKey - User's amikoo key, used by the service to scope the
12
+ * upload to the right organization.
13
+ * @param testSlug - URL-safe test name; becomes a path segment in S3.
14
+ * @returns `{ sourcePath, signedUrl }` — throws on HTTP error or if the
15
+ * response is missing either field.
16
+ */
1
17
  export declare function requestSignedUrl(endpoint: string, amikooKey: string, testSlug: string): Promise<{
2
18
  sourcePath: string;
3
19
  signedUrl: string;
4
20
  }>;
21
+ /**
22
+ * Streams a local zip file to S3 via a presigned PUT URL.
23
+ *
24
+ * Memory note: we deliberately do **not** call `fs.readFileSync(zipPath)`
25
+ * here. With concurrent uploads, buffering each zip would multiply RAM
26
+ * usage by the concurrency factor. Instead we open a Node read stream,
27
+ * convert it to a Web ReadableStream, and let undici/fetch send it in
28
+ * chunks (~64 KB at a time). `Content-Length` is set explicitly so S3 can
29
+ * validate the request and doesn't have to fall back to chunked encoding.
30
+ *
31
+ * The `duplex: 'half'` option is required by undici whenever the request
32
+ * body is a stream.
33
+ *
34
+ * @param zipPath - Absolute path to the zip on disk.
35
+ * @param signedUrl - Presigned PUT URL from `requestSignedUrl`.
36
+ * @throws If S3 responds with a non-2xx status.
37
+ */
5
38
  export declare function uploadZipToS3(zipPath: string, signedUrl: string): Promise<void>;
6
39
  //# sourceMappingURL=s3Upload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"s3Upload.d.ts","sourceRoot":"","sources":["../controlHub/s3Upload.ts"],"names":[],"mappings":"AAEA,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBpD;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAerF"}
1
+ {"version":3,"file":"s3Upload.d.ts","sourceRoot":"","sources":["../controlHub/s3Upload.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBrF"}
package/dist/s3Upload.js CHANGED
@@ -6,6 +6,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.requestSignedUrl = requestSignedUrl;
7
7
  exports.uploadZipToS3 = uploadZipToS3;
8
8
  const fs_1 = __importDefault(require("fs"));
9
+ const stream_1 = require("stream");
10
+ /**
11
+ * Requests a presigned S3 URL from the amikoo signed-URL service so we can
12
+ * PUT an artifact zip directly to S3 without going through the backend.
13
+ *
14
+ * The service decides the final S3 key from `test_name` (slug) and returns
15
+ * both the destination path we should record in our DB (`sourcePath`) and
16
+ * the time-limited PUT URL.
17
+ *
18
+ * @param endpoint - Full HTTPS URL of the signed-URL service
19
+ * (prod/staging differ — see `resolveSignedUrlEndpoint`).
20
+ * @param amikooKey - User's amikoo key, used by the service to scope the
21
+ * upload to the right organization.
22
+ * @param testSlug - URL-safe test name; becomes a path segment in S3.
23
+ * @returns `{ sourcePath, signedUrl }` — throws on HTTP error or if the
24
+ * response is missing either field.
25
+ */
9
26
  async function requestSignedUrl(endpoint, amikooKey, testSlug) {
10
27
  const response = await fetch(endpoint, {
11
28
  method: 'POST',
@@ -21,16 +38,40 @@ async function requestSignedUrl(endpoint, amikooKey, testSlug) {
21
38
  }
22
39
  return { sourcePath: data.sourcePath, signedUrl: data.signedUrl };
23
40
  }
41
+ /**
42
+ * Streams a local zip file to S3 via a presigned PUT URL.
43
+ *
44
+ * Memory note: we deliberately do **not** call `fs.readFileSync(zipPath)`
45
+ * here. With concurrent uploads, buffering each zip would multiply RAM
46
+ * usage by the concurrency factor. Instead we open a Node read stream,
47
+ * convert it to a Web ReadableStream, and let undici/fetch send it in
48
+ * chunks (~64 KB at a time). `Content-Length` is set explicitly so S3 can
49
+ * validate the request and doesn't have to fall back to chunked encoding.
50
+ *
51
+ * The `duplex: 'half'` option is required by undici whenever the request
52
+ * body is a stream.
53
+ *
54
+ * @param zipPath - Absolute path to the zip on disk.
55
+ * @param signedUrl - Presigned PUT URL from `requestSignedUrl`.
56
+ * @throws If S3 responds with a non-2xx status.
57
+ */
24
58
  async function uploadZipToS3(zipPath, signedUrl) {
25
- const buffer = fs_1.default.readFileSync(zipPath);
59
+ // Stream the zip from disk instead of buffering it in memory. With multiple
60
+ // concurrent uploads this keeps RAM flat even for large zips.
61
+ const stat = fs_1.default.statSync(zipPath);
62
+ const nodeStream = fs_1.default.createReadStream(zipPath);
63
+ const body = stream_1.Readable.toWeb(nodeStream);
26
64
  const response = await fetch(signedUrl, {
27
65
  method: 'PUT',
28
- body: buffer,
66
+ body,
29
67
  headers: {
30
68
  'Content-Type': 'application/zip',
69
+ 'Content-Length': String(stat.size),
31
70
  'x-amz-server-side-encryption': 'AES256',
32
71
  'x-amz-meta-purpose': 'muukmcp',
33
72
  },
73
+ // duplex is required by undici when the request body is a stream.
74
+ duplex: 'half',
34
75
  });
35
76
  if (!response.ok) {
36
77
  throw new Error(`S3 upload failed: ${response.status} ${response.statusText}`);
@@ -1 +1 @@
1
- {"version":3,"file":"s3Upload.js","sourceRoot":"","sources":["../controlHub/s3Upload.ts"],"names":[],"mappings":";;;;;AAEA,4CAqBC;AAED,sCAeC;AAxCD,4CAAoB;AAEb,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,SAAiB,EACjB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACrC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;KAC9D,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,IAAI,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;AACpE,CAAC;AAEM,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,SAAiB;IACpE,MAAM,MAAM,GAAG,YAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACtC,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE;YACP,cAAc,EAAE,iBAAiB;YACjC,8BAA8B,EAAE,QAAQ;YACxC,oBAAoB,EAAE,SAAS;SAChC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"s3Upload.js","sourceRoot":"","sources":["../controlHub/s3Upload.ts"],"names":[],"mappings":";;;;;AAmBA,4CAqBC;AAmBD,sCAuBC;AAlFD,4CAAoB;AACpB,mCAAkC;AAElC;;;;;;;;;;;;;;;GAeG;AACI,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,SAAiB,EACjB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACrC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;KAC9D,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,IAAI,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;AACpE,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACI,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,SAAiB;IACpE,4EAA4E;IAC5E,8DAA8D;IAC9D,MAAM,IAAI,GAAG,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,YAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,iBAAQ,CAAC,KAAK,CAAC,UAAU,CAA0C,CAAC;IAEjF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACtC,MAAM,EAAE,KAAK;QACb,IAAI;QACJ,OAAO,EAAE;YACP,cAAc,EAAE,iBAAiB;YACjC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YACnC,8BAA8B,EAAE,QAAQ;YACxC,oBAAoB,EAAE,SAAS;SAChC;QACD,kEAAkE;QAClE,MAAM,EAAE,MAAM;KACR,CAAC,CAAC;IAEV,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC"}
@@ -1,16 +1,57 @@
1
1
  /**
2
- * Gets video path from test result attachments
2
+ * Extracts the local filesystem path of the video recorded by Playwright
3
+ * for a given test result.
4
+ *
5
+ * Playwright stores videos as attachments on the TestResult. We look for an
6
+ * attachment explicitly named 'video', and fall back to any attachment whose
7
+ * path ends in `.webm` (older Playwright versions or custom setups).
8
+ *
9
+ * @param result - Playwright TestResult object (typed as `any` to avoid a hard
10
+ * dependency on Playwright's reporter types here).
11
+ * @returns Absolute path to the video file, or an empty string if no video
12
+ * attachment exists for this test.
3
13
  */
4
14
  export declare function getVideoPath(result: any): string;
5
15
  /**
6
- * Processes videos and requests presigned URLs for upload
16
+ * Prepares the video list for upload and asks the backend for presigned S3
17
+ * upload URLs in a single batch request.
18
+ *
19
+ * Steps:
20
+ * 1. Filter out videos whose local file no longer exists on disk.
21
+ * 2. Compute a deterministic S3 filename per video:
22
+ * `<executionNumber>_<testId>.webm`
23
+ * 3. Call `/execution/batch_upload_urls` once for all videos (single API
24
+ * round-trip instead of one per file).
25
+ *
26
+ * @param videos - Raw entries collected during the run, each with
27
+ * `{ path, testId }`.
28
+ * @param organizationId - Used as the S3 folder prefix: `videos/<orgId>`.
29
+ * @param executionNumber - Current run's execution number (prefix in S3 key).
30
+ * @param token - Amikoo API access token.
31
+ * @returns An object with the processed video metadata (`localPath` +
32
+ * `s3FileName`) and the matching presigned upload URLs. `uploadUrls`
33
+ * is `null` if the backend request failed or no videos were eligible.
7
34
  */
8
35
  export declare function processVideos(videos: any[], organizationId: string, executionNumber: number, token: string): Promise<{
9
36
  videos: any[];
10
37
  uploadUrls: any[] | null;
11
38
  }>;
12
39
  /**
13
- * Uploads all processed videos to S3 using their presigned URLs
40
+ * Uploads every processed video to S3 in parallel, bounded by
41
+ * `VIDEO_UPLOAD_CONCURRENCY`.
42
+ *
43
+ * Implementation:
44
+ * - Builds a `Map<s3FileName, presignedUrl>` for O(1) lookup.
45
+ * - Spawns up to N "worker" promises that pull from a shared cursor; as
46
+ * soon as a worker finishes one upload, it grabs the next pending video.
47
+ * This keeps the connection pipeline saturated without ever holding more
48
+ * than N file streams open at once.
49
+ * - Failures are recorded per-video; one failed upload does not abort the
50
+ * rest. A summary line is printed at the end.
51
+ *
52
+ * @param videos - Processed video entries from `processVideos`.
53
+ * @param uploadUrls - Presigned URLs from the backend, keyed by `fileName`.
54
+ * @returns Per-video results: `{ fileName, success, error? }`.
14
55
  */
15
56
  export declare function uploadVideosToS3(videos: any[], uploadUrls: any[]): Promise<any[]>;
16
57
  //# sourceMappingURL=videoUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"videoUtils.d.ts","sourceRoot":"","sources":["../controlHub/videoUtils.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,GAAG,EAAE,EACb,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAAC,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC,CA0BtD;AA8BD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CA8BvF"}
1
+ {"version":3,"file":"videoUtils.d.ts","sourceRoot":"","sources":["../controlHub/videoUtils.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAGhD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,GAAG,EAAE,EACb,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAAC,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC,CA0BtD;AAsDD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAqCvF"}
@@ -7,16 +7,59 @@ exports.getVideoPath = getVideoPath;
7
7
  exports.processVideos = processVideos;
8
8
  exports.uploadVideosToS3 = uploadVideosToS3;
9
9
  const fs_1 = __importDefault(require("fs"));
10
+ const stream_1 = require("stream");
10
11
  const apiUtils_1 = require("./apiUtils");
12
+ // How many videos are uploaded to S3 in parallel.
13
+ //
14
+ // Each "worker" streams one .webm file to S3 via a presigned URL using
15
+ // fs.createReadStream → fetch (no buffering). Higher values finish faster
16
+ // on fast networks but hold more open sockets and file descriptors at once.
17
+ // Lower values (1–2) are gentler on memory and network — useful on
18
+ // constrained CI runners.
19
+ //
20
+ // Trade-off (per concurrent worker, approx):
21
+ // - 1 open HTTPS socket to S3 (TLS state ~1–2 MB)
22
+ // - 1 open file descriptor + small read-stream buffer (~64 KB)
23
+ //
24
+ // Default: 10 (good balance for typical CI). Override with
25
+ // AMIKOO_VIDEO_UPLOAD_CONCURRENCY=<n>.
26
+ const VIDEO_UPLOAD_CONCURRENCY = Math.max(1, parseInt(process.env.AMIKOO_VIDEO_UPLOAD_CONCURRENCY || '', 10) || 10);
11
27
  /**
12
- * Gets video path from test result attachments
28
+ * Extracts the local filesystem path of the video recorded by Playwright
29
+ * for a given test result.
30
+ *
31
+ * Playwright stores videos as attachments on the TestResult. We look for an
32
+ * attachment explicitly named 'video', and fall back to any attachment whose
33
+ * path ends in `.webm` (older Playwright versions or custom setups).
34
+ *
35
+ * @param result - Playwright TestResult object (typed as `any` to avoid a hard
36
+ * dependency on Playwright's reporter types here).
37
+ * @returns Absolute path to the video file, or an empty string if no video
38
+ * attachment exists for this test.
13
39
  */
14
40
  function getVideoPath(result) {
15
41
  const attachment = result.attachments?.find((a) => a.name === 'video' || a.path?.endsWith('.webm'));
16
42
  return attachment?.path || '';
17
43
  }
18
44
  /**
19
- * Processes videos and requests presigned URLs for upload
45
+ * Prepares the video list for upload and asks the backend for presigned S3
46
+ * upload URLs in a single batch request.
47
+ *
48
+ * Steps:
49
+ * 1. Filter out videos whose local file no longer exists on disk.
50
+ * 2. Compute a deterministic S3 filename per video:
51
+ * `<executionNumber>_<testId>.webm`
52
+ * 3. Call `/execution/batch_upload_urls` once for all videos (single API
53
+ * round-trip instead of one per file).
54
+ *
55
+ * @param videos - Raw entries collected during the run, each with
56
+ * `{ path, testId }`.
57
+ * @param organizationId - Used as the S3 folder prefix: `videos/<orgId>`.
58
+ * @param executionNumber - Current run's execution number (prefix in S3 key).
59
+ * @param token - Amikoo API access token.
60
+ * @returns An object with the processed video metadata (`localPath` +
61
+ * `s3FileName`) and the matching presigned upload URLs. `uploadUrls`
62
+ * is `null` if the backend request failed or no videos were eligible.
20
63
  */
21
64
  async function processVideos(videos, organizationId, executionNumber, token) {
22
65
  let processed = [];
@@ -45,25 +88,48 @@ async function processVideos(videos, organizationId, executionNumber, token) {
45
88
  return { videos: processed, uploadUrls };
46
89
  }
47
90
  /**
48
- * Uploads a single video file to S3 using a presigned URL
91
+ * Uploads a single video file to S3 using a presigned URL.
92
+ *
93
+ * Memory note: the file is **streamed** from disk via `fs.createReadStream`
94
+ * and converted to a Web ReadableStream for `fetch`. This keeps RAM usage
95
+ * flat (a small ~64 KB internal buffer) regardless of file size — important
96
+ * because `.webm` recordings can be tens of MB each and we may have hundreds
97
+ * of them in a single run.
98
+ *
99
+ * The `duplex: 'half'` option is required by Node's undici-based fetch
100
+ * implementation whenever the request body is a stream.
101
+ *
102
+ * @param filePath - Absolute path to the local video file.
103
+ * @param uploadUrl - Presigned S3 PUT URL returned by `processVideos`.
104
+ * @returns `true` if S3 responded with a 2xx status, `false` otherwise (the
105
+ * caller logs and continues — one failed upload does not abort the
106
+ * batch).
49
107
  */
50
108
  async function uploadVideoToS3(filePath, uploadUrl) {
51
109
  let success = false;
52
110
  if (fs_1.default.existsSync(filePath)) {
53
- //try {
54
- const fileBuffer = fs_1.default.readFileSync(filePath);
111
+ // Stream the file instead of buffering it in memory. This keeps RAM flat
112
+ // even when there are hundreds of large .webm files.
113
+ const stat = fs_1.default.statSync(filePath);
114
+ const nodeStream = fs_1.default.createReadStream(filePath);
115
+ // undici/fetch requires a Web ReadableStream for streamed bodies and
116
+ // `duplex: 'half'` when the body is a stream.
117
+ const body = stream_1.Readable.toWeb(nodeStream);
55
118
  const response = await fetch(uploadUrl, {
56
119
  method: 'PUT',
57
- body: fileBuffer,
58
- headers: { 'Content-Type': 'video/webm' },
120
+ body,
121
+ headers: {
122
+ 'Content-Type': 'video/webm',
123
+ 'Content-Length': String(stat.size),
124
+ },
125
+ // duplex is required by undici when the request body is a stream.
126
+ // Cast to any because not all TS lib versions include this field yet.
127
+ duplex: 'half',
59
128
  });
60
129
  success = response.ok;
61
130
  if (!success) {
62
131
  console.log(` ✖ Upload failed with status: ${response.status}`);
63
132
  }
64
- /* } catch (error) {
65
- console.log('Error uploading video:', error);
66
- }*/
67
133
  }
68
134
  else {
69
135
  console.log(` ✖ Video file not found: ${filePath}`);
@@ -71,28 +137,48 @@ async function uploadVideoToS3(filePath, uploadUrl) {
71
137
  return success;
72
138
  }
73
139
  /**
74
- * Uploads all processed videos to S3 using their presigned URLs
140
+ * Uploads every processed video to S3 in parallel, bounded by
141
+ * `VIDEO_UPLOAD_CONCURRENCY`.
142
+ *
143
+ * Implementation:
144
+ * - Builds a `Map<s3FileName, presignedUrl>` for O(1) lookup.
145
+ * - Spawns up to N "worker" promises that pull from a shared cursor; as
146
+ * soon as a worker finishes one upload, it grabs the next pending video.
147
+ * This keeps the connection pipeline saturated without ever holding more
148
+ * than N file streams open at once.
149
+ * - Failures are recorded per-video; one failed upload does not abort the
150
+ * rest. A summary line is printed at the end.
151
+ *
152
+ * @param videos - Processed video entries from `processVideos`.
153
+ * @param uploadUrls - Presigned URLs from the backend, keyed by `fileName`.
154
+ * @returns Per-video results: `{ fileName, success, error? }`.
75
155
  */
76
156
  async function uploadVideosToS3(videos, uploadUrls) {
77
157
  const results = [];
78
- console.log(`📹 Uploading ${videos.length} video(s) to S3...`);
158
+ console.log(`📹 Uploading ${videos.length} video(s) to S3 (concurrency=${VIDEO_UPLOAD_CONCURRENCY})...`);
79
159
  if (videos.length && uploadUrls?.length) {
80
160
  // Create a map for quick lookup by S3 filename
81
161
  const urlMap = new Map(uploadUrls.map(u => [u.fileName, u.uploadUrl]));
82
- // Upload all videos in parallel
83
- const uploadPromises = videos.map(async (video) => {
84
- const uploadUrl = urlMap.get(video.s3FileName);
85
- if (uploadUrl) {
86
- const success = await uploadVideoToS3(video.localPath, uploadUrl);
87
- return { fileName: video.s3FileName, success };
162
+ // Upload in bounded-concurrency batches so we never hold more than
163
+ // VIDEO_UPLOAD_CONCURRENCY file streams open at once.
164
+ let cursor = 0;
165
+ const worker = async () => {
166
+ while (cursor < videos.length) {
167
+ const index = cursor++;
168
+ const video = videos[index];
169
+ const uploadUrl = urlMap.get(video.s3FileName);
170
+ if (uploadUrl) {
171
+ const success = await uploadVideoToS3(video.localPath, uploadUrl);
172
+ results.push({ fileName: video.s3FileName, success });
173
+ }
174
+ else {
175
+ console.log(` ✖ No upload URL found for: ${video.s3FileName}`);
176
+ results.push({ fileName: video.s3FileName, success: false, error: 'No upload URL' });
177
+ }
88
178
  }
89
- else {
90
- console.log(` ✖ No upload URL found for: ${video.s3FileName}`);
91
- return { fileName: video.s3FileName, success: false, error: 'No upload URL' };
92
- }
93
- });
94
- const uploadResults = await Promise.all(uploadPromises);
95
- results.push(...uploadResults);
179
+ };
180
+ const workerCount = Math.min(VIDEO_UPLOAD_CONCURRENCY, videos.length);
181
+ await Promise.all(Array.from({ length: workerCount }, () => worker()));
96
182
  const successCount = results.filter(r => r.success).length;
97
183
  console.log(`✔ Uploaded ${successCount}/${results.length} video(s) to S3`);
98
184
  }
@@ -1 +1 @@
1
- {"version":3,"file":"videoUtils.js","sourceRoot":"","sources":["../controlHub/videoUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"videoUtils.js","sourceRoot":"","sources":["../controlHub/videoUtils.ts"],"names":[],"mappings":";;;;;AAoCA,oCAGC;AAsBD,sCA+BC;AAuED,4CAqCC;AAxMD,4CAAoB;AACpB,mCAAkC;AAClC,yCAAiC;AAEjC,kDAAkD;AAClD,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,4EAA4E;AAC5E,mEAAmE;AACnE,0BAA0B;AAC1B,EAAE;AACF,6CAA6C;AAC7C,oDAAoD;AACpD,iEAAiE;AACjE,EAAE;AACF,2DAA2D;AAC3D,uCAAuC;AACvC,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,CACvC,CAAC,EACD,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CACtE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,SAAgB,YAAY,CAAC,MAAW;IACtC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACzG,OAAO,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACI,KAAK,UAAU,aAAa,CACjC,MAAa,EACb,cAAsB,EACtB,eAAuB,EACvB,KAAa;IAEb,IAAI,SAAS,GAAU,EAAE,CAAC;IAC1B,IAAI,UAAU,GAAiB,IAAI,CAAC;IAEpC,IAAI,MAAM,CAAC,MAAM,IAAI,cAAc,IAAI,eAAe,EAAE,CAAC;QACvD,qDAAqD;QACrD,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,YAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aAC5D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACT,SAAS,EAAE,CAAC,CAAC,IAAI;YACjB,UAAU,EAAE,GAAG,eAAe,IAAI,CAAC,CAAC,MAAM,OAAO;SAClD,CAAC,CAAC,CAAC;QAEN,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YACrB,mDAAmD;YACnD,MAAM,QAAQ,GAAG,MAAM,cAAG,CAAC,IAAI,CAAC,8BAA8B,EAAE,KAAK,EAAE;gBACrE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,cAAc,EAAE,EAAE,CAAC,CAAC;aACvH,CAAC,CAAC;YACH,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,SAAiB;IAChE,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,yEAAyE;QACzE,qDAAqD;QACrD,MAAM,IAAI,GAAG,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,YAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACjD,qEAAqE;QACrE,8CAA8C;QAC9C,MAAM,IAAI,GAAG,iBAAQ,CAAC,KAAK,CAAC,UAAU,CAA0C,CAAC;QAEjF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YACtC,MAAM,EAAE,KAAK;YACb,IAAI;YACJ,OAAO,EAAE;gBACP,cAAc,EAAE,YAAY;gBAC5B,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;aACpC;YACD,kEAAkE;YAClE,sEAAsE;YACtE,MAAM,EAAE,MAAM;SACR,CAAC,CAAC;QACV,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,kCAAkC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACI,KAAK,UAAU,gBAAgB,CAAC,MAAa,EAAE,UAAiB;IACrE,MAAM,OAAO,GAAU,EAAE,CAAC;IAE1B,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,MAAM,gCAAgC,wBAAwB,MAAM,CAAC,CAAC;IACzG,IAAI,MAAM,CAAC,MAAM,IAAI,UAAU,EAAE,MAAM,EAAE,CAAC;QACxC,+CAA+C;QAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAEvE,mEAAmE;QACnE,sDAAsD;QACtD,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;YACxB,OAAO,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC/C,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;oBAClE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;gBACxD,CAAC;qBACI,CAAC;oBACJ,OAAO,CAAC,GAAG,CAAC,gCAAgC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;oBAChE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;gBACvF,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACtE,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEvE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,cAAc,YAAY,IAAI,OAAO,CAAC,MAAM,iBAAiB,CAAC,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muuktest/amikoo-reporter",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Playwright reporter for Amikoo - automatically installs and configures test reporting to Amikoo AI",
5
5
  "main": "dist/controlHubReporter.js",
6
6
  "types": "dist/controlHubReporter.d.ts",