@empiricalrun/playwright-utils 0.43.1 → 0.45.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,17 @@
1
1
  # @empiricalrun/playwright-utils
2
2
 
3
+ ## 0.45.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 11ea318: feat: after sigint, ER stops sending events and uploader is shared
8
+
9
+ ## 0.44.0
10
+
11
+ ### Minor Changes
12
+
13
+ - d3981f9: fix: prevent attachment upload in blob zip
14
+
3
15
  ## 0.43.1
4
16
 
5
17
  ### Patch Changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=example.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example.spec.d.ts","sourceRoot":"","sources":["../../../src/reporter/IBR-unit-test/example.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_1 = require("@playwright/test");
4
+ (0, test_1.test)("fast test", async () => {
5
+ (0, test_1.expect)(1 + 1).toBe(2);
6
+ });
7
+ (0, test_1.test)("slow test 1", async () => {
8
+ await new Promise((r) => setTimeout(r, 20000));
9
+ (0, test_1.expect)(true).toBe(true);
10
+ });
11
+ (0, test_1.test)("slow test 2", async () => {
12
+ await new Promise((r) => setTimeout(r, 20000));
13
+ (0, test_1.expect)(true).toBe(true);
14
+ });
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@playwright/test").PlaywrightTestConfig<{}, {}>;
2
+ export default _default;
3
+ //# sourceMappingURL=playwright.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright.config.d.ts","sourceRoot":"","sources":["../../../src/reporter/IBR-unit-test/playwright.config.ts"],"names":[],"mappings":";AAEA,wBAIG"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_1 = require("@playwright/test");
4
+ exports.default = (0, test_1.defineConfig)({
5
+ reporter: [["__REPORTER_PATH__"], ["list"]],
6
+ testDir: ".",
7
+ timeout: 30000,
8
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"empirical-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/empirical-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAqBnC,cAAM,iBAAkB,YAAW,QAAQ;IACzC,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,oBAAoB,CAG1B;IACF,OAAO,CAAC,sBAAsB,CAAuB;IACrD,OAAO,CAAC,YAAY,CAAgD;IACpE,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,SAAS,CAAyB;;IAM1C,OAAO,CAAC,6BAA6B,CAkCnC;IAEF,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAuGtC,KAAK,CAAC,MAAM,EAAE,UAAU;IAiG9B,OAAO,CAAC,qBAAqB;YAkBf,gBAAgB;YAOhB,iBAAiB;CAmChC;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"empirical-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/empirical-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAsBnC,cAAM,iBAAkB,YAAW,QAAQ;IACzC,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,oBAAoB,CAG1B;IACF,OAAO,CAAC,sBAAsB,CAAuB;IACrD,OAAO,CAAC,YAAY,CAAgD;IACpE,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,SAAS,CAAyB;;IAM1C,OAAO,CAAC,6BAA6B,CAkCnC;IAEF,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAwGtC,KAAK,CAAC,MAAM,EAAE,UAAU;IAkG9B,OAAO,CAAC,qBAAqB;YAkBf,gBAAgB;YAOhB,iBAAiB;CAmChC;AAED,eAAe,iBAAiB,CAAC"}
@@ -10,6 +10,7 @@ const telemetry_1 = require("../telemetry");
10
10
  const blob_utils_1 = require("./blob-utils");
11
11
  const failing_line_1 = require("./failing-line");
12
12
  const incremental_blob_reporter_1 = require("./incremental-blob-reporter");
13
+ const reporter_state_1 = require("./reporter-state");
13
14
  const uploader_1 = require("./uploader");
14
15
  const util_1 = require("./util");
15
16
  class EmpiricalReporter {
@@ -21,7 +22,7 @@ class EmpiricalReporter {
21
22
  _testRetryCounts = new Map();
22
23
  _uploader = null;
23
24
  constructor() {
24
- this._uploader = (0, uploader_1.createUploader)();
25
+ this._uploader = (0, uploader_1.getUploader)();
25
26
  }
26
27
  enqueTestAttachmentUploadTask = async (attachment) => {
27
28
  if (!this._uploader)
@@ -43,6 +44,8 @@ class EmpiricalReporter {
43
44
  }
44
45
  };
45
46
  onTestEnd(test, result) {
47
+ if ((0, reporter_state_1.isFinalized)())
48
+ return;
46
49
  if (!this._uploader)
47
50
  return;
48
51
  if (!process.env.TEST_RUN_GITHUB_ACTION_ID) {
@@ -124,6 +127,8 @@ class EmpiricalReporter {
124
127
  }
125
128
  }
126
129
  async onEnd(result) {
130
+ if ((0, reporter_state_1.isFinalized)())
131
+ return;
127
132
  if (!this._uploader)
128
133
  return;
129
134
  logger_1.logger.debug(`[Empirical Reporter] Test run completed with status: ${result.status}`);
@@ -22,7 +22,6 @@ declare class IncrementalBlobReporter implements Reporter {
22
22
  private _uploader;
23
23
  private _interrupted;
24
24
  private _lastTestEndIndex;
25
- private _finalized;
26
25
  private _startTime;
27
26
  constructor();
28
27
  private _sigintHandler;
@@ -50,7 +49,6 @@ declare class IncrementalBlobReporter implements Reporter {
50
49
  onStepBegin(test: TestCase, result: TestResult, step: TestStep): void;
51
50
  onStepEnd(test: TestCase, result: TestResult, step: TestStep): void;
52
51
  onEnd(result: FullResult): Promise<void>;
53
- private _mergeForLocalTest;
54
52
  /**
55
53
  * Add a single attachment URL mapping
56
54
  */
@@ -1 +1 @@
1
- {"version":3,"file":"incremental-blob-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/incremental-blob-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAUnC;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEnD,cAAM,uBAAwB,YAAW,QAAQ;IAC/C,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,WAAW,CAIjB;IACF,OAAO,CAAC,UAAU,CAGhB;IACF,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,UAAU,CAAsB;;IAexC,OAAO,CAAC,cAAc,CAA6B;IAEnD,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,oBAAoB;YAOd,eAAe;IAiC7B,OAAO,CAAC,2BAA2B;IA4BnC,OAAO,KAAK,QAAQ,GAKnB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,cAAc;YAQR,SAAS;IAwBvB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IA+E/C,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAerD,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAyCnD,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAmBrE,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAsB7D,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAmBhC,kBAAkB;IA2ChC;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI5D,aAAa,IAAI,OAAO;CAGzB;AAID,wBAAgB,0BAA0B,IAAI,uBAAuB,GAAG,IAAI,CAE3E;AAED,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,uBAAuB,GAChC,IAAI,CAEN;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"incremental-blob-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/incremental-blob-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAenC;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEnD,cAAM,uBAAwB,YAAW,QAAQ;IAC/C,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,WAAW,CAIjB;IACF,OAAO,CAAC,UAAU,CAGhB;IACF,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,UAAU,CAAsB;;IAexC,OAAO,CAAC,cAAc,CAA6B;IAEnD,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,oBAAoB;YAOd,eAAe;IAkC7B,OAAO,CAAC,2BAA2B;IA8BnC,OAAO,KAAK,QAAQ,GAKnB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,cAAc;YAQR,SAAS;IAwBvB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IA+E/C,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAerD,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAyCnD,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAmBrE,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAsB7D,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9C;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI5D,aAAa,IAAI,OAAO;CAGzB;AAID,wBAAgB,0BAA0B,IAAI,uBAAuB,GAAG,IAAI,CAE3E;AAED,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,uBAAuB,GAChC,IAAI,CAEN;AAED,eAAe,uBAAuB,CAAC"}
@@ -6,13 +6,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getIncrementalBlobReporter = getIncrementalBlobReporter;
7
7
  exports.setIncrementalBlobReporterInstance = setIncrementalBlobReporterInstance;
8
8
  const zip_1 = require("@empiricalrun/r2-uploader/zip");
9
- const child_process_1 = require("child_process");
10
9
  const crypto_1 = __importDefault(require("crypto"));
11
10
  const fs_1 = __importDefault(require("fs"));
12
11
  const os_1 = __importDefault(require("os"));
13
12
  const path_1 = __importDefault(require("path"));
13
+ const local_test_1 = require("./local-test");
14
+ const reporter_state_1 = require("./reporter-state");
14
15
  const uploader_1 = require("./uploader");
15
16
  const BLOB_REPORT_VERSION = 2;
17
+ function isLocalTesting() {
18
+ return process.env.LOCAL_TEST === "true";
19
+ }
16
20
  class IncrementalBlobReporter {
17
21
  _currentWorkingDir = process.cwd();
18
22
  _stagingDir = path_1.default.join(this._currentWorkingDir, "blob-report-incremental", "staging");
@@ -27,7 +31,6 @@ class IncrementalBlobReporter {
27
31
  _uploader = null;
28
32
  _interrupted = false;
29
33
  _lastTestEndIndex = -1;
30
- _finalized = false;
31
34
  _startTime = Date.now();
32
35
  constructor() {
33
36
  if (process.env.SHARD_INDEX && process.env.TOTAL_SHARDS) {
@@ -38,7 +41,7 @@ class IncrementalBlobReporter {
38
41
  this._shardIndex = 1;
39
42
  this._totalShards = 1;
40
43
  }
41
- this._uploader = (0, uploader_1.createUploader)();
44
+ this._uploader = (0, uploader_1.getUploader)();
42
45
  setIncrementalBlobReporterInstance(this);
43
46
  this._setupSignalHandler();
44
47
  }
@@ -48,7 +51,8 @@ class IncrementalBlobReporter {
48
51
  console.log("[IncrementalBlobReporter] SIGINT received, flushing and uploading...");
49
52
  this._flushAndUpload()
50
53
  .then(() => {
51
- console.log("[IncrementalBlobReporter] Flush and upload complete on SIGINT");
54
+ console.log("[IncrementalBlobReporter] Flush and upload complete on SIGINT, exiting");
55
+ process.exit(0);
52
56
  })
53
57
  .catch((err) => {
54
58
  console.error("[IncrementalBlobReporter] Flush/upload failed on SIGINT:", err);
@@ -67,6 +71,7 @@ class IncrementalBlobReporter {
67
71
  }
68
72
  async _flushAndUpload() {
69
73
  this._interrupted = true;
74
+ (0, reporter_state_1.setFinalized)();
70
75
  // Wait for pending attachment uploads FIRST so URLs are available
71
76
  if (this._uploader) {
72
77
  await this._uploader.waitForUploads();
@@ -80,29 +85,30 @@ class IncrementalBlobReporter {
80
85
  await this._uploader.uploadFile(this._zipPath, `blobs/incremental-report-${this._shardIndex}.zip`);
81
86
  await this._uploader.waitForUploads();
82
87
  console.log("[IncrementalBlobReporter] Flush and upload complete on SIGINT");
83
- if (process.env.LOCAL_TEST === "true") {
84
- await this._mergeForLocalTest();
88
+ if (isLocalTesting()) {
89
+ await (0, local_test_1.mergeForLocalTest)(this._currentWorkingDir, this._outputDir);
85
90
  }
86
91
  }
87
92
  _finalizeReportForInterrupt() {
88
- if (this._finalized)
89
- return;
90
93
  if (this._lastTestEndIndex === -1) {
91
94
  console.log("[IncrementalBlobReporter] No onTestEnd found, cannot finalize report. Merge may fail");
92
95
  return;
93
96
  }
94
97
  // Truncate to last onTestEnd
95
98
  this._reportLines = this._reportLines.slice(0, this._lastTestEndIndex + 1);
96
- // Append onEnd with interrupted status
99
+ // Push onEnd directly (bypass _appendEvent which checks isFinalized)
97
100
  const now = Date.now();
98
- this._appendEvent("onEnd", {
99
- result: {
100
- status: "interrupted",
101
- startTime: this._startTime,
102
- duration: now - this._startTime,
101
+ const onEndEvent = {
102
+ method: "onEnd",
103
+ params: {
104
+ result: {
105
+ status: "interrupted",
106
+ startTime: this._startTime,
107
+ duration: now - this._startTime,
108
+ },
103
109
  },
104
- });
105
- this._finalized = true;
110
+ };
111
+ this._reportLines.push(JSON.stringify(onEndEvent));
106
112
  console.log(`[IncrementalBlobReporter] Finalized report at line ${this._lastTestEndIndex + 1}, status: interrupted`);
107
113
  }
108
114
  get _zipPath() {
@@ -127,6 +133,9 @@ class IncrementalBlobReporter {
127
133
  _embedAttachment(attachmentPath, resultId) {
128
134
  if (!attachmentPath || !fs_1.default.existsSync(attachmentPath))
129
135
  return null;
136
+ if (!isLocalTesting()) {
137
+ return null;
138
+ }
130
139
  const ext = path_1.default.extname(attachmentPath);
131
140
  const uniqueName = `${resultId}-${this._generateId()}${ext}`;
132
141
  const destPath = path_1.default.join(this._stagingDir, uniqueName);
@@ -160,7 +169,7 @@ class IncrementalBlobReporter {
160
169
  return stepId;
161
170
  }
162
171
  _appendEvent(method, params) {
163
- if (this._finalized)
172
+ if ((0, reporter_state_1.isFinalized)())
164
173
  return;
165
174
  if (this._interrupted && method !== "onEnd")
166
175
  return;
@@ -392,33 +401,6 @@ class IncrementalBlobReporter {
392
401
  await this._writeZip();
393
402
  console.log(`[IncrementalBlobReporter] Finished with status: ${result.status}`);
394
403
  }
395
- async _mergeForLocalTest() {
396
- const htmlOutputDir = path_1.default.join(this._currentWorkingDir, "partial-playwright-report");
397
- const summaryJsonPath = path_1.default.join(this._currentWorkingDir, "partial-summary.json");
398
- console.log(`[IncrementalBlobReporter] Running merge report on ${this._outputDir}`);
399
- try {
400
- (0, child_process_1.execFileSync)("npx", [
401
- "playwright",
402
- "merge-reports",
403
- this._outputDir,
404
- "--reporter",
405
- "html,json",
406
- ], {
407
- cwd: this._currentWorkingDir,
408
- env: {
409
- ...process.env,
410
- PLAYWRIGHT_HTML_OPEN: "never",
411
- PLAYWRIGHT_HTML_OUTPUT_DIR: htmlOutputDir,
412
- PLAYWRIGHT_JSON_OUTPUT_NAME: summaryJsonPath,
413
- },
414
- stdio: "inherit",
415
- });
416
- console.log(`[IncrementalBlobReporter] Merge report completed. HTML: ${htmlOutputDir}, JSON: ${summaryJsonPath}`);
417
- }
418
- catch (err) {
419
- console.error(`[IncrementalBlobReporter] Merge report failed:`, err);
420
- }
421
- }
422
404
  /**
423
405
  * Add a single attachment URL mapping
424
406
  */
@@ -0,0 +1,2 @@
1
+ export declare function mergeForLocalTest(currentWorkingDir: string, outputDir: string): Promise<void>;
2
+ //# sourceMappingURL=local-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-test.d.ts","sourceRoot":"","sources":["../../src/reporter/local-test.ts"],"names":[],"mappings":"AAGA,wBAAsB,iBAAiB,CACrC,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.mergeForLocalTest = mergeForLocalTest;
7
+ const child_process_1 = require("child_process");
8
+ const path_1 = __importDefault(require("path"));
9
+ async function mergeForLocalTest(currentWorkingDir, outputDir) {
10
+ const htmlOutputDir = path_1.default.join(currentWorkingDir, "partial-playwright-report");
11
+ const summaryJsonPath = path_1.default.join(currentWorkingDir, "partial-summary.json");
12
+ console.log(`[IncrementalBlobReporter] Running merge report on ${outputDir}`);
13
+ try {
14
+ (0, child_process_1.execFileSync)("npx", ["playwright", "merge-reports", outputDir, "--reporter", "html,json"], {
15
+ cwd: currentWorkingDir,
16
+ env: {
17
+ ...process.env,
18
+ PLAYWRIGHT_HTML_OPEN: "never",
19
+ PLAYWRIGHT_HTML_OUTPUT_DIR: htmlOutputDir,
20
+ PLAYWRIGHT_JSON_OUTPUT_NAME: summaryJsonPath,
21
+ },
22
+ stdio: "inherit",
23
+ });
24
+ console.log(`[IncrementalBlobReporter] Merge report completed. HTML: ${htmlOutputDir}, JSON: ${summaryJsonPath}`);
25
+ }
26
+ catch (err) {
27
+ console.error(`[IncrementalBlobReporter] Merge report failed:`, err);
28
+ }
29
+ }
@@ -0,0 +1,3 @@
1
+ export declare function isFinalized(): boolean;
2
+ export declare function setFinalized(): void;
3
+ //# sourceMappingURL=reporter-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter-state.d.ts","sourceRoot":"","sources":["../../src/reporter/reporter-state.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFinalized = isFinalized;
4
+ exports.setFinalized = setFinalized;
5
+ let _finalized = false;
6
+ function isFinalized() {
7
+ return _finalized;
8
+ }
9
+ function setFinalized() {
10
+ _finalized = true;
11
+ }
@@ -23,5 +23,5 @@ export declare class Uploader {
23
23
  uploadDirectory(sourceDir: string, destinationPrefix: string): Promise<void>;
24
24
  waitForUploads(): Promise<void>;
25
25
  }
26
- export declare function createUploader(): Uploader | null;
26
+ export declare function getUploader(): Uploader | null;
27
27
  //# sourceMappingURL=uploader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../src/reporter/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAGnB,MAAM,2BAA2B,CAAC;AAKnC,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,YAAY,CAAqB;gBAE7B,MAAM,EAAE,cAAc;IAWlC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgBhC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAUhC,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI;IAO1E,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAEK,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA6BnB,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC;IAiBV,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAGtC;AAED,wBAAgB,cAAc,IAAI,QAAQ,GAAG,IAAI,CAoDhD"}
1
+ {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../src/reporter/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAGnB,MAAM,2BAA2B,CAAC;AAKnC,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,YAAY,CAAqB;gBAE7B,MAAM,EAAE,cAAc;IAWlC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgBhC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAUhC,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI;IAO1E,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAEK,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA6BnB,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC;IAiBV,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAGtC;AAID,wBAAgB,WAAW,IAAI,QAAQ,GAAG,IAAI,CAI7C"}
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Uploader = void 0;
7
- exports.createUploader = createUploader;
7
+ exports.getUploader = getUploader;
8
8
  const r2_uploader_1 = require("@empiricalrun/r2-uploader");
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const logger_1 = require("../logger");
@@ -100,6 +100,13 @@ class Uploader {
100
100
  }
101
101
  }
102
102
  exports.Uploader = Uploader;
103
+ let _uploaderInstance = null;
104
+ function getUploader() {
105
+ if (_uploaderInstance)
106
+ return _uploaderInstance;
107
+ _uploaderInstance = createUploader();
108
+ return _uploaderInstance;
109
+ }
103
110
  function createUploader() {
104
111
  if (process.argv.includes("--list")) {
105
112
  logger_1.logger.debug("[Uploader] Reporter disabled for --list command");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/playwright-utils",
3
- "version": "0.43.1",
3
+ "version": "0.45.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -43,11 +43,11 @@
43
43
  "puppeteer-extra-plugin-recaptcha": "^3.6.8",
44
44
  "rimraf": "^6.0.1",
45
45
  "ts-morph": "^23.0.0",
46
+ "@empiricalrun/dashboard-client": "^0.2.0",
47
+ "@empiricalrun/cua": "^0.3.0",
46
48
  "@empiricalrun/llm": "^0.26.0",
47
49
  "@empiricalrun/r2-uploader": "^0.9.1",
48
- "@empiricalrun/reporter": "^0.28.0",
49
- "@empiricalrun/cua": "^0.3.0",
50
- "@empiricalrun/dashboard-client": "^0.2.0"
50
+ "@empiricalrun/reporter": "^0.28.0"
51
51
  },
52
52
  "scripts": {
53
53
  "dev": "tsc --build --watch",
@@ -1 +1 @@
1
- {"root":["./src/email.ts","./src/index.ts","./src/kv.ts","./src/logger.ts","./src/mailosaur-client.ts","./src/playwright-extensions.ts","./src/postgres.ts","./src/telemetry.ts","./src/webhook.ts","./src/auth/google.ts","./src/auth/index.ts","./src/auth/types.ts","./src/captcha/index.ts","./src/config/index.ts","./src/config/proxy.ts","./src/config/devices/types.ts","./src/overlay-tests/cache.spec.ts","./src/overlay-tests/click.spec.ts","./src/overlay-tests/fixtures.ts","./src/overlay-tests/patch.spec.ts","./src/reporter/blob-utils.ts","./src/reporter/empirical-reporter.ts","./src/reporter/failing-line.ts","./src/reporter/incremental-blob-reporter.ts","./src/reporter/uploader.ts","./src/reporter/util.ts","./src/test/constants.ts","./src/test/coverage.ts","./src/test/index.ts","./src/test/types.ts","./src/test/video-labels.ts","./src/test/expect/index.ts","./src/test/expect/types.ts","./src/test/expect/visual.ts","./src/test/expect/webhook.ts","./src/test/scripts/agent-capabilities.ts","./src/test/scripts/index.ts","./src/test/scripts/locator-highlights.ts","./src/test/scripts/locator-vision.ts","./src/test/scripts/mouse-pointer.ts","./src/test/scripts/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/cache.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/prompt.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts","./src/test/scripts/pw-locator-patch/highlight/click.ts","./src/test/scripts/pw-locator-patch/highlight/expect.ts","./src/test/scripts/pw-locator-patch/highlight/hover.ts","./src/test/scripts/pw-locator-patch/highlight/inner-text.ts","./src/test/scripts/pw-locator-patch/highlight/input-value.ts","./src/test/scripts/pw-locator-patch/highlight/is-checked.ts","./src/test/scripts/pw-locator-patch/highlight/is-disabled.ts","./src/test/scripts/pw-locator-patch/highlight/is-editable.ts","./src/test/scripts/pw-locator-patch/highlight/text-content.ts","./src/test/scripts/pw-locator-patch/utils/index.ts","./src/test/scripts/pw-locator-patch/vision/query.ts"],"version":"5.8.3"}
1
+ {"root":["./src/email.ts","./src/index.ts","./src/kv.ts","./src/logger.ts","./src/mailosaur-client.ts","./src/playwright-extensions.ts","./src/postgres.ts","./src/telemetry.ts","./src/webhook.ts","./src/auth/google.ts","./src/auth/index.ts","./src/auth/types.ts","./src/captcha/index.ts","./src/config/index.ts","./src/config/proxy.ts","./src/config/devices/types.ts","./src/overlay-tests/cache.spec.ts","./src/overlay-tests/click.spec.ts","./src/overlay-tests/fixtures.ts","./src/overlay-tests/patch.spec.ts","./src/reporter/blob-utils.ts","./src/reporter/empirical-reporter.ts","./src/reporter/failing-line.ts","./src/reporter/incremental-blob-reporter.ts","./src/reporter/local-test.ts","./src/reporter/reporter-state.ts","./src/reporter/uploader.ts","./src/reporter/util.ts","./src/reporter/IBR-unit-test/example.spec.ts","./src/reporter/IBR-unit-test/playwright.config.ts","./src/test/constants.ts","./src/test/coverage.ts","./src/test/index.ts","./src/test/types.ts","./src/test/video-labels.ts","./src/test/expect/index.ts","./src/test/expect/types.ts","./src/test/expect/visual.ts","./src/test/expect/webhook.ts","./src/test/scripts/agent-capabilities.ts","./src/test/scripts/index.ts","./src/test/scripts/locator-highlights.ts","./src/test/scripts/locator-vision.ts","./src/test/scripts/mouse-pointer.ts","./src/test/scripts/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/cache.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/prompt.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/types.ts","./src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts","./src/test/scripts/pw-locator-patch/highlight/click.ts","./src/test/scripts/pw-locator-patch/highlight/expect.ts","./src/test/scripts/pw-locator-patch/highlight/hover.ts","./src/test/scripts/pw-locator-patch/highlight/inner-text.ts","./src/test/scripts/pw-locator-patch/highlight/input-value.ts","./src/test/scripts/pw-locator-patch/highlight/is-checked.ts","./src/test/scripts/pw-locator-patch/highlight/is-disabled.ts","./src/test/scripts/pw-locator-patch/highlight/is-editable.ts","./src/test/scripts/pw-locator-patch/highlight/text-content.ts","./src/test/scripts/pw-locator-patch/utils/index.ts","./src/test/scripts/pw-locator-patch/vision/query.ts"],"version":"5.8.3"}