@empiricalrun/playwright-utils 0.26.14 → 0.26.16

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,33 @@
1
1
  # @empiricalrun/playwright-utils
2
2
 
3
+ ## 0.26.16
4
+
5
+ ### Patch Changes
6
+
7
+ - 43dc453: fix: record locators before execution for more reliable codegen
8
+ - Updated dependencies [e5b9f7e]
9
+ - Updated dependencies [43dc453]
10
+ - Updated dependencies [1a5ec8d]
11
+ - Updated dependencies [24d9415]
12
+ - @empiricalrun/test-gen@0.64.0
13
+ - @empiricalrun/llm@0.17.2
14
+
15
+ ## 0.26.15
16
+
17
+ ### Patch Changes
18
+
19
+ - a6b5997: test: add failing test for overlay dismiss triggering recursively
20
+ - 0b8379b: fix: ensure cached overlay dismissal does not run recursively
21
+ - Updated dependencies [c491cdd]
22
+ - Updated dependencies [f926e40]
23
+ - Updated dependencies [55c7913]
24
+ - Updated dependencies [2f1ee31]
25
+ - Updated dependencies [0fea8f1]
26
+ - Updated dependencies [115a023]
27
+ - Updated dependencies [6c7740b]
28
+ - @empiricalrun/test-gen@0.63.0
29
+ - @empiricalrun/llm@0.17.1
30
+
3
31
  ## 0.26.14
4
32
 
5
33
  ### Patch Changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cache.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.spec.d.ts","sourceRoot":"","sources":["../../src/overlay-tests/cache.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const test_1 = require("../test");
9
+ const cache_1 = require("../test/scripts/pw-locator-patch/dismiss-overlays/cache");
10
+ const fixtures_1 = require("./fixtures");
11
+ const useCache = (data) => {
12
+ const cacheValue = {
13
+ version: "2025-03-06",
14
+ data,
15
+ };
16
+ // Ensure the directory exists
17
+ const dir = path_1.default.dirname(cache_1.CACHE_FILE);
18
+ if (!fs_1.default.existsSync(dir)) {
19
+ fs_1.default.mkdirSync(dir, { recursive: true });
20
+ }
21
+ fs_1.default.writeFileSync(cache_1.CACHE_FILE, JSON.stringify(cacheValue, null, 2), "utf8");
22
+ };
23
+ fixtures_1.test.beforeEach(async ({ page }) => {
24
+ (0, test_1.injectLocatorHighlightScripts)(page, fixtures_1.test);
25
+ });
26
+ fixtures_1.test.afterEach(() => {
27
+ // Delete overlay cache
28
+ if (fs_1.default.existsSync(cache_1.CACHE_FILE))
29
+ fs_1.default.unlinkSync(cache_1.CACHE_FILE);
30
+ });
31
+ (0, fixtures_1.test)("overlay dismiss should not trigger recursively when executing from cache", async ({ page, server, }) => {
32
+ // Set up cache with a bad value: click on "Target" to dimiss the glass pane
33
+ useCache([
34
+ {
35
+ element: { dom: '<div class="glass-pane">', textContent: "" },
36
+ code: `await page.getByRole('button', { name: 'Target' }).click();\n`,
37
+ },
38
+ ]);
39
+ await page.goto(`${server.baseURL}/glass-pane.html`);
40
+ let error;
41
+ let startTime = Date.now();
42
+ // Overwriting API key to ensure we don't call OpenAI
43
+ const originalApiKey = process.env.OPENAI_API_KEY;
44
+ process.env.OPENAI_API_KEY = undefined;
45
+ try {
46
+ // Target element click will trigger the cache - which will invoke another
47
+ // click to the same element (recursive overlay dismissal)
48
+ await page.getByRole("button", { name: "Target" }).click();
49
+ }
50
+ catch (e) {
51
+ error = e;
52
+ }
53
+ process.env.OPENAI_API_KEY = originalApiKey;
54
+ const duration = Date.now() - startTime;
55
+ (0, fixtures_1.expect)(error).toBeDefined();
56
+ (0, fixtures_1.expect)(error.message).toContain('<div class="glass-pane"></div> intercepts pointer events');
57
+ // Expect total time to be action > timeout * 2 (original + dismiss)
58
+ (0, fixtures_1.expect)(duration).toBeGreaterThan(10_000);
59
+ // + some buffer for failing API call
60
+ (0, fixtures_1.expect)(duration).toBeLessThan(14_999);
61
+ });
@@ -1,10 +1,36 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
3
7
  const test_1 = require("../test");
8
+ const cache_1 = require("../test/scripts/pw-locator-patch/dismiss-overlays/cache");
4
9
  const fixtures_1 = require("./fixtures");
5
10
  fixtures_1.test.beforeEach(async ({ page }) => {
6
11
  (0, test_1.injectLocatorHighlightScripts)(page, fixtures_1.test);
7
12
  });
13
+ fixtures_1.test.afterAll(async () => {
14
+ // Delete overlay cache
15
+ if (fs_1.default.existsSync(cache_1.CACHE_FILE))
16
+ fs_1.default.unlinkSync(cache_1.CACHE_FILE);
17
+ });
18
+ function getCacheDataWithDom({ dom }) {
19
+ const cacheData = JSON.parse(fs_1.default.readFileSync(cache_1.CACHE_FILE, "utf8"));
20
+ return cacheData.data.find(({ element }) => {
21
+ if (dom)
22
+ return element.dom.includes(dom);
23
+ return false;
24
+ });
25
+ }
26
+ function getCacheDataWithTextContent({ textContent }) {
27
+ const cacheData = JSON.parse(fs_1.default.readFileSync(cache_1.CACHE_FILE, "utf8"));
28
+ return cacheData.data.find(({ element }) => {
29
+ if (textContent)
30
+ return element.textContent.includes(textContent);
31
+ return false;
32
+ });
33
+ }
8
34
  (0, fixtures_1.test)("should dismiss survicate for hover", async ({ page, server }) => {
9
35
  await page.goto(`${server.baseURL}/survey.html`);
10
36
  // Assert that Survicate and button loads
@@ -27,6 +53,38 @@ fixtures_1.test.beforeEach(async ({ page }) => {
27
53
  // Do the click, which should pass
28
54
  await page.getByRole("button", { name: "Target" }).click();
29
55
  await (0, fixtures_1.expect)(page.getByRole("heading", { name: "Terms of Service" })).not.toBeVisible();
56
+ // Assert cache is correct
57
+ const withDom = getCacheDataWithDom({
58
+ dom: '<div class="terms-text">',
59
+ });
60
+ (0, fixtures_1.expect)(withDom).toBeTruthy();
61
+ const withText = getCacheDataWithTextContent({
62
+ textContent: "By accepting these terms, you agree to our Terms of Service",
63
+ });
64
+ (0, fixtures_1.expect)(withDom).toEqual(withText);
65
+ const code = withDom?.code;
66
+ (0, fixtures_1.expect)(code).toBeDefined();
67
+ (0, fixtures_1.expect)(code).toMatch(/await page\.getBy(Text|Label)\('I have read and agree to the'\)\.click\(\);/);
68
+ (0, fixtures_1.expect)(code).toContain("await page.getByRole('button', { name: 'Accept' }).click()");
69
+ });
70
+ (0, fixtures_1.test)("should be able to fill form and dismiss overlay", async ({ page, server, }) => {
71
+ await page.goto(`${server.baseURL}/overlay-form.html`);
72
+ await page.getByRole("button", { name: "Target" }).click();
73
+ await (0, fixtures_1.expect)(page.getByText("Target was clicked")).toBeVisible();
74
+ // Assert cache is correct
75
+ const withDom = getCacheDataWithDom({
76
+ dom: 'id="hearAboutUs"',
77
+ });
78
+ (0, fixtures_1.expect)(withDom).toBeTruthy();
79
+ const withText = getCacheDataWithTextContent({
80
+ textContent: "How did you hear about us",
81
+ });
82
+ (0, fixtures_1.expect)(withText).toBeTruthy();
83
+ (0, fixtures_1.expect)(withDom).toEqual(withText);
84
+ const code = withDom?.code;
85
+ (0, fixtures_1.expect)(code).toBeDefined();
86
+ (0, fixtures_1.expect)(code).toContain("await page.getByPlaceholder('Please enter at least 4').fill");
87
+ (0, fixtures_1.expect)(code).toContain("await page.getByRole('button', { name: 'Submit' }).click()");
30
88
  });
31
89
  (0, fixtures_1.test)("should choose and dismiss the correct overlay", async ({ page, server, }) => {
32
90
  await page.goto(`${server.baseURL}/choose-an-overlay.html`);
@@ -39,8 +97,22 @@ fixtures_1.test.beforeEach(async ({ page }) => {
39
97
  // Assert correct overlay was dismissed
40
98
  await (0, fixtures_1.expect)(page.getByText("This is a toast message")).not.toBeVisible();
41
99
  await (0, fixtures_1.expect)(page.getByRole("button", { name: "Close" })).toBeVisible();
100
+ // Assert cache is correct
101
+ const withDom = getCacheDataWithDom({
102
+ dom: '<div id="toast" class="z-[100]">',
103
+ });
104
+ (0, fixtures_1.expect)(withDom).toBeTruthy();
105
+ const withText = getCacheDataWithTextContent({
106
+ textContent: "This is a toast message",
107
+ });
108
+ (0, fixtures_1.expect)(withText).toBeTruthy();
109
+ (0, fixtures_1.expect)(withDom).toEqual(withText);
110
+ const code = withDom?.code;
111
+ (0, fixtures_1.expect)(code).toBeDefined();
112
+ (0, fixtures_1.expect)(code).toContain("await page.getByRole('button', { name: '×' }).click()");
42
113
  });
43
- (0, fixtures_1.test)("should fallback when the overlay cannot be dismissed", async ({ page, server, }) => {
114
+ // Test is flaky - skipping it
115
+ fixtures_1.test.skip("should fallback when the overlay cannot be dismissed", async ({ page, server, }) => {
44
116
  await page.goto(`${server.baseURL}/no-overlay.html`);
45
117
  let error;
46
118
  try {
@@ -61,11 +133,6 @@ fixtures_1.test.beforeEach(async ({ page }) => {
61
133
  await page.locator("#sidebar-menu").getByText("Customise UI").click();
62
134
  await (0, fixtures_1.expect)(page.getByText("This is the Customise UI page")).toBeVisible();
63
135
  });
64
- (0, fixtures_1.test)("should be able to fill form and dismiss overlay", async ({ page, server, }) => {
65
- await page.goto(`${server.baseURL}/overlay-form.html`);
66
- await page.getByRole("button", { name: "Target" }).click();
67
- await (0, fixtures_1.expect)(page.getByText("Target was clicked")).toBeVisible();
68
- });
69
136
  fixtures_1.test.skip("should be able to dismiss multiple overlays", async ({ page, server, }) => {
70
137
  await page.goto(`${server.baseURL}/loop-to-dismiss.html`);
71
138
  await page.getByRole("button", { name: "Target" }).click();
@@ -1,4 +1,5 @@
1
1
  import type { Page } from "@playwright/test";
2
+ export declare const CACHE_FILE: string;
2
3
  export declare function setCodeToCache({ dom, text, code, }: {
3
4
  dom: string | undefined;
4
5
  text: string | undefined;
@@ -11,4 +12,5 @@ export declare function executeFromCache({ page, dom, text, }: {
11
12
  }): Promise<{
12
13
  success: boolean;
13
14
  }>;
15
+ export declare function addOverlayOption(code: string): string;
14
16
  //# sourceMappingURL=cache.d.ts.map
@@ -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;AAiB7C,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,CAkChC"}
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"}
@@ -3,11 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CACHE_FILE = void 0;
6
7
  exports.setCodeToCache = setCodeToCache;
7
8
  exports.executeFromCache = executeFromCache;
9
+ exports.addOverlayOption = addOverlayOption;
8
10
  const fs_1 = __importDefault(require("fs"));
9
11
  const path_1 = __importDefault(require("path"));
10
- const CACHE_FILE = path_1.default.join(process.cwd(), ".empiricalrun", `overlay-cache.json`);
12
+ exports.CACHE_FILE = path_1.default.join(process.cwd(), ".empiricalrun", `overlay-cache.json`);
11
13
  function normalizeString(str) {
12
14
  // Replace all whitespace sequences with a single space
13
15
  return str.replace(/\s+/g, " ").trim();
@@ -33,7 +35,7 @@ async function setCodeToCache({ dom, text, code, }) {
33
35
  data: [],
34
36
  };
35
37
  try {
36
- cache = JSON.parse(fs_1.default.readFileSync(CACHE_FILE, "utf8"));
38
+ cache = JSON.parse(fs_1.default.readFileSync(exports.CACHE_FILE, "utf8"));
37
39
  cache.data.push(obj);
38
40
  }
39
41
  catch (err) {
@@ -42,11 +44,11 @@ async function setCodeToCache({ dom, text, code, }) {
42
44
  data: [obj],
43
45
  };
44
46
  }
45
- const dir = path_1.default.dirname(CACHE_FILE);
47
+ const dir = path_1.default.dirname(exports.CACHE_FILE);
46
48
  if (!fs_1.default.existsSync(dir)) {
47
49
  fs_1.default.mkdirSync(dir, { recursive: true });
48
50
  }
49
- fs_1.default.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
51
+ fs_1.default.writeFileSync(exports.CACHE_FILE, JSON.stringify(cache, null, 2));
50
52
  }
51
53
  async function executeFromCache({ page, dom, text, }) {
52
54
  if (!dom && !text) {
@@ -54,7 +56,7 @@ async function executeFromCache({ page, dom, text, }) {
54
56
  return { success: false };
55
57
  }
56
58
  try {
57
- const cache = JSON.parse(fs_1.default.readFileSync(CACHE_FILE, "utf8"));
59
+ const cache = JSON.parse(fs_1.default.readFileSync(exports.CACHE_FILE, "utf8"));
58
60
  const match = cache.data.find((c) => {
59
61
  return (c.element.dom === (dom || "") &&
60
62
  c.element.textContent === normalizeString(text || ""));
@@ -66,7 +68,8 @@ async function executeFromCache({ page, dom, text, }) {
66
68
  console.log(`Executing from cache: "${match.code}" for element: ${dom}`);
67
69
  // Ref: https://davidwalsh.name/async-function-class
68
70
  const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
69
- const exec = new AsyncFunction("page", match.code);
71
+ const codeToExecute = addOverlayOption(match.code);
72
+ const exec = new AsyncFunction("page", codeToExecute);
70
73
  await exec(page);
71
74
  return { success: true };
72
75
  }
@@ -79,3 +82,16 @@ async function executeFromCache({ page, dom, text, }) {
79
82
  return { success: false };
80
83
  }
81
84
  }
85
+ function addOverlayOption(code) {
86
+ return code.replace(/\.(click|hover)(\s*\(\s*)(\{[^}]*\})?(\s*\))(;)?/g, (match, action, openParen, options, closeParen, semicolon) => {
87
+ if (options) {
88
+ // If options exist, add isExecutingForOverlayDismiss to them
89
+ const optionsObj = options.replace(/\s*}\s*$/, "");
90
+ return `.${action}${openParen}${optionsObj}, isExecutingForOverlayDismiss: true }${closeParen}${semicolon || ""}`;
91
+ }
92
+ else {
93
+ // If no options, add them with isExecutingForOverlayDismiss
94
+ return `.${action}${openParen}{ isExecutingForOverlayDismiss: true }${closeParen}${semicolon || ""}`;
95
+ }
96
+ });
97
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,QAsDf"}
1
+ {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,QA2Df"}
@@ -33,6 +33,11 @@ function patchClick(LocatorClass, testFn) {
33
33
  // Overwrite the stack trace to show the original click (remove patch)
34
34
  Error.captureStackTrace(originalError, LocatorClass.prototype.click);
35
35
  }
36
+ 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
+ throw originalError;
40
+ }
36
41
  if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
37
42
  // TODO: Playwright actionability checks have precedence: if an overlay blocks a
38
43
  // disabled button, the error will not show interception -- it will focus on "not enabled".
@@ -1 +1 @@
1
- {"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/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,QA+Cf"}
1
+ {"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/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,QAoDf"}
@@ -31,6 +31,11 @@ function patchHover(LocatorClass, testFn) {
31
31
  if (originalError instanceof Error) {
32
32
  Error.captureStackTrace(originalError, LocatorClass.prototype.hover);
33
33
  }
34
+ if (options?.isExecutingForOverlayDismiss) {
35
+ // While executing dismiss code from cache, we attach this custom option
36
+ // which ensures that the overlay dismissal will not trigger recursively
37
+ throw originalError;
38
+ }
34
39
  if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
35
40
  throw originalError;
36
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/playwright-utils",
3
- "version": "0.26.14",
3
+ "version": "0.26.16",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -38,9 +38,9 @@
38
38
  "mailosaur": "^8.6.1",
39
39
  "puppeteer-extra-plugin-recaptcha": "^3.6.8",
40
40
  "rimraf": "^6.0.1",
41
- "@empiricalrun/llm": "^0.17.0",
41
+ "@empiricalrun/llm": "^0.17.2",
42
42
  "@empiricalrun/r2-uploader": "^0.3.9",
43
- "@empiricalrun/test-gen": "^0.62.0"
43
+ "@empiricalrun/test-gen": "^0.64.0"
44
44
  },
45
45
  "scripts": {
46
46
  "dev": "tsc --build --watch",
@@ -1 +1 @@
1
- {"root":["./src/config.ts","./src/email.ts","./src/index.ts","./src/logger.ts","./src/playwright-extensions.ts","./src/auth/index.ts","./src/auth/types.ts","./src/captcha/index.ts","./src/captcha/vision.ts","./src/devices/types.ts","./src/overlay-tests/click.spec.ts","./src/overlay-tests/fixtures.ts","./src/overlay-tests/patch.spec.ts","./src/reporter/base.ts","./src/reporter/custom.ts","./src/reporter/queue.ts","./src/reporter/reporterV2.ts","./src/reporter/types.ts","./src/reporter/uploader.ts","./src/reporter/util.ts","./src/reporter/third_party/html-reporter-types.ts","./src/test/constants.ts","./src/test/expect.ts","./src/test/index.ts","./src/test/types.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/config.ts","./src/email.ts","./src/index.ts","./src/logger.ts","./src/playwright-extensions.ts","./src/auth/index.ts","./src/auth/types.ts","./src/captcha/index.ts","./src/captcha/vision.ts","./src/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/base.ts","./src/reporter/custom.ts","./src/reporter/queue.ts","./src/reporter/reporterV2.ts","./src/reporter/types.ts","./src/reporter/uploader.ts","./src/reporter/util.ts","./src/reporter/third_party/html-reporter-types.ts","./src/test/constants.ts","./src/test/expect.ts","./src/test/index.ts","./src/test/types.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"}