@empiricalrun/playwright-utils 0.62.1 → 0.63.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.
Files changed (115) hide show
  1. package/CHANGELOG.md +15 -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 +2083 -1044
  12. package/dist/generated/api-worker-openapi.d.ts.map +1 -1
  13. package/dist/overlay-tests/cache.spec.js +0 -10
  14. package/dist/overlay-tests/click.spec.js +0 -18
  15. package/dist/playwright-extensions.d.ts.map +1 -1
  16. package/dist/playwright-extensions.js +0 -1
  17. package/dist/reporter/attachment-cleanup-test-reporter.d.ts +0 -6
  18. package/dist/reporter/attachment-cleanup-test-reporter.d.ts.map +1 -1
  19. package/dist/reporter/attachment-cleanup-test-reporter.js +0 -6
  20. package/dist/reporter/attachment-cleanup.d.ts +0 -33
  21. package/dist/reporter/attachment-cleanup.d.ts.map +1 -1
  22. package/dist/reporter/attachment-cleanup.js +2 -51
  23. package/dist/reporter/empirical-reporter.d.ts.map +1 -1
  24. package/dist/reporter/empirical-reporter.js +0 -9
  25. package/dist/reporter/harness.d.ts +0 -62
  26. package/dist/reporter/harness.d.ts.map +1 -1
  27. package/dist/reporter/harness.js +1 -53
  28. package/dist/reporter/ibr-utils.d.ts +0 -5
  29. package/dist/reporter/ibr-utils.d.ts.map +1 -1
  30. package/dist/reporter/ibr-utils.js +0 -5
  31. package/dist/reporter/incremental-blob-reporter.d.ts +0 -17
  32. package/dist/reporter/incremental-blob-reporter.d.ts.map +1 -1
  33. package/dist/reporter/incremental-blob-reporter.js +5 -35
  34. package/dist/reporter/lifecycle-events.d.ts.map +1 -1
  35. package/dist/reporter/lifecycle-events.js +0 -9
  36. package/dist/reporter/parity-utils.d.ts +0 -30
  37. package/dist/reporter/parity-utils.d.ts.map +1 -1
  38. package/dist/reporter/parity-utils.js +4 -28
  39. package/dist/reporter/reporter-state.d.ts +0 -12
  40. package/dist/reporter/reporter-state.d.ts.map +1 -1
  41. package/dist/reporter/reporter-state.js +0 -12
  42. package/dist/reporter/test-case-sync.d.ts.map +1 -1
  43. package/dist/reporter/test-case-sync.js +0 -12
  44. package/dist/reporter/uploader.d.ts.map +1 -1
  45. package/dist/reporter/uploader.js +0 -6
  46. package/dist/reporter/util.d.ts +0 -33
  47. package/dist/reporter/util.d.ts.map +1 -1
  48. package/dist/reporter/util.js +0 -37
  49. package/dist/telemetry.d.ts.map +1 -1
  50. package/dist/telemetry.js +1 -10
  51. package/dist/test/coverage.d.ts.map +1 -1
  52. package/dist/test/coverage.js +1 -3
  53. package/dist/test/expect/visual.d.ts.map +1 -1
  54. package/dist/test/expect/visual.js +1 -9
  55. package/dist/test/index.d.ts.map +1 -1
  56. package/dist/test/index.js +4 -21
  57. package/dist/test/scripts/agent-capabilities.js +2 -2
  58. package/dist/test/scripts/index.d.ts +2 -2
  59. package/dist/test/scripts/index.d.ts.map +1 -1
  60. package/dist/test/scripts/index.js +3 -16
  61. package/dist/test/scripts/pw-locator-patch/actions/click.d.ts.map +1 -0
  62. package/dist/test/scripts/pw-locator-patch/{highlight → actions}/click.js +0 -6
  63. package/dist/test/scripts/pw-locator-patch/actions/hover.d.ts.map +1 -0
  64. package/dist/test/scripts/pw-locator-patch/{highlight → actions}/hover.js +0 -3
  65. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/cache.d.ts.map +1 -1
  66. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/cache.js +0 -7
  67. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.d.ts.map +1 -1
  68. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.js +1 -9
  69. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/prompt.d.ts.map +1 -1
  70. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/prompt.js +0 -1
  71. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.d.ts.map +1 -1
  72. package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.js +2 -5
  73. package/dist/test/scripts/pw-locator-patch/utils/index.d.ts +0 -1
  74. package/dist/test/scripts/pw-locator-patch/utils/index.d.ts.map +1 -1
  75. package/dist/test/scripts/pw-locator-patch/utils/index.js +0 -18
  76. package/dist/test/types.d.ts +2 -5
  77. package/dist/test/types.d.ts.map +1 -1
  78. package/dist/test/video-labels.d.ts.map +1 -1
  79. package/dist/test/video-labels.js +0 -1
  80. package/dist/webhook.d.ts.map +1 -1
  81. package/dist/webhook.js +0 -3
  82. package/docs/fixtures.md +4 -5
  83. package/package.json +6 -6
  84. package/playwright.config.ts +0 -4
  85. package/tsconfig.tsbuildinfo +1 -1
  86. package/upstream-oracle/ibr-adapter.js +0 -23
  87. package/upstream-oracle/run.mjs +1 -69
  88. package/dist/test/scripts/locator-highlights.d.ts +0 -4
  89. package/dist/test/scripts/locator-highlights.d.ts.map +0 -1
  90. package/dist/test/scripts/locator-highlights.js +0 -28
  91. package/dist/test/scripts/pw-locator-patch/highlight/click.d.ts.map +0 -1
  92. package/dist/test/scripts/pw-locator-patch/highlight/expect.d.ts +0 -5
  93. package/dist/test/scripts/pw-locator-patch/highlight/expect.d.ts.map +0 -1
  94. package/dist/test/scripts/pw-locator-patch/highlight/expect.js +0 -23
  95. package/dist/test/scripts/pw-locator-patch/highlight/hover.d.ts.map +0 -1
  96. package/dist/test/scripts/pw-locator-patch/highlight/inner-text.d.ts +0 -6
  97. package/dist/test/scripts/pw-locator-patch/highlight/inner-text.d.ts.map +0 -1
  98. package/dist/test/scripts/pw-locator-patch/highlight/inner-text.js +0 -30
  99. package/dist/test/scripts/pw-locator-patch/highlight/input-value.d.ts +0 -6
  100. package/dist/test/scripts/pw-locator-patch/highlight/input-value.d.ts.map +0 -1
  101. package/dist/test/scripts/pw-locator-patch/highlight/input-value.js +0 -30
  102. package/dist/test/scripts/pw-locator-patch/highlight/is-checked.d.ts +0 -6
  103. package/dist/test/scripts/pw-locator-patch/highlight/is-checked.d.ts.map +0 -1
  104. package/dist/test/scripts/pw-locator-patch/highlight/is-checked.js +0 -30
  105. package/dist/test/scripts/pw-locator-patch/highlight/is-disabled.d.ts +0 -6
  106. package/dist/test/scripts/pw-locator-patch/highlight/is-disabled.d.ts.map +0 -1
  107. package/dist/test/scripts/pw-locator-patch/highlight/is-disabled.js +0 -30
  108. package/dist/test/scripts/pw-locator-patch/highlight/is-editable.d.ts +0 -6
  109. package/dist/test/scripts/pw-locator-patch/highlight/is-editable.d.ts.map +0 -1
  110. package/dist/test/scripts/pw-locator-patch/highlight/is-editable.js +0 -29
  111. package/dist/test/scripts/pw-locator-patch/highlight/text-content.d.ts +0 -6
  112. package/dist/test/scripts/pw-locator-patch/highlight/text-content.d.ts.map +0 -1
  113. package/dist/test/scripts/pw-locator-patch/highlight/text-content.js +0 -30
  114. /package/dist/test/scripts/pw-locator-patch/{highlight → actions}/click.d.ts +0 -0
  115. /package/dist/test/scripts/pw-locator-patch/{highlight → actions}/hover.d.ts +0 -0
@@ -107,9 +107,6 @@ class Uploader {
107
107
  await (0, r2_uploader_1.waitForTaskQueueToFinish)();
108
108
  return;
109
109
  }
110
- // This drain runs after the last test with no other output (observed at
111
- // 4+ minutes on spot runs), so make it visible: count up front, progress
112
- // every 30s, duration at the end.
113
110
  const start = Date.now();
114
111
  console.log(`[Uploader] Waiting for ${pending} pending uploads (${executing} executing, ${waiting} queued)...`);
115
112
  const progress = setInterval(() => {
@@ -143,7 +140,6 @@ function createUploader() {
143
140
  logger_1.logger.debug("[Uploader] PROJECT_NAME and TEST_RUN_GITHUB_ACTION_ID must be set");
144
141
  return null;
145
142
  }
146
- // REPORT_STORAGE_BACKEND selects the upload target; anything else is a misconfig.
147
143
  const backend = process.env.REPORT_STORAGE_BACKEND;
148
144
  if (backend !== "s3" && backend !== "r2") {
149
145
  logger_1.logger.debug(`[Uploader] REPORT_STORAGE_BACKEND must be "s3" or "r2" (got ${backend ?? "unset"})`);
@@ -165,8 +161,6 @@ function createUploader() {
165
161
  logger_1.logger.debug("[Uploader] S3_REGION or S3_UPLOAD_BUCKET not configured");
166
162
  return null;
167
163
  }
168
- // Upload through the task role to S3, but persist CDN URLs so the bucket
169
- // can stay private. Direct S3 is the fallback for envs without a CDN.
170
164
  baseUrl =
171
165
  process.env.REPORTS_BASE_URL?.replace(/\/+$/, "") ||
172
166
  `https://${bucket}.s3.${region}.amazonaws.com`;
@@ -20,40 +20,7 @@ export declare function suitesAndProjectForTest(test: TestCase): {
20
20
  export declare function sendTestCaseUpdateToDashboard(params: TestCaseRunEndEventV2): Promise<void>;
21
21
  export declare function safelySerialiseJSON(obj: any, keyFilter?: (key: string) => boolean): any;
22
22
  export declare function updateHtmlZipFileAttachmentPaths(jsonFilePath: string, htmlFilePath: string, repoPath: string): Promise<void>;
23
- /**
24
- * Replaces media paths in test results with normalized paths from the test attachment map.
25
- * This function updates the attachments array in each test result with the corresponding
26
- * normalized attachments from the test attachment map.
27
- *
28
- * @param jsonData - The JSON data containing test results, which can be either in the format
29
- * of { files: [{ tests: [...] }] } or { tests: [...] }
30
- * @param testAttachmentMap - A Map where the key is the test ID and the value is an array of
31
- * objects containing attachments with updated path for each test result
32
- * @returns void
33
- */
34
- /**
35
- * Builds a map from test ID to an array of objects containing attachments for each result (retry).
36
- * The attachments are normalized to use relative paths starting with 'data/'.
37
- * @param summaryJsonFilePath Path to the summary JSON file
38
- * @returns Map<string, { attachments: GenericPlaywrightAttachment[] }[]>
39
- */
40
23
  export declare function buildTestAttachmentMapFromSummary(summaryJsonFilePath: string, repoPath: string, doNotNormalize?: boolean): TestAttachmentMap;
41
- /**
42
- * Checks asynchronously if a file exists at the given path.
43
- * @param filePath - The path to the file to check
44
- * @returns Promise<boolean> - true if the file exists, false otherwise
45
- */
46
24
  export declare function checkFileExistsAsync(filePath: string): Promise<boolean>;
47
- /**
48
- * Updates the attachment paths in the summary JSON file to use remote URLs.
49
- *
50
- * This function rewrites all attachment `path` fields in the given Playwright summary JSON file
51
- * so that they point to remote URLs based on the current `PROJECT_NAME` and `TEST_RUN_GITHUB_ACTION_ID`
52
- * environment variables.
53
- *
54
- * @param filePath - The path to the summary JSON file
55
- * @returns The updated summary JSON
56
- *
57
- */
58
25
  export declare function updateSummaryJsonAttachmentPaths(filePath: string, repoPath: string, urlPrefix: string): Promise<PlaywrightJSONReport | undefined>;
59
26
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/reporter/util.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EACL,UAAU,IAAI,oBAAoB,EAElC,QAAQ,EACT,MAAM,2BAA2B,CAAC;AA0BnC,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAqB7D;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAAG,SAAS,UAQhC;AAED,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5E,OAAO,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CA6CD;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ;IAqBlD,MAAM;IACN,WAAW;EAEd;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GACnC,GAAG,CAIL;AAED,wBAAsB,gCAAgC,CACpD,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,iBAoFjB;AAED;;;;;;;;;;GAUG;AACH;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,EAChB,cAAc,GAAE,OAAe,GAC9B,iBAAiB,CAgBnB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7E;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,6CA+BlB"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/reporter/util.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EACL,UAAU,IAAI,oBAAoB,EAElC,QAAQ,EACT,MAAM,2BAA2B,CAAC;AA0BnC,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAqB7D;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAAG,SAAS,UAQhC;AAED,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5E,OAAO,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CA6CD;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ;IAmBlD,MAAM;IACN,WAAW;EAEd;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GACnC,GAAG,CAIL;AAED,wBAAsB,gCAAgC,CACpD,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,iBAkFjB;AAED,wBAAgB,iCAAiC,CAC/C,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,EAChB,cAAc,GAAE,OAAe,GAC9B,iBAAiB,CAgBnB;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7E;AAED,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,6CA+BlB"}
@@ -108,8 +108,6 @@ function suitesAndProjectForTest(test) {
108
108
  parent = parent.parent;
109
109
  }
110
110
  }
111
- // rawSuites looks like [ 'describe 3', 'describe 1', 'home.spec.ts', 'chromium', '' ]
112
- // For suites, we will extract suites and then reverse them, since we expect top-to-bottom ordering for suites
113
111
  let suites = [];
114
112
  let iteratorIdx = 0;
115
113
  for (; iteratorIdx < rawSuites.length; iteratorIdx++) {
@@ -210,27 +208,8 @@ async function updateHtmlZipFileAttachmentPaths(jsonFilePath, htmlFilePath, repo
210
208
  logger_1.logger.error("❌ Error processing report.json or updating files:", err);
211
209
  }
212
210
  finally {
213
- // Optional cleanup:
214
- // await fs.promises.rm(tempDir, { recursive: true, force: true });
215
211
  }
216
212
  }
217
- /**
218
- * Replaces media paths in test results with normalized paths from the test attachment map.
219
- * This function updates the attachments array in each test result with the corresponding
220
- * normalized attachments from the test attachment map.
221
- *
222
- * @param jsonData - The JSON data containing test results, which can be either in the format
223
- * of { files: [{ tests: [...] }] } or { tests: [...] }
224
- * @param testAttachmentMap - A Map where the key is the test ID and the value is an array of
225
- * objects containing attachments with updated path for each test result
226
- * @returns void
227
- */
228
- /**
229
- * Builds a map from test ID to an array of objects containing attachments for each result (retry).
230
- * The attachments are normalized to use relative paths starting with 'data/'.
231
- * @param summaryJsonFilePath Path to the summary JSON file
232
- * @returns Map<string, { attachments: GenericPlaywrightAttachment[] }[]>
233
- */
234
213
  function buildTestAttachmentMapFromSummary(summaryJsonFilePath, repoPath, doNotNormalize = false) {
235
214
  const summaryJson = JSON.parse(fs_1.default.readFileSync(summaryJsonFilePath, "utf8"));
236
215
  return (0, reporter_1.buildTestAttachmentMap)(summaryJson, {
@@ -245,11 +224,6 @@ function buildTestAttachmentMapFromSummary(summaryJsonFilePath, repoPath, doNotN
245
224
  },
246
225
  });
247
226
  }
248
- /**
249
- * Checks asynchronously if a file exists at the given path.
250
- * @param filePath - The path to the file to check
251
- * @returns Promise<boolean> - true if the file exists, false otherwise
252
- */
253
227
  async function checkFileExistsAsync(filePath) {
254
228
  try {
255
229
  await fs_1.default.promises.access(filePath);
@@ -259,17 +233,6 @@ async function checkFileExistsAsync(filePath) {
259
233
  return false;
260
234
  }
261
235
  }
262
- /**
263
- * Updates the attachment paths in the summary JSON file to use remote URLs.
264
- *
265
- * This function rewrites all attachment `path` fields in the given Playwright summary JSON file
266
- * so that they point to remote URLs based on the current `PROJECT_NAME` and `TEST_RUN_GITHUB_ACTION_ID`
267
- * environment variables.
268
- *
269
- * @param filePath - The path to the summary JSON file
270
- * @returns The updated summary JSON
271
- *
272
- */
273
236
  async function updateSummaryJsonAttachmentPaths(filePath, repoPath, urlPrefix) {
274
237
  if (!process.env.PROJECT_NAME || !process.env.TEST_RUN_GITHUB_ACTION_ID) {
275
238
  console.error("PROJECT_NAME and TEST_RUN_GITHUB_ACTION_ID must be set");
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAUtE,wBAAsB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBrE;AAED,UAAU,uBAAuB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhB;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB"}
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAOtE,wBAAsB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBrE;AAED,UAAU,uBAAuB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhB;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB"}
package/dist/telemetry.js CHANGED
@@ -5,9 +5,6 @@ exports.trackReportUpload = trackReportUpload;
5
5
  exports.trackOverlayDismissed = trackOverlayDismissed;
6
6
  exports.trackLLMResponseGenerated = trackLLMResponseGenerated;
7
7
  const api_worker_client_1 = require("./api-worker-client");
8
- // Events go to api-worker on the project API key the run already carries, so
9
- // a runner needs no telemetry secret. Best-effort: no key means no telemetry,
10
- // and a failed send is never retried or surfaced to the test.
11
8
  async function trackEvent(event) {
12
9
  if (!process.env.EMPIRICALRUN_API_KEY) {
13
10
  return;
@@ -16,14 +13,10 @@ async function trackEvent(event) {
16
13
  const { client } = new api_worker_client_1.ApiWorkerClient();
17
14
  const { response } = await client.POST("/api/v1/telemetry/track", {
18
15
  body: {
19
- // api-worker accepts only test-run events; the ones sent from here
20
- // are all on its allowlist.
21
16
  name: event.name,
22
17
  properties: event.properties,
23
18
  timestamp: event.timestamp?.toISOString(),
24
19
  },
25
- // Plain fetch, not the client's retrying one: a test should not wait
26
- // out backoff for a metric.
27
20
  fetch,
28
21
  signal: AbortSignal.timeout(10_000),
29
22
  });
@@ -31,9 +24,7 @@ async function trackEvent(event) {
31
24
  throw new Error(`Telemetry request failed: ${response.status}`);
32
25
  }
33
26
  }
34
- catch {
35
- // Don't throw - telemetry failures shouldn't break the application
36
- }
27
+ catch { }
37
28
  }
38
29
  async function trackReportUpload(params) {
39
30
  const environment = process.env.ENVIRONMENT || "unknown";
@@ -1 +1 @@
1
- {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/test/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAYvD,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,cAAc,qBAwBpE;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,MAAM,EAAE,EACvB,QAAQ,EAAE;IACR,MAAM,EAAE,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,iBAqBF"}
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/test/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAYvD,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,cAAc,qBAwBpE;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,MAAM,EAAE,EACvB,QAAQ,EAAE;IACR,MAAM,EAAE,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,iBAmBF"}
@@ -31,9 +31,7 @@ async function collectAndAttachCoverage(context, coverageFiles, testInfo) {
31
31
  try {
32
32
  await page.evaluate(() => window.collectIstanbulCoverage(JSON.stringify(window.__coverage__)));
33
33
  }
34
- catch {
35
- // Page might be closed or coverage not available
36
- }
34
+ catch { }
37
35
  }
38
36
  for (const filepath of coverageFiles) {
39
37
  if (fs_1.default.existsSync(filepath)) {
@@ -1 +1 @@
1
- {"version":3,"file":"visual.d.ts","sourceRoot":"","sources":["../../../src/test/expect/visual.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAY,MAAM,kBAAkB,CAAC;AAOhE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAsE7C,wBAAsB,WAAW,CAC/B,MAAM,EAAE,IAAI,GAAG,OAAO,EACtB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,aAAa,CAAC,CAwFxB"}
1
+ {"version":3,"file":"visual.d.ts","sourceRoot":"","sources":["../../../src/test/expect/visual.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAY,MAAM,kBAAkB,CAAC;AAOhE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAgE7C,wBAAsB,WAAW,CAC/B,MAAM,EAAE,IAAI,GAAG,OAAO,EACtB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,aAAa,CAAC,CAsFxB"}
@@ -17,7 +17,6 @@ function getCallerLine() {
17
17
  return "unknown";
18
18
  }
19
19
  const frames = stack.split("\n").slice(1);
20
- // Find the test file frame (e.g. .spec.ts, .test.ts)
21
20
  const testFrame = frames.find((f) => /\.(spec|test)\.[jt]sx?:/.test(f));
22
21
  if (!testFrame) {
23
22
  return "unknown";
@@ -27,7 +26,6 @@ function getCallerLine() {
27
26
  }
28
27
  function attachScreenshot(screenshot, pageDescription) {
29
28
  try {
30
- // test.info() is only available during a Playwright test run
31
29
  const { test } = require("@playwright/test");
32
30
  const testInfo = test.info();
33
31
  const slug = pageDescription
@@ -38,8 +36,6 @@ function attachScreenshot(screenshot, pageDescription) {
38
36
  .replace(/(^-|-$)/g, "");
39
37
  const line = getCallerLine();
40
38
  const attachmentName = `toLookRight-L${line}-${slug}`;
41
- // Write to a temp file so the attachment has a path (required by empirical reporter).
42
- // Playwright copies it into test-results/<test>/attachments/ on attach.
43
39
  const tmpFile = path_1.default.join(os_1.default.tmpdir(), `${attachmentName}-${Date.now()}.png`);
44
40
  fs_1.default.writeFileSync(tmpFile, screenshot);
45
41
  testInfo.attach(attachmentName, {
@@ -47,9 +43,7 @@ function attachScreenshot(screenshot, pageDescription) {
47
43
  contentType: "image/png",
48
44
  });
49
45
  }
50
- catch {
51
- // Not in a Playwright test context, skip attachment
52
- }
46
+ catch { }
53
47
  }
54
48
  const SYSTEM_PROMPT = `
55
49
  You are a software QA tester who specializes in visual testing. You look at a
@@ -79,8 +73,6 @@ async function toLookRight(target, pageDescription) {
79
73
  attachScreenshot(screenshot, pageDescription);
80
74
  const base64Image = screenshot.toString("base64");
81
75
  const model = "gpt-4o";
82
- // Same api-worker proxy the overlay-dismissal agent uses, so a test run needs
83
- // no OpenAI key of its own; undefined falls back to the SDK's env defaults.
84
76
  const openai = new openai_1.default({ maxRetries: 5, ...(0, api_worker_client_1.llmProxyOpenAIConfig)() });
85
77
  const completion = await openai.chat.completions.create({
86
78
  model,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,KAAK,mBAAmB,EAAwB,MAAM,SAAS,CAAC;AACzE,OAAO,EAA8B,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,cAAc,CAAC;QACvB,UAAU,QAAQ,CAAC,CAAC;YAClB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7C,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;SACnE;KACF;CACF;AAED,QAAA,MAAM,YAAY,mBAA6B,OAAO,MAAM,0CAG3D,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,QAAQ,CAAC;IACb,yBAAyB,EAAE,CACzB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAYF,QAAA,MAAM,eAAe,WACX,QAAQ,CACd,kBAAkB,GAAG,qBAAqB,EAC1C,oBAAoB,GAAG,uBAAuB,CAC/C,YACQ,mBAAmB,uHAwH7B,CAAC;AAEF,OAAO,EACL,eAAe,EACf,YAAY,EACZ,6BAA6B,EAC7B,aAAa,GACd,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAA8B,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,cAAc,CAAC;QACvB,UAAU,QAAQ,CAAC,CAAC;YAClB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7C,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;SACnE;KACF;CACF;AAED,QAAA,MAAM,YAAY,mBAA6B,OAAO,MAAM,0CAG3D,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,QAAQ,CAAC;IACb,yBAAyB,EAAE,CACzB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAIF,QAAA,MAAM,eAAe,WACX,QAAQ,CACd,kBAAkB,GAAG,qBAAqB,EAC1C,oBAAoB,GAAG,uBAAuB,CAC/C,YACQ,mBAAmB,uHA6G7B,CAAC;AAEF,OAAO,EACL,eAAe,EACf,YAAY,EACZ,6BAA6B,EAC7B,aAAa,GACd,CAAC"}
@@ -17,23 +17,13 @@ const extendExpect = function (expectInstance) {
17
17
  return expectInstance;
18
18
  };
19
19
  exports.extendExpect = extendExpect;
20
- // Track pages per test to save videos with labels
21
20
  const testPages = new Map();
22
- const defaultOptions = {
23
- mousePointerHighlighter: true,
24
- locatorHighlighter: true,
25
- visionMethods: true,
26
- agentCapabilities: true,
27
- };
28
- const baseTestFixture = function (testFn, options = defaultOptions) {
21
+ const baseTestFixture = function (testFn, options = {}) {
29
22
  const coverageEnabled = options.collectCoverage ?? false;
30
- // Playwright draws the cursor, target box and action title into the video.
31
- // 100ms per action keeps them visible without the default 500ms slowdown.
32
- const showActions = options.mousePointerHighlighter === false ? undefined : { duration: 100 };
33
23
  const recordVideoOptions = (dir) => ({
34
24
  dir,
35
25
  size: { width: 1280, height: 720 },
36
- showActions,
26
+ showActions: { duration: 100 },
37
27
  });
38
28
  const extendedTestFn = testFn.extend({
39
29
  context: async ({ browser }, use, testInfo) => {
@@ -57,10 +47,7 @@ const baseTestFixture = function (testFn, options = defaultOptions) {
57
47
  await context.close();
58
48
  },
59
49
  page: async ({ page }, use) => {
60
- (0, scripts_1.injectLocatorHighlightScripts)(page, extendedTestFn, {
61
- ...defaultOptions,
62
- ...options,
63
- });
50
+ (0, scripts_1.injectLocatorHighlightScripts)(page, extendedTestFn, options);
64
51
  await use(page);
65
52
  },
66
53
  kv: async ({}, use) => {
@@ -82,7 +69,6 @@ const baseTestFixture = function (testFn, options = defaultOptions) {
82
69
  return { context: pageContext, page: customPage };
83
70
  }
84
71
  await use(createContext);
85
- // Store pages for video renaming
86
72
  if (!testPages.has(testInfo.testId)) {
87
73
  testPages.set(testInfo.testId, []);
88
74
  }
@@ -98,7 +84,6 @@ const baseTestFixture = function (testFn, options = defaultOptions) {
98
84
  await use();
99
85
  const pages = testPages.get(testInfo.testId) || [];
100
86
  const usedLabels = new Set();
101
- // Save videos with custom labels using saveAs
102
87
  for (let i = 0; i < pages.length; i++) {
103
88
  const page = pages[i];
104
89
  if (!page) {
@@ -121,9 +106,7 @@ const baseTestFixture = function (testFn, options = defaultOptions) {
121
106
  });
122
107
  await video.delete();
123
108
  }
124
- catch (e) {
125
- // Skip if video not available
126
- }
109
+ catch (e) { }
127
110
  }
128
111
  testPages.delete(testInfo.testId);
129
112
  },
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addAgentCapabilities = addAgentCapabilities;
4
- const click_1 = require("./pw-locator-patch/highlight/click");
5
- const hover_1 = require("./pw-locator-patch/highlight/hover");
4
+ const click_1 = require("./pw-locator-patch/actions/click");
5
+ const hover_1 = require("./pw-locator-patch/actions/hover");
6
6
  function applyPatchForAutoDismissOverlay(page, testFn) {
7
7
  const LocatorClass = page.locator("").constructor;
8
8
  (0, click_1.patchClick)(LocatorClass, testFn);
@@ -1,5 +1,5 @@
1
1
  import type { Page } from "@playwright/test";
2
- import { HighlighterOpts } from "../types";
2
+ import { PageScriptOpts } from "../types";
3
3
  import { TestFn } from "./types";
4
- export declare function injectLocatorHighlightScripts(page: Page, testFn: TestFn, options?: HighlighterOpts): void;
4
+ export declare function injectLocatorHighlightScripts(page: Page, testFn: TestFn, { visionMethods, agentCapabilities }?: PageScriptOpts): void;
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAI3C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAQjC,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,eAAgC,QAmB1C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,EAAE,aAAoB,EAAE,iBAAwB,EAAE,GAAE,cAAmB,QAYxE"}
@@ -3,26 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.injectLocatorHighlightScripts = injectLocatorHighlightScripts;
4
4
  const logger_1 = require("../../logger");
5
5
  const agent_capabilities_1 = require("./agent-capabilities");
6
- const locator_highlights_1 = require("./locator-highlights");
7
6
  const locator_vision_1 = require("./locator-vision");
8
- const defaultOptions = {
9
- locatorHighlighter: true,
10
- visionMethods: true,
11
- agentCapabilities: true,
12
- };
13
- function injectLocatorHighlightScripts(page, testFn, options = defaultOptions) {
14
- const opts = {
15
- ...defaultOptions,
16
- ...options,
17
- };
7
+ function injectLocatorHighlightScripts(page, testFn, { visionMethods = true, agentCapabilities = true } = {}) {
18
8
  try {
19
- if (opts.locatorHighlighter) {
20
- (0, locator_highlights_1.addLocatorHighlights)(page, testFn);
21
- }
22
- if (opts.visionMethods) {
9
+ if (visionMethods) {
23
10
  (0, locator_vision_1.addLocatorVisionMethods)(page);
24
11
  }
25
- if (opts.agentCapabilities) {
12
+ if (agentCapabilities) {
26
13
  (0, agent_capabilities_1.addAgentCapabilities)(page, testFn);
27
14
  }
28
15
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/actions/click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,QAsDf"}
@@ -4,7 +4,6 @@ exports.patchClick = patchClick;
4
4
  const dismiss_overlays_1 = require("../dismiss-overlays");
5
5
  const utils_1 = require("../dismiss-overlays/utils");
6
6
  const utils_2 = require("../utils");
7
- // Static flag to track if click has been patched
8
7
  const isClickPatched = new WeakMap();
9
8
  function patchClick(LocatorClass, testFn) {
10
9
  if (isClickPatched.get(LocatorClass)) {
@@ -23,19 +22,15 @@ function patchClick(LocatorClass, testFn) {
23
22
  overlayAttemptsRemaining--;
24
23
  try {
25
24
  let result = await originalClick.apply(this, [options]);
26
- // If click is successful, we can save overlay dismissal code to cache and return
27
25
  await overlayDismiss.saveToCache();
28
26
  return result;
29
27
  }
30
28
  catch (error) {
31
29
  originalError = error;
32
30
  if (originalError instanceof Error) {
33
- // Overwrite the stack trace to show the original click (remove patch)
34
31
  Error.captureStackTrace(originalError, LocatorClass.prototype.click);
35
32
  }
36
33
  if (options?.isExecutingForOverlayDismiss) {
37
- // While executing dismiss code from cache, we attach this custom option
38
- // which ensures that the overlay dismissal will not trigger recursively
39
34
  throw originalError;
40
35
  }
41
36
  if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
@@ -45,7 +40,6 @@ function patchClick(LocatorClass, testFn) {
45
40
  throw originalError;
46
41
  }
47
42
  await overlayDismiss.run(originalError, reporter, testFn);
48
- // Dismissal attempt finished (implicitly successful if no error thrown)
49
43
  reporter(`Overlay dismissal attempted, retrying original action.`);
50
44
  }
51
45
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/actions/hover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,QAgDf"}
@@ -21,7 +21,6 @@ function patchHover(LocatorClass, testFn) {
21
21
  overlayAttemptsRemaining--;
22
22
  try {
23
23
  let result = await originalHover.apply(this, [options]);
24
- // If hover is successful, we can save overlay dismissal code to cache and return
25
24
  await overlayDismiss.saveToCache();
26
25
  return result;
27
26
  }
@@ -31,8 +30,6 @@ function patchHover(LocatorClass, testFn) {
31
30
  Error.captureStackTrace(originalError, LocatorClass.prototype.hover);
32
31
  }
33
32
  if (options?.isExecutingForOverlayDismiss) {
34
- // While executing dismiss code from cache, we attach this custom option
35
- // which ensures that the overlay dismissal will not trigger recursively
36
33
  throw originalError;
37
34
  }
38
35
  if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAM7C,eAAO,MAAM,UAAU,QAItB,CAAC;AAOF,wBAAsB,cAAc,CAAC,EACnC,GAAG,EACH,IAAI,EACJ,IAAI,GACL,EAAE;IACD,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,iBAkCA;AAED,wBAAsB,gBAAgB,CAAC,EACrC,IAAI,EACJ,GAAG,EACH,IAAI,GACL,EAAE;IACD,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAmChC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,UAc5C"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAM7C,eAAO,MAAM,UAAU,QAItB,CAAC;AAMF,wBAAsB,cAAc,CAAC,EACnC,GAAG,EACH,IAAI,EACJ,IAAI,GACL,EAAE;IACD,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,iBAgCA;AAED,wBAAsB,gBAAgB,CAAC,EACrC,IAAI,EACJ,GAAG,EACH,IAAI,GACL,EAAE;IACD,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAiChC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,UAY5C"}
@@ -11,16 +11,13 @@ const fs_1 = __importDefault(require("fs"));
11
11
  const path_1 = __importDefault(require("path"));
12
12
  exports.CACHE_FILE = path_1.default.join(process.cwd(), ".empiricalrun", `overlay-cache.json`);
13
13
  function normalizeString(str) {
14
- // Replace all whitespace sequences with a single space
15
14
  return str.replace(/\s+/g, " ").trim();
16
15
  }
17
16
  async function setCodeToCache({ dom, text, code, }) {
18
17
  if (!dom && !text) {
19
- // At least one of the two is required
20
18
  return;
21
19
  }
22
20
  if (process.env.TEST_GEN_TOKEN) {
23
- // No caching for test gen sessions (we don't want steps to get committed)
24
21
  return;
25
22
  }
26
23
  const obj = {
@@ -52,7 +49,6 @@ async function setCodeToCache({ dom, text, code, }) {
52
49
  }
53
50
  async function executeFromCache({ page, dom, text, }) {
54
51
  if (!dom && !text) {
55
- // At least one of the two is required
56
52
  return { success: false };
57
53
  }
58
54
  try {
@@ -66,7 +62,6 @@ async function executeFromCache({ page, dom, text, }) {
66
62
  }
67
63
  try {
68
64
  console.log(`Executing from cache: "${match.code}" for element: ${dom}`);
69
- // Ref: https://davidwalsh.name/async-function-class
70
65
  const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
71
66
  const codeToExecute = addOverlayOption(match.code);
72
67
  const exec = new AsyncFunction("page", codeToExecute);
@@ -85,12 +80,10 @@ async function executeFromCache({ page, dom, text, }) {
85
80
  function addOverlayOption(code) {
86
81
  return code.replace(/\.(click|hover)(\s*\(\s*)(\{[^}]*\})?(\s*\))(;)?/g, (match, action, openParen, options, closeParen, semicolon) => {
87
82
  if (options) {
88
- // If options exist, add isExecutingForOverlayDismiss to them
89
83
  const optionsObj = options.replace(/\s*}\s*$/, "");
90
84
  return `.${action}${openParen}${optionsObj}, isExecutingForOverlayDismiss: true }${closeParen}${semicolon || ""}`;
91
85
  }
92
86
  else {
93
- // If no options, add them with isExecutingForOverlayDismiss
94
87
  return `.${action}${openParen}{ isExecutingForOverlayDismiss: true }${closeParen}${semicolon || ""}`;
95
88
  }
96
89
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AAED,qBAAa,mBAAmB;IAOlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,iBAAiB,CAIhB;IAET,YAA6B,IAAI,EAAE,IAAI,EAAI;IAErC,WAAW,kBAIhB;IAEK,GAAG,CACP,aAAa,EAAE,GAAG,EAClB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,EACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAuDf;YAEa,QAAQ;CAqCvB;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AAED,qBAAa,mBAAmB;IAOlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,iBAAiB,CAIhB;IAET,YAA6B,IAAI,EAAE,IAAI,EAAI;IAErC,WAAW,kBAIhB;IAEK,GAAG,CACP,aAAa,EAAE,GAAG,EAClB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,EACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAqDf;YAEa,QAAQ;CA+BvB;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B"}
@@ -33,9 +33,7 @@ class OverlayDismissAgent {
33
33
  try {
34
34
  element = extractInterceptingElement(originalError.message);
35
35
  }
36
- catch {
37
- // Ignoring this error
38
- }
36
+ catch { }
39
37
  const description = (0, utils_1.overlayDescription)(element) ?? "unknown";
40
38
  const testName = testFn.info().title;
41
39
  reporter(`Attempting to auto-dismiss overlay: ${description}`);
@@ -96,13 +94,7 @@ class OverlayDismissAgent {
96
94
  // only once in a particular test run.
97
95
  // Ran into this here: https://empirical.run/quizizz-tests/sessions/2825
98
96
  prefersElementFromPointCodegen: true,
99
- // Overlay dismissal doesn't need page navigation — the overlay is
100
- // already on the current page. Including page_goto causes the model
101
- // to waste turns trying to navigate instead of clicking dismiss.
102
97
  includePageGotoTool: false,
103
- // Route the model call through api-worker (Cloudflare AI Gateway) on the
104
- // project API key, so test-run containers carry no OpenAI key. Undefined
105
- // on a dev machine or in a pi sandbox — see the helper.
106
98
  openAIClientConfig: (0, api_worker_client_1.llmProxyOpenAIConfig)(),
107
99
  });
108
100
  this.cachingCandidates.push({
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,wBAAsB,OAAO,CAC3B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,IAAI,EAAE,MAAM,GAAG,SAAS,mBAsCzB"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,wBAAsB,OAAO,CAC3B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,IAAI,EAAE,MAAM,GAAG,SAAS,mBAqCzB"}
@@ -13,7 +13,6 @@ ${text}
13
13
  `
14
14
  : "";
15
15
  if ((0, utils_1.isProductFruitsOverlay)(element)) {
16
- // TODO: Remove this special handling with app knowledge
17
16
  promptAddition = promptForPFScenario(text);
18
17
  }
19
18
  let task = `
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,sBASrE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,uBAKzE;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,cAAc,GAAG,SAAS,+BAmDpC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAMpE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uDAiBrD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,sBASrE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,uBAKzE;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,cAAc,GAAG,SAAS,+BAgDpC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAMpE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uDAiBrD"}
@@ -29,7 +29,7 @@ async function textContent(pageRef, element) {
29
29
  let endTag;
30
30
  const match = startTag.match(/^<\s*([^\s>]+)/);
31
31
  if (match) {
32
- const tagName = match[1]; // "div"
32
+ const tagName = match[1];
33
33
  endTag = `</${tagName}>`;
34
34
  }
35
35
  if (!startTag || !endTag) {
@@ -41,18 +41,15 @@ async function textContent(pageRef, element) {
41
41
  const parser = new DOMParser();
42
42
  const doc = parser.parseFromString(htmlString, "text/html");
43
43
  const tempEl = doc.body.firstElementChild;
44
- let selector = tempEl.tagName.toLowerCase(); // start with the tag name, e.g., 'div'
45
- // If there's an id, add it (id is unique and very specific)
44
+ let selector = tempEl.tagName.toLowerCase();
46
45
  if (tempEl.id) {
47
46
  selector += `#${CSS.escape(tempEl.id)}`;
48
47
  }
49
- // Add classes individually, escaping each one
50
48
  if (tempEl.classList.length > 0) {
51
49
  Array.from(tempEl.classList).forEach((cls) => {
52
50
  selector += `.${CSS.escape(cls)}`;
53
51
  });
54
52
  }
55
- // Add other attributes, being careful with escaping
56
53
  Array.from(tempEl.attributes).forEach((attr) => {
57
54
  if (attr.name === "id" || attr.name === "class") {
58
55
  return;
@@ -1,4 +1,3 @@
1
1
  import { Locator } from "playwright-core";
2
2
  export declare function description(locator: Locator): string;
3
- export declare function scrollIntoView(locator: Locator): Promise<void>;
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK1C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,UA0B3C;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,iBAgBpD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,UA0B3C"}
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.description = description;
4
- exports.scrollIntoView = scrollIntoView;
5
- const logger_1 = require("../../../../logger");
6
- const constants_1 = require("../../../constants");
7
4
  function description(locator) {
8
5
  const fallbackDescription = locator.toString();
9
6
  try {
@@ -25,18 +22,3 @@ function description(locator) {
25
22
  return fallbackDescription;
26
23
  }
27
24
  }
28
- async function scrollIntoView(locator) {
29
- try {
30
- await locator.evaluate((node) => {
31
- if (node.scrollIntoViewIfNeeded) {
32
- node.scrollIntoViewIfNeeded();
33
- }
34
- else {
35
- node.scrollIntoView();
36
- }
37
- }, undefined, { timeout: constants_1.DEFAULT_SCRIPT_EXECUTION_TIMEOUT });
38
- }
39
- catch {
40
- logger_1.logger.debug("Failed to scroll into view for locator method");
41
- }
42
- }