@empiricalrun/playwright-utils 0.62.1 → 0.63.1

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.
Files changed (136) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/api-worker-client.d.ts +0 -13
  3. package/dist/api-worker-client.d.ts.map +1 -1
  4. package/dist/api-worker-client.js +0 -15
  5. package/dist/auth/google.d.ts.map +1 -1
  6. package/dist/auth/google.js +0 -1
  7. package/dist/auth/index.d.ts.map +1 -1
  8. package/dist/auth/index.js +0 -9
  9. package/dist/config/index.d.ts.map +1 -1
  10. package/dist/config/index.js +0 -8
  11. package/dist/generated/api-worker-openapi.d.ts +3031 -1420
  12. package/dist/generated/api-worker-openapi.d.ts.map +1 -1
  13. package/dist/overlay-tests/cache.spec.js +31 -17
  14. package/dist/overlay-tests/click.spec.js +2 -25
  15. package/dist/overlay-tests/dismiss-mechanics.spec.d.ts +2 -0
  16. package/dist/overlay-tests/dismiss-mechanics.spec.d.ts.map +1 -0
  17. package/dist/overlay-tests/dismiss-mechanics.spec.js +59 -0
  18. package/dist/overlay-tests/dropdown.spec.d.ts +2 -0
  19. package/dist/overlay-tests/dropdown.spec.d.ts.map +1 -0
  20. package/dist/overlay-tests/dropdown.spec.js +53 -0
  21. package/dist/overlay-tests/fixtures.d.ts +3 -1
  22. package/dist/overlay-tests/fixtures.d.ts.map +1 -1
  23. package/dist/overlay-tests/fixtures.js +15 -0
  24. package/dist/overlay-tests/typesafe-hit-check.spec.d.ts +2 -0
  25. package/dist/overlay-tests/typesafe-hit-check.spec.d.ts.map +1 -0
  26. package/dist/overlay-tests/typesafe-hit-check.spec.js +57 -0
  27. package/dist/overlay-tests/typesafe.spec.d.ts +2 -0
  28. package/dist/overlay-tests/typesafe.spec.d.ts.map +1 -0
  29. package/dist/overlay-tests/typesafe.spec.js +86 -0
  30. package/dist/playwright-extensions.d.ts.map +1 -1
  31. package/dist/playwright-extensions.js +0 -1
  32. package/dist/reporter/attachment-cleanup-test-reporter.d.ts +0 -6
  33. package/dist/reporter/attachment-cleanup-test-reporter.d.ts.map +1 -1
  34. package/dist/reporter/attachment-cleanup-test-reporter.js +0 -6
  35. package/dist/reporter/attachment-cleanup.d.ts +0 -33
  36. package/dist/reporter/attachment-cleanup.d.ts.map +1 -1
  37. package/dist/reporter/attachment-cleanup.js +2 -51
  38. package/dist/reporter/empirical-reporter.d.ts.map +1 -1
  39. package/dist/reporter/empirical-reporter.js +0 -9
  40. package/dist/reporter/harness.d.ts +0 -62
  41. package/dist/reporter/harness.d.ts.map +1 -1
  42. package/dist/reporter/harness.js +1 -53
  43. package/dist/reporter/ibr-utils.d.ts +0 -5
  44. package/dist/reporter/ibr-utils.d.ts.map +1 -1
  45. package/dist/reporter/ibr-utils.js +0 -5
  46. package/dist/reporter/incremental-blob-reporter.d.ts +0 -17
  47. package/dist/reporter/incremental-blob-reporter.d.ts.map +1 -1
  48. package/dist/reporter/incremental-blob-reporter.js +5 -35
  49. package/dist/reporter/lifecycle-events.d.ts.map +1 -1
  50. package/dist/reporter/lifecycle-events.js +0 -9
  51. package/dist/reporter/parity-utils.d.ts +0 -30
  52. package/dist/reporter/parity-utils.d.ts.map +1 -1
  53. package/dist/reporter/parity-utils.js +4 -28
  54. package/dist/reporter/reporter-state.d.ts +0 -12
  55. package/dist/reporter/reporter-state.d.ts.map +1 -1
  56. package/dist/reporter/reporter-state.js +0 -12
  57. package/dist/reporter/test-case-sync.d.ts.map +1 -1
  58. package/dist/reporter/test-case-sync.js +0 -12
  59. package/dist/reporter/uploader.d.ts.map +1 -1
  60. package/dist/reporter/uploader.js +0 -6
  61. package/dist/reporter/util.d.ts +0 -33
  62. package/dist/reporter/util.d.ts.map +1 -1
  63. package/dist/reporter/util.js +0 -37
  64. package/dist/telemetry.d.ts.map +1 -1
  65. package/dist/telemetry.js +1 -10
  66. package/dist/test/coverage.d.ts.map +1 -1
  67. package/dist/test/coverage.js +1 -3
  68. package/dist/test/expect/visual.d.ts.map +1 -1
  69. package/dist/test/expect/visual.js +1 -9
  70. package/dist/test/index.d.ts.map +1 -1
  71. package/dist/test/index.js +4 -21
  72. package/dist/test/scripts/agent-capabilities.js +2 -2
  73. package/dist/test/scripts/index.d.ts +2 -2
  74. package/dist/test/scripts/index.d.ts.map +1 -1
  75. package/dist/test/scripts/index.js +3 -16
  76. package/dist/test/scripts/pw-locator-patch/actions/click.d.ts.map +1 -0
  77. package/dist/test/scripts/pw-locator-patch/{highlight → actions}/click.js +8 -6
  78. package/dist/test/scripts/pw-locator-patch/actions/hover.d.ts.map +1 -0
  79. package/dist/test/scripts/pw-locator-patch/{highlight → actions}/hover.js +0 -3
  80. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/cache.d.ts +1 -1
  81. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/cache.d.ts.map +1 -1
  82. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/cache.js +9 -13
  83. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.d.ts +3 -0
  84. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.d.ts.map +1 -1
  85. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.js +14 -12
  86. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/prompt.d.ts.map +1 -1
  87. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/prompt.js +0 -1
  88. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/typesafe.d.ts +38 -0
  89. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/typesafe.d.ts.map +1 -0
  90. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/typesafe.js +159 -0
  91. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.d.ts +3 -0
  92. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.d.ts.map +1 -1
  93. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.js +13 -5
  94. package/dist/test/scripts/pw-locator-patch/utils/index.d.ts +0 -1
  95. package/dist/test/scripts/pw-locator-patch/utils/index.d.ts.map +1 -1
  96. package/dist/test/scripts/pw-locator-patch/utils/index.js +0 -18
  97. package/dist/test/types.d.ts +2 -5
  98. package/dist/test/types.d.ts.map +1 -1
  99. package/dist/test/video-labels.d.ts.map +1 -1
  100. package/dist/test/video-labels.js +0 -1
  101. package/dist/webhook.d.ts.map +1 -1
  102. package/dist/webhook.js +0 -3
  103. package/docs/fixtures.md +4 -5
  104. package/package.json +6 -6
  105. package/playwright.config.ts +0 -4
  106. package/tsconfig.tsbuildinfo +1 -1
  107. package/upstream-oracle/ibr-adapter.js +0 -23
  108. package/upstream-oracle/run.mjs +1 -69
  109. package/dist/test/scripts/locator-highlights.d.ts +0 -4
  110. package/dist/test/scripts/locator-highlights.d.ts.map +0 -1
  111. package/dist/test/scripts/locator-highlights.js +0 -28
  112. package/dist/test/scripts/pw-locator-patch/highlight/click.d.ts.map +0 -1
  113. package/dist/test/scripts/pw-locator-patch/highlight/expect.d.ts +0 -5
  114. package/dist/test/scripts/pw-locator-patch/highlight/expect.d.ts.map +0 -1
  115. package/dist/test/scripts/pw-locator-patch/highlight/expect.js +0 -23
  116. package/dist/test/scripts/pw-locator-patch/highlight/hover.d.ts.map +0 -1
  117. package/dist/test/scripts/pw-locator-patch/highlight/inner-text.d.ts +0 -6
  118. package/dist/test/scripts/pw-locator-patch/highlight/inner-text.d.ts.map +0 -1
  119. package/dist/test/scripts/pw-locator-patch/highlight/inner-text.js +0 -30
  120. package/dist/test/scripts/pw-locator-patch/highlight/input-value.d.ts +0 -6
  121. package/dist/test/scripts/pw-locator-patch/highlight/input-value.d.ts.map +0 -1
  122. package/dist/test/scripts/pw-locator-patch/highlight/input-value.js +0 -30
  123. package/dist/test/scripts/pw-locator-patch/highlight/is-checked.d.ts +0 -6
  124. package/dist/test/scripts/pw-locator-patch/highlight/is-checked.d.ts.map +0 -1
  125. package/dist/test/scripts/pw-locator-patch/highlight/is-checked.js +0 -30
  126. package/dist/test/scripts/pw-locator-patch/highlight/is-disabled.d.ts +0 -6
  127. package/dist/test/scripts/pw-locator-patch/highlight/is-disabled.d.ts.map +0 -1
  128. package/dist/test/scripts/pw-locator-patch/highlight/is-disabled.js +0 -30
  129. package/dist/test/scripts/pw-locator-patch/highlight/is-editable.d.ts +0 -6
  130. package/dist/test/scripts/pw-locator-patch/highlight/is-editable.d.ts.map +0 -1
  131. package/dist/test/scripts/pw-locator-patch/highlight/is-editable.js +0 -29
  132. package/dist/test/scripts/pw-locator-patch/highlight/text-content.d.ts +0 -6
  133. package/dist/test/scripts/pw-locator-patch/highlight/text-content.d.ts.map +0 -1
  134. package/dist/test/scripts/pw-locator-patch/highlight/text-content.js +0 -30
  135. /package/dist/test/scripts/pw-locator-patch/{highlight → actions}/click.d.ts +0 -0
  136. /package/dist/test/scripts/pw-locator-patch/{highlight → actions}/hover.d.ts +0 -0
@@ -16,7 +16,7 @@ function getDefaultDiskLimitBytes() {
16
16
  }
17
17
  logger_1.logger.warn(`[AttachmentCleanup] Invalid ATTACHMENT_CLEANUP_LIMIT_BYTES=${raw}, using default`);
18
18
  }
19
- return 10 * 1024 * 1024 * 1024; // 10 GB
19
+ return 10 * 1024 * 1024 * 1024;
20
20
  }
21
21
  const DISK_LOG_INTERVAL_MS = 30_000;
22
22
  function formatBytes(bytes) {
@@ -39,12 +39,9 @@ function getDiskUsage() {
39
39
  return "unavailable";
40
40
  }
41
41
  }
42
- // Where the test-run worker checks out the test repo.
43
42
  const WORKER_REPO_DIR = "/app/source-repo";
44
43
  function getDiskBreakdown() {
45
44
  try {
46
- // /tmp also holds browser profiles and download dirs that no attachment
47
- // accounts for, so it is listed whole alongside its artifact dirs.
48
45
  const output = (0, child_process_1.execSync)("du -sh test-results/.playwright-artifacts-* test-results/ blob-report/ blob-report-incremental/ playwright-report/ /tmp/playwright-artifacts-* /tmp 2>/dev/null | sort -rh", { encoding: "utf8", timeout: 8000, cwd: WORKER_REPO_DIR }).trim();
49
46
  if (!output) {
50
47
  return "none";
@@ -58,31 +55,6 @@ function getDiskBreakdown() {
58
55
  return "none";
59
56
  }
60
57
  }
61
- /**
62
- * Tracks test attachments and evicts the oldest uploaded ones from disk
63
- * when total size exceeds the configured limit.
64
- *
65
- * Two-phase tracking:
66
- * 1. register() — called immediately when an attachment is created.
67
- * Adds the file to the total size accounting so the LRU knows about
68
- * all disk usage, even while uploads are still queued.
69
- * 2. markUploaded() — called after the file is uploaded to R2.
70
- * Marks the file as safe to evict (delete from disk).
71
- *
72
- * Eviction only deletes files that have been uploaded. This ensures we
73
- * never delete a file before its upload completes.
74
- *
75
- * Why this exists:
76
- * Test attachments (videos, traces, screenshots) accumulate on disk during a
77
- * test run. On Fargate workers with 50 GB ephemeral storage, large test suites
78
- * can exhaust disk space. Since attachments are already uploaded to R2, we can
79
- * safely delete them from disk — but we can't delete them immediately because
80
- * Playwright's blob reporter reads them during onEnd to embed as resources/.
81
- *
82
- * The blob reporter's statSync guard (Playwright 1.57+) gracefully skips
83
- * missing files, and patchBlobZip replaces resources/ with
84
- * _empirical_urls.json pointing to R2 URLs anyway.
85
- */
86
58
  class AttachmentCleanup {
87
59
  _pending = new Map();
88
60
  _uploaded = [];
@@ -97,19 +69,11 @@ class AttachmentCleanup {
97
69
  _onEvict = null;
98
70
  constructor(limitBytes = getDefaultDiskLimitBytes()) {
99
71
  this._limitBytes = limitBytes;
100
- // logger.debug(
101
- // `[AttachmentCleanup] Initialized with limit: ${formatBytes(limitBytes)}`,
102
- // );
103
72
  this._diskLogTimer = setInterval(() => {
104
73
  this._logDiskStatus();
105
74
  }, DISK_LOG_INTERVAL_MS);
106
- // Don't keep the process alive just for this timer
107
75
  this._diskLogTimer.unref();
108
76
  }
109
- /**
110
- * Phase 1: Register an attachment immediately when it's created.
111
- * Adds to total size accounting and attempts eviction of already-uploaded files.
112
- */
113
77
  register(attachment) {
114
78
  try {
115
79
  if (!attachment.path) {
@@ -125,14 +89,8 @@ class AttachmentCleanup {
125
89
  this._registeredCount++;
126
90
  this._evict();
127
91
  }
128
- catch {
129
- // Ignore errors (file may not exist)
130
- }
92
+ catch { }
131
93
  }
132
- /**
133
- * Phase 2: Mark an attachment as uploaded (safe to evict).
134
- * Moves from pending to the uploaded queue and attempts eviction.
135
- */
136
94
  markUploaded(attachmentPath) {
137
95
  const size = this._pending.get(attachmentPath);
138
96
  if (size === undefined) {
@@ -170,19 +128,12 @@ class AttachmentCleanup {
170
128
  }
171
129
  _logDiskStatus() {
172
130
  this._diskLogTick++;
173
- // const artifactsSuffix =
174
- // this._diskLogTick % 15 === 0 ? `, breakdown=${getDiskBreakdown()}` : "";
175
- // logger.info(
176
- // `[AttachmentCleanup] Periodic: registered=${this._registeredCount}, pending=${this._pending.size}, uploaded=${this._uploadedCount}, evicted=${this._evictedCount} (${formatBytes(this._evictedBytes)}), totalSize=${formatBytes(this._totalSize)}, limit=${formatBytes(this._limitBytes)}, disk=${getDiskUsage()}${artifactsSuffix}`,
177
- // );
178
131
  }
179
132
  logSummary() {
180
133
  if (this._diskLogTimer) {
181
134
  clearInterval(this._diskLogTimer);
182
135
  this._diskLogTimer = null;
183
136
  }
184
- // One line per run, only on the worker: the only record of what filled the
185
- // disk when a run hits ENOSPC. Local runs stay quiet.
186
137
  if (!fs_1.default.existsSync(WORKER_REPO_DIR)) {
187
138
  return;
188
139
  }
@@ -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,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAuBnC,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;IAC1C,OAAO,CAAC,kBAAkB,CAA2B;IAGrD,OAAO,CAAC,YAAY,CAAqB;IAEzC,cAEC;IAED,OAAO,CAAC,MAAM,EAAE,UAAU,QAEzB;IAED,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,6BAA6B,CA2CnC;IAEF,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,QAoJ3C;IAEK,KAAK,CAAC,MAAM,EAAE,UAAU,iBAoH7B;IAED,OAAO,CAAC,qBAAqB;YAkBf,gBAAgB;YAOhB,iBAAiB;CAqChC;eAEc,iBAAiB"}
1
+ {"version":3,"file":"empirical-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/empirical-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAuBnC,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;IAC1C,OAAO,CAAC,kBAAkB,CAA2B;IACrD,OAAO,CAAC,YAAY,CAAqB;IAEzC,cAEC;IAED,OAAO,CAAC,MAAM,EAAE,UAAU,QAEzB;IAED,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,6BAA6B,CA2CnC;IAEF,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,QA+I3C;IAEK,KAAK,CAAC,MAAM,EAAE,UAAU,iBAkH7B;IAED,OAAO,CAAC,qBAAqB;YAkBf,gBAAgB;YAOhB,iBAAiB;CAqChC;eAEc,iBAAiB"}
@@ -23,8 +23,6 @@ class EmpiricalReporter {
23
23
  _testRetryCounts = new Map();
24
24
  _uploader = null;
25
25
  _attachmentCleanup = new attachment_cleanup_1.AttachmentCleanup();
26
- // Resolved Playwright maxFailures (0 = no cap), sent on every run-end event
27
- // so the server-side early-end enforces the client's configured cap.
28
26
  _maxFailures;
29
27
  constructor() {
30
28
  this._uploader = (0, uploader_1.getUploader)();
@@ -62,11 +60,6 @@ class EmpiricalReporter {
62
60
  }
63
61
  };
64
62
  onTestEnd(test, result) {
65
- // After the SIGINT salvage, an attempt that really finished (its body
66
- // completed, only its teardown overlapped the signal) is still reported:
67
- // the blob keeps it, and a ledger that misses it calls the test unfinished,
68
- // so the resume shard re-runs it and the merged report holds it twice.
69
- // Shutdown artifacts stay out, as they do in the blob.
70
63
  if ((0, reporter_state_1.isFinalized)() && (0, reporter_state_1.isShutdownArtifact)(result.status, true)) {
71
64
  return;
72
65
  }
@@ -186,8 +179,6 @@ class EmpiricalReporter {
186
179
  }
187
180
  async onEnd(result) {
188
181
  if ((0, reporter_state_1.isFinalized)()) {
189
- // The salvage owns the report upload. Only flush the test-case events
190
- // sent during shutdown, so they land before the process exits.
191
182
  await Promise.allSettled(this._pendingTestCaseEvents);
192
183
  return;
193
184
  }
@@ -8,10 +8,6 @@ export interface TestCaseSyncTestContext {
8
8
  outputPath: string;
9
9
  }
10
10
  export declare function sleep(ms: number): Promise<void>;
11
- /**
12
- * Sets up a temp directory with the IBR fixture files.
13
- * Returns a context object and a cleanup function.
14
- */
15
11
  export declare function setupFixture(suite: string): Promise<{
16
12
  ctx: IBRTestContext;
17
13
  cleanup: () => Promise<void>;
@@ -20,16 +16,12 @@ export declare function setupTestCaseSyncFixture(suite: string): Promise<{
20
16
  ctx: TestCaseSyncTestContext;
21
17
  cleanup: () => Promise<void>;
22
18
  }>;
23
- /**
24
- * Cleans blob artifacts from a previous run inside the same temp dir.
25
- */
26
19
  export declare function cleanBlobArtifacts(ctx: IBRTestContext): Promise<void>;
27
20
  export interface RunResult {
28
21
  stdout: string;
29
22
  stderr: string;
30
23
  }
31
24
  export type WaitFor = "first-passed" | "first-failed";
32
- /** A `@@ NAME @@` line printed by a fixture suite, with its offset from run start. */
33
25
  export interface Marker {
34
26
  name: string;
35
27
  atMs: number;
@@ -38,79 +30,40 @@ export interface SignalRunResult extends RunResult {
38
30
  exitCode: number | null;
39
31
  exitSignal: NodeJS.Signals | null;
40
32
  markers: Marker[];
41
- /** Offset from run start at which the first signal was delivered. */
42
33
  signalSentAtMs: number;
43
- /** Wall clock at run start, so `atMs` offsets can be compared to file mtimes. */
44
34
  startedAtEpochMs: number;
45
35
  }
46
36
  export interface SignalRunOptions {
47
37
  workers: number;
48
- /**
49
- * Signal as soon as this `@@ MARKER @@` is printed. Preferred over `waitFor`:
50
- * it pins the signal to a known point in the run instead of a sleep.
51
- */
52
38
  waitForMarker?: string;
53
- /** Legacy trigger: wait for the first pass/fail line in stdout. */
54
39
  waitFor?: WaitFor;
55
- /** Settling delay between the trigger and the signal. */
56
40
  delayBeforeSignalMs?: number;
57
- /** Defaults to SIGINT, which is what production sends. */
58
41
  signal?: NodeJS.Signals;
59
- /** Send the same signal again this long after the first one. */
60
42
  secondSignalAfterMs?: number;
61
- /** SIGKILL the group this long after the first signal, like the cmd.ts grace cap. */
62
43
  killAfterMs?: number;
63
- /** How long to wait for the trigger before giving up and signalling anyway. */
64
44
  triggerTimeoutMs?: number;
65
- /** Extra env for the runner, e.g. from `startDashboardStub`. */
66
45
  env?: NodeJS.ProcessEnv;
67
46
  }
68
- /**
69
- * Spawns `playwright test` with the IBR reporter in its own process group,
70
- * signals the group mid-run, and waits for exit.
71
- *
72
- * The process group and the signal both match production: `cmd.ts` spawns the
73
- * runner detached and does `process.kill(-pid, signal)`.
74
- */
75
47
  export declare function runPlaywrightWithSignal(ctx: IBRTestContext, opts: SignalRunOptions): Promise<SignalRunResult>;
76
- /**
77
- * Spawns `playwright test` with the IBR reporter, waits for a test outcome,
78
- * sends SIGINT, and waits for the process to exit.
79
- *
80
- * Returns captured stdout/stderr.
81
- */
82
48
  export declare function runPlaywrightWithSigint(ctx: IBRTestContext, opts: {
83
49
  workers: number;
84
50
  waitFor: WaitFor;
85
51
  }): Promise<RunResult>;
86
- /** Marker names in the order they were printed. */
87
52
  export declare function markerNames(result: SignalRunResult): string[];
88
53
  export declare function runPlaywrightList(ctx: TestCaseSyncTestContext): Promise<RunResult>;
89
54
  export interface BlobEvent {
90
55
  method: string;
91
56
  params?: Record<string, unknown>;
92
57
  }
93
- /**
94
- * Reads `report.jsonl` from the blob zip and returns parsed events.
95
- */
96
58
  export declare function readBlobEvents(ctx: IBRTestContext): Promise<BlobEvent[]>;
97
- /**
98
- * Reads `report.jsonl` from any blob-format zip (standard or incremental).
99
- */
100
59
  export declare function readEventsFromZip(zipPath: string): Promise<BlobEvent[]>;
101
60
  export interface ParityTestContext {
102
61
  tempDir: string;
103
- /** Playwright's built-in blob reporter output: blob-report/report-1.zip */
104
62
  standardZipPath: string;
105
63
  standardBlobDir: string;
106
- /** IBR output: blob-report-incremental/incremental-report-1.zip */
107
64
  incrementalZipPath: string;
108
65
  incrementalBlobDir: string;
109
66
  }
110
- /**
111
- * Sets up a fixture whose config runs BOTH the built-in blob reporter and the
112
- * IBR on the same invocation, so one event stream feeds both zips.
113
- */
114
67
  export declare function setupParityFixture(suite: string): Promise<{
115
68
  ctx: ParityTestContext;
116
69
  cleanup: () => Promise<void>;
@@ -118,10 +71,6 @@ export declare function setupParityFixture(suite: string): Promise<{
118
71
  export interface CleanRunResult extends RunResult {
119
72
  exitCode: number | null;
120
73
  }
121
- /**
122
- * Spawns `playwright test` and lets it run to completion — the clean-finish
123
- * half of the matrix (the SIGINT helpers above cover interruption).
124
- */
125
74
  export declare function runPlaywrightClean(ctx: ParityTestContext, opts: {
126
75
  workers: number;
127
76
  shard?: {
@@ -129,22 +78,11 @@ export declare function runPlaywrightClean(ctx: ParityTestContext, opts: {
129
78
  total: number;
130
79
  };
131
80
  }): Promise<CleanRunResult>;
132
- /**
133
- * Runs `playwright merge-reports <blobDir> --reporter json` and returns the
134
- * parsed summary. Distinct output names let one temp dir hold both merges.
135
- */
136
81
  export declare function mergeBlobDirToSummary(cwd: string, blobDir: string, outputName: string): Record<string, unknown>;
137
82
  export interface DashboardStub {
138
- /** `test_case_run_end` payloads EmpiricalReporter sent, in arrival order. */
139
83
  testCaseEvents: () => Array<Record<string, any>>;
140
- /** Runner env that points EmpiricalReporter's API calls and uploads here. */
141
84
  env: NodeJS.ProcessEnv;
142
85
  close: () => Promise<void>;
143
86
  }
144
- /**
145
- * A local stand-in for api-worker and the report bucket, so EmpiricalReporter
146
- * runs unmodified inside a real Playwright run. Records test-case events and
147
- * accepts every upload.
148
- */
149
87
  export declare function startDashboardStub(): Promise<DashboardStub>;
150
88
  //# sourceMappingURL=harness.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../src/reporter/harness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../src/reporter/harness.ts"],"names":[],"mappings":"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"}
@@ -31,10 +31,6 @@ const PLAYWRIGHT_BIN = path_1.default.resolve(__dirname, "../../node_modules/.bi
31
31
  async function sleep(ms) {
32
32
  return new Promise((resolve) => setTimeout(resolve, ms));
33
33
  }
34
- /**
35
- * Sets up a temp directory with the IBR fixture files.
36
- * Returns a context object and a cleanup function.
37
- */
38
34
  async function setupFixture(suite) {
39
35
  const { tempDir, cleanup } = await setupReporterFixture({
40
36
  suite,
@@ -58,7 +54,6 @@ async function setupReporterFixture({ suite, reporterPath, tempPrefix, }) {
58
54
  const src = path_1.default.join(fixtureDir, entry.name);
59
55
  const dest = path_1.default.join(tempDir, entry.name);
60
56
  if (entry.isDirectory()) {
61
- // Fixtures that put specs under a testDir subdir.
62
57
  await fs_1.default.promises.cp(src, dest, { recursive: true });
63
58
  }
64
59
  else if (entry.name === "playwright.config.ts") {
@@ -90,9 +85,6 @@ async function setupTestCaseSyncFixture(suite) {
90
85
  cleanup,
91
86
  };
92
87
  }
93
- /**
94
- * Cleans blob artifacts from a previous run inside the same temp dir.
95
- */
96
88
  async function cleanBlobArtifacts(ctx) {
97
89
  if (fs_1.default.existsSync(ctx.blobDir)) {
98
90
  await fs_1.default.promises.rm(ctx.blobDir, { recursive: true, force: true });
@@ -103,13 +95,6 @@ const WAIT_FOR_PATTERNS = {
103
95
  "first-failed": /failed|✘|×/,
104
96
  };
105
97
  const MARKER_RE = /@@ ([A-Z0-9-]+) @@/g;
106
- /**
107
- * Spawns `playwright test` with the IBR reporter in its own process group,
108
- * signals the group mid-run, and waits for exit.
109
- *
110
- * The process group and the signal both match production: `cmd.ts` spawns the
111
- * runner detached and does `process.kill(-pid, signal)`.
112
- */
113
98
  async function runPlaywrightWithSignal(ctx, opts) {
114
99
  const { workers, waitForMarker, waitFor, delayBeforeSignalMs = 0, signal = "SIGINT", secondSignalAfterMs, killAfterMs, triggerTimeoutMs = 30_000, env, } = opts;
115
100
  const startedAt = Date.now();
@@ -162,9 +147,7 @@ async function runPlaywrightWithSignal(ctx, opts) {
162
147
  try {
163
148
  process.kill(-child.pid, sig);
164
149
  }
165
- catch {
166
- // The group is already gone.
167
- }
150
+ catch { }
168
151
  };
169
152
  const pattern = waitFor ? WAIT_FOR_PATTERNS[waitFor] : undefined;
170
153
  const isTriggered = () => waitForMarker
@@ -199,7 +182,6 @@ async function runPlaywrightWithSignal(ctx, opts) {
199
182
  if (killAfterMs !== undefined) {
200
183
  timers.push(setTimeout(() => signalGroup("SIGKILL"), killAfterMs));
201
184
  }
202
- // Backstop: never leave a runner behind if the suite misbehaves.
203
185
  timers.push(setTimeout(() => signalGroup("SIGKILL"), 120_000));
204
186
  try {
205
187
  await closed;
@@ -219,21 +201,13 @@ async function runPlaywrightWithSignal(ctx, opts) {
219
201
  startedAtEpochMs: startedAt,
220
202
  };
221
203
  }
222
- /**
223
- * Spawns `playwright test` with the IBR reporter, waits for a test outcome,
224
- * sends SIGINT, and waits for the process to exit.
225
- *
226
- * Returns captured stdout/stderr.
227
- */
228
204
  async function runPlaywrightWithSigint(ctx, opts) {
229
205
  return runPlaywrightWithSignal(ctx, {
230
206
  workers: opts.workers,
231
207
  waitFor: opts.waitFor,
232
- // Waiting for 1 sec to ensure second test has started
233
208
  delayBeforeSignalMs: 1_000,
234
209
  });
235
210
  }
236
- /** Marker names in the order they were printed. */
237
211
  function markerNames(result) {
238
212
  return result.markers.map((m) => m.name);
239
213
  }
@@ -262,15 +236,9 @@ async function runPlaywrightList(ctx) {
262
236
  }
263
237
  return { stdout, stderr };
264
238
  }
265
- /**
266
- * Reads `report.jsonl` from the blob zip and returns parsed events.
267
- */
268
239
  async function readBlobEvents(ctx) {
269
240
  return readEventsFromZip(ctx.zipPath);
270
241
  }
271
- /**
272
- * Reads `report.jsonl` from any blob-format zip (standard or incremental).
273
- */
274
242
  async function readEventsFromZip(zipPath) {
275
243
  const reportBuffer = await (0, zip_1.readZipEntry)(zipPath, "report.jsonl");
276
244
  if (!reportBuffer) {
@@ -282,10 +250,6 @@ async function readEventsFromZip(zipPath) {
282
250
  .split("\n")
283
251
  .map((line) => JSON.parse(line));
284
252
  }
285
- /**
286
- * Sets up a fixture whose config runs BOTH the built-in blob reporter and the
287
- * IBR on the same invocation, so one event stream feeds both zips.
288
- */
289
253
  async function setupParityFixture(suite) {
290
254
  const { tempDir, cleanup } = await setupReporterFixture({
291
255
  suite,
@@ -305,10 +269,6 @@ async function setupParityFixture(suite) {
305
269
  cleanup,
306
270
  };
307
271
  }
308
- /**
309
- * Spawns `playwright test` and lets it run to completion — the clean-finish
310
- * half of the matrix (the SIGINT helpers above cover interruption).
311
- */
312
272
  async function runPlaywrightClean(ctx, opts) {
313
273
  const args = ["test", `--workers=${opts.workers}`];
314
274
  if (opts.shard) {
@@ -319,8 +279,6 @@ async function runPlaywrightClean(ctx, opts) {
319
279
  env: {
320
280
  ...process.env,
321
281
  LOCAL_TEST: "false",
322
- // With --shard, the env vars are cleared on purpose so IBR falls back to
323
- // the same config.shard the built-in blob reporter sees.
324
282
  SHARD_INDEX: opts.shard ? undefined : "1",
325
283
  TOTAL_SHARDS: opts.shard ? undefined : "1",
326
284
  FORCE_COLOR: "0",
@@ -340,10 +298,6 @@ async function runPlaywrightClean(ctx, opts) {
340
298
  });
341
299
  return { stdout, stderr, exitCode };
342
300
  }
343
- /**
344
- * Runs `playwright merge-reports <blobDir> --reporter json` and returns the
345
- * parsed summary. Distinct output names let one temp dir hold both merges.
346
- */
347
301
  function mergeBlobDirToSummary(cwd, blobDir, outputName) {
348
302
  const outputPath = path_1.default.join(cwd, outputName);
349
303
  (0, child_process_1.execFileSync)(PLAYWRIGHT_BIN, ["merge-reports", blobDir, "--reporter", "json"], {
@@ -357,11 +311,6 @@ function mergeBlobDirToSummary(cwd, blobDir, outputName) {
357
311
  });
358
312
  return JSON.parse(fs_1.default.readFileSync(outputPath, "utf8"));
359
313
  }
360
- /**
361
- * A local stand-in for api-worker and the report bucket, so EmpiricalReporter
362
- * runs unmodified inside a real Playwright run. Records test-case events and
363
- * accepts every upload.
364
- */
365
314
  async function startDashboardStub() {
366
315
  const events = [];
367
316
  const server = http_1.default.createServer((req, res) => {
@@ -379,7 +328,6 @@ async function startDashboardStub() {
379
328
  res.end("{}");
380
329
  return;
381
330
  }
382
- // Everything else is the S3 client; r2-uploader always goes multipart.
383
331
  res.writeHead(200, { "content-type": "application/xml", etag: '"etag"' });
384
332
  if (req.method === "POST" && req.url?.includes("?uploads")) {
385
333
  res.end("<InitiateMultipartUploadResult><UploadId>upload</UploadId></InitiateMultipartUploadResult>");
@@ -43,11 +43,6 @@ export declare function relativeLocation(location: JsonLocation | undefined, roo
43
43
  export declare function relativeAnnotationLocations(annotations: TestAnnotation[], rootDir: string): TestAnnotation[];
44
44
  export declare function serializeTest(test: TestCase, rootDir: string): JsonTestCase;
45
45
  export declare function serializeSuite(suite: Suite, rootDir: string): JsonSuite;
46
- /**
47
- * Recursively filters a serialized suite tree to only include tests
48
- * whose testId is in the completedTestIds set. Removes empty parent suites.
49
- * Returns null if the suite has no completed test descendants.
50
- */
51
46
  export declare function filterSuiteByCompletedTests(suite: JsonSuite, completedTestIds: Set<string>): JsonSuite | null;
52
47
  export declare function hasValidReport(reportLines: string[]): boolean;
53
48
  export declare function buildUrlsJson(attachmentUrlMap: Map<string, string>): Record<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"ibr-utils.d.ts","sourceRoot":"","sources":["../../src/reporter/ibr-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ibr-utils.d.ts","sourceRoot":"","sources":["../../src/reporter/ibr-utils.ts"],"names":[],"mappings":"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"}
@@ -108,11 +108,6 @@ function serializeSuite(suite, rootDir) {
108
108
  function isTestEntry(entry) {
109
109
  return "testId" in entry;
110
110
  }
111
- /**
112
- * Recursively filters a serialized suite tree to only include tests
113
- * whose testId is in the completedTestIds set. Removes empty parent suites.
114
- * Returns null if the suite has no completed test descendants.
115
- */
116
111
  function filterSuiteByCompletedTests(suite, completedTestIds) {
117
112
  const filteredEntries = [];
118
113
  for (const entry of suite.entries) {
@@ -1,12 +1,4 @@
1
1
  import type { FullConfig, FullResult, Reporter, Suite, TestCase, TestError, TestResult, TestStep, WorkerInfo } from "@playwright/test/reporter";
2
- /**
3
- * IncrementalBlobReporter
4
- *
5
- * This reporter builds a report.jsonl incrementally matching Playwright's blob format.
6
- * The zip can be uploaded for merge at any point (e.g., on SIGTERM).
7
- *
8
- * Format matches Playwright's blob reporter exactly.
9
- */
10
2
  export type AttachmentUrlMap = Map<string, string>;
11
3
  declare class IncrementalBlobReporter implements Reporter {
12
4
  private _currentWorkingDir;
@@ -33,12 +25,6 @@ declare class IncrementalBlobReporter implements Reporter {
33
25
  private _removeSignalHandler;
34
26
  private _buildSyntheticResult;
35
27
  private _finalizeAndMaybeUpload;
36
- /**
37
- * Computes the lines to write, without touching `_reportLines`: recording
38
- * continues after the SIGINT salvage, and the onEnd pass re-finalizes from
39
- * the full stream — mutating here would make the second pass work from the
40
- * first pass's pruned leftovers.
41
- */
42
28
  private _buildFinalReportLines;
43
29
  private _computeCompletedSets;
44
30
  private _removeIncompleteTestArtifacts;
@@ -60,9 +46,6 @@ declare class IncrementalBlobReporter implements Reporter {
60
46
  onStepBegin(test: TestCase, result: TestResult, step: TestStep): void;
61
47
  onStepEnd(test: TestCase, result: TestResult, step: TestStep): void;
62
48
  onEnd(result: FullResult): Promise<void>;
63
- /**
64
- * Add a single attachment URL mapping
65
- */
66
49
  addAttachmentUrl(localPath: string, remoteUrl: string): void;
67
50
  printsToStdio(): boolean;
68
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"incremental-blob-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/incremental-blob-reporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"incremental-blob-reporter.d.ts","sourceRoot":"","sources":["../../src/reporter/incremental-blob-reporter.ts"],"names":[],"mappings":"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"}
@@ -22,14 +22,14 @@ class IncrementalBlobReporter {
22
22
  _totalShards;
23
23
  _reportLines = [];
24
24
  _attachmentUrlMap = new Map();
25
- _resultIdMap = new Map(); // testId+retry -> resultId
26
- _stepIdMap = new Map(); // step -> stepId
27
- _knownAttachmentCounts = new Map(); // resultId -> attachments already sent
25
+ _resultIdMap = new Map();
26
+ _stepIdMap = new Map();
27
+ _knownAttachmentCounts = new Map();
28
28
  _uploader = null;
29
29
  _completedTestIds = new Set();
30
30
  _completedResultIds = new Set();
31
- _testRetries = new Map(); // testId → configured retries
32
- _testResults = new Map(); // testId → retryIndex → RecordedRetry
31
+ _testRetries = new Map();
32
+ _testResults = new Map();
33
33
  _startTime = Date.now();
34
34
  _finalizePromise = null;
35
35
  _rootDir = process.cwd();
@@ -99,7 +99,6 @@ class IncrementalBlobReporter {
99
99
  console.warn("[IncrementalBlobReporterFailure] No onBegin received, skipping upload (nothing to merge)");
100
100
  return;
101
101
  }
102
- // Wait for pending attachment uploads FIRST so URLs are available
103
102
  if (this._uploader) {
104
103
  await this._uploader.waitForUploads();
105
104
  }
@@ -127,33 +126,19 @@ class IncrementalBlobReporter {
127
126
  }
128
127
  logFinalizeComplete();
129
128
  }
130
- /**
131
- * Computes the lines to write, without touching `_reportLines`: recording
132
- * continues after the SIGINT salvage, and the onEnd pass re-finalizes from
133
- * the full stream — mutating here would make the second pass work from the
134
- * first pass's pruned leftovers.
135
- */
136
129
  _buildFinalReportLines(result, pruneIncompleteTests) {
137
130
  let lines = [...this._reportLines];
138
131
  if (pruneIncompleteTests) {
139
- // Determine which tests are fully complete (passed or all retries finished)
140
132
  this._computeCompletedSets();
141
- // Remove unrun tests from onProject suites
142
133
  lines = this._patchProjectSuites(lines);
143
- // Remove events (onTestBegin, onStepBegin, etc.) for incomplete tests
144
134
  lines = this._removeIncompleteTestArtifacts(lines);
145
135
  }
146
- // The onEnd event belongs only in the written report, never in the
147
- // in-memory stream — a later finalize pass appends its own.
148
136
  lines.push(JSON.stringify((0, lifecycle_events_1.buildOnEndEvent)(result)));
149
137
  return lines;
150
138
  }
151
139
  _computeCompletedSets() {
152
140
  for (const [testId, results] of this._testResults) {
153
141
  const maxRetries = this._testRetries.get(testId);
154
- // Shutdown artifacts are not finished retries. Counting them as
155
- // complete would put their results in the final zip alongside the
156
- // resume shard's, duplicating tests in the merge.
157
142
  const finished = new Map([...results].filter(([, r]) => !(0, reporter_state_1.isShutdownArtifact)(r.status, r.postSignal)));
158
143
  if ((0, reporter_1.areRetriesComplete)(maxRetries, finished)) {
159
144
  this._completedTestIds.add(testId);
@@ -222,13 +207,10 @@ class IncrementalBlobReporter {
222
207
  }
223
208
  async _writeZip(lines) {
224
209
  this._ensureDirs();
225
- // Write report.jsonl to the output directory
226
210
  const jsonlContent = lines.join("\n") + "\n";
227
211
  fs_1.default.writeFileSync(this._jsonlPath, jsonlContent, "utf8");
228
- // Write _empirical_urls.json with attachment URL mappings
229
212
  const urlsJson = (0, ibr_utils_1.buildUrlsJson)(this._attachmentUrlMap);
230
213
  fs_1.default.writeFileSync(this._urlsJsonPath, JSON.stringify(urlsJson, null, 2), "utf8");
231
- // Create zip from the staging directory
232
214
  const zipBuffer = await (0, zip_1.createZipFromDirectory)(this._stagingDir);
233
215
  fs_1.default.writeFileSync(this._zipPath, zipBuffer);
234
216
  console.log(`[IncrementalBlobReporter] Zip updated: ${this._zipPath} (${lines.length} events, ${this._attachmentUrlMap.size} attachments)`);
@@ -236,9 +218,6 @@ class IncrementalBlobReporter {
236
218
  onBegin(config, suite) {
237
219
  this._ensureDirs();
238
220
  this._rootDir = config.rootDir;
239
- // The env vars win (production sets them), but a sharded run without
240
- // them should still stamp the right shard into the blob metadata and
241
- // the zip name instead of defaulting every shard to 1/1.
242
221
  if (!process.env.SHARD_INDEX && config.shard) {
243
222
  this._shardIndex = config.shard.current;
244
223
  this._totalShards = config.shard.total;
@@ -264,8 +243,6 @@ class IncrementalBlobReporter {
264
243
  resultId,
265
244
  status: result.status,
266
245
  expectedStatus: test.expectedStatus,
267
- // The SIGINT salvage has started; this result arrived during
268
- // interruption shutdown rather than the normal run.
269
246
  postSignal: this._finalizePromise !== null,
270
247
  });
271
248
  }
@@ -288,10 +265,6 @@ class IncrementalBlobReporter {
288
265
  }
289
266
  async onEnd(result) {
290
267
  this._removeSignalHandler();
291
- // Second phase of an interrupted run: the SIGINT pass salvaged a snapshot
292
- // within milliseconds (SIGKILL insurance); by the time Playwright calls
293
- // onEnd the teardown chain has finished, so re-finalize from the full
294
- // stream and overwrite the salvage blob with the post-teardown report.
295
268
  if (this._finalizePromise) {
296
269
  await this._finalizePromise;
297
270
  this._finalizePromise = this._finalizeAndMaybeUpload({
@@ -314,9 +287,6 @@ class IncrementalBlobReporter {
314
287
  await this._finalizePromise;
315
288
  console.log(`[IncrementalBlobReporter] Finished with status: ${result.status}`);
316
289
  }
317
- /**
318
- * Add a single attachment URL mapping
319
- */
320
290
  addAttachmentUrl(localPath, remoteUrl) {
321
291
  this._attachmentUrlMap.set((0, ibr_utils_1.toResourcePath)(localPath), remoteUrl);
322
292
  }