@empiricalrun/playwright-utils 0.24.1 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @empiricalrun/playwright-utils
2
2
 
3
+ ## 0.25.0
4
+
5
+ ### Minor Changes
6
+
7
+ - be00f0b: feat: update overlay dismissal to support multiple overlays at once
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [be00f0b]
12
+ - @empiricalrun/test-gen@0.52.1
13
+
14
+ ## 0.24.2
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [a399a57]
19
+ - Updated dependencies [1b8d273]
20
+ - Updated dependencies [99b0826]
21
+ - @empiricalrun/test-gen@0.52.0
22
+ - @empiricalrun/llm@0.12.0
23
+
3
24
  ## 0.24.1
4
25
 
5
26
  ### Patch Changes
@@ -29,7 +29,7 @@ fixtures_1.test.beforeEach(async ({ page }) => {
29
29
  await (0, fixtures_1.expect)(page.getByRole("heading", { name: "Terms of Service" })).not.toBeVisible();
30
30
  });
31
31
  (0, fixtures_1.test)("should choose and dismiss the correct overlay", async ({ page, server, }) => {
32
- await page.goto(`${server.baseURL}/two-overlays.html`);
32
+ await page.goto(`${server.baseURL}/choose-an-overlay.html`);
33
33
  // Assert that button and overlays load
34
34
  await (0, fixtures_1.expect)(page.getByRole("button", { name: "Target" })).toBeVisible();
35
35
  await (0, fixtures_1.expect)(page.getByText("This is a toast message")).toBeVisible();
@@ -66,3 +66,8 @@ fixtures_1.test.beforeEach(async ({ page }) => {
66
66
  await page.getByRole("button", { name: "Target" }).click();
67
67
  await (0, fixtures_1.expect)(page.getByText("Target was clicked")).toBeVisible();
68
68
  });
69
+ (0, fixtures_1.test)("should be able to dismiss multiple overlays", async ({ page, server, }) => {
70
+ await page.goto(`${server.baseURL}/loop-to-dismiss.html`);
71
+ await page.getByRole("button", { name: "Target" }).click();
72
+ await (0, fixtures_1.expect)(page.getByText("Clicked!")).toBeVisible();
73
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/overlay-tests/fixtures.ts"],"names":[],"mappings":"AAIA,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,MAAM,uCAAc,CAAC;AAClC,eAAO,MAAM,IAAI;YAA6B,aAAa;EAsBzD,CAAC"}
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/overlay-tests/fixtures.ts"],"names":[],"mappings":"AAKA,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,MAAM,uCAAc,CAAC;AAClC,eAAO,MAAM,IAAI;YAA6B,aAAa;EAwBzD,CAAC"}
@@ -5,16 +5,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.test = exports.expect = void 0;
7
7
  const test_1 = require("@playwright/test");
8
- const http_server_1 = __importDefault(require("http-server"));
8
+ const http_1 = __importDefault(require("http"));
9
9
  const path_1 = __importDefault(require("path"));
10
+ const serve_handler_1 = __importDefault(require("serve-handler"));
10
11
  exports.expect = test_1.test.expect;
11
12
  exports.test = test_1.test.extend({
12
13
  server: [
13
14
  // eslint-disable-next-line no-empty-pattern
14
15
  async ({}, use, workerInfo) => {
15
16
  const port = 1234 + workerInfo.workerIndex;
16
- const server = http_server_1.default.createServer({
17
- root: path_1.default.join(process.cwd(), "test-data"),
17
+ const server = http_1.default.createServer((request, response) => {
18
+ return (0, serve_handler_1.default)(request, response, {
19
+ public: path_1.default.join(process.cwd(), "test-data"),
20
+ });
18
21
  });
19
22
  await new Promise((resolve) => {
20
23
  server.listen(port, () => {
@@ -1,8 +1,6 @@
1
1
  import { Page } from "@playwright/test";
2
- import type { TestFn } from "../../types";
3
2
  import { OverlayElement } from "./types";
4
3
  export declare function isErrorSupported(errorMessage: string | undefined): boolean;
5
- export declare function runAgentOnOverlay(pageRef: Page, element: OverlayElement | undefined): Promise<void>;
6
4
  export declare function extractInterceptingElement(errorMessage: string): OverlayElement | undefined;
7
- export declare function handleOverlayDismissal<T>(originalError: any, page: Page, actionName: string, testFn: TestFn, retryAction: () => Promise<T>): Promise<T>;
5
+ export declare function attemptToDismissOverlay(originalError: any, page: Page, reporter: (description: string) => void): Promise<void>;
8
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAYzC,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,cAAc,GAAG,SAAS,iBA8EpC;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B;AAwBD,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,aAAa,EAAE,GAAG,EAClB,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC,CAyBZ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIxC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAOzC,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AA0CD,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B;AAwBD,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,GAAG,EAClB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleOverlayDismissal = exports.extractInterceptingElement = exports.runAgentOnOverlay = exports.isErrorSupported = void 0;
3
+ exports.attemptToDismissOverlay = exports.extractInterceptingElement = exports.isErrorSupported = void 0;
4
4
  const run_1 = require("@empiricalrun/test-gen/agent/master/run");
5
5
  const cache_1 = require("./cache");
6
+ const prompt_1 = require("./prompt");
6
7
  const utils_1 = require("./utils");
7
8
  const ERROR_SUBSTRING_INTERCEPTION = "intercepts pointer events";
8
9
  const PREFERRED_AGENT = "openai-cua";
@@ -15,48 +16,7 @@ function isErrorSupported(errorMessage) {
15
16
  exports.isErrorSupported = isErrorSupported;
16
17
  async function runAgentOnOverlay(pageRef, element) {
17
18
  const text = await (0, utils_1.textContent)(pageRef, element);
18
- const promptAddition = text
19
- ? `
20
- In this case, the popup can be identified with its text content:
21
-
22
- <popup_text_content>
23
- ${text}
24
- </popup_text_content>
25
- `
26
- : ``;
27
- let task = `
28
- Find a way to dismiss the popup. If the popup is non dismissible or there is no popup then return immediately.
29
- Do all actions required to dismiss the popup - don't ask for user confirmation.
30
-
31
- Note that you just need to dismiss popup and DO NOTHING ELSE. If you do more steps, the remainder
32
- of the workflow will fail, because ONLY the popup is expected to be dismissed by your actions.
33
-
34
- Examples of typical popups:
35
- 1. Feature announcements, which can be generally dismissed by close/dismiss buttons.
36
- 2. Product tours which might require going through the tour steps.
37
- 3. Consents for cookies or updated terms of service, which can be dismissed by clicking on the accept/continue button.
38
- 4. Forms that capture traffic sources or persona information. Make up content for the input fields, if that's required to dismiss the popup.
39
- 5. Anything else that can be dismissed by taking a few user actions.
40
-
41
- ${promptAddition}`;
42
- if ((0, utils_1.isProductFruitsOverlay)(element)) {
43
- // Special handling for product fruits overlay: Overwrite the task
44
- task = `
45
- We are attempting to do a click action on Target element.
46
-
47
- This action is failing because our Target element is covered with another element (called Overlapper).
48
-
49
- The Overlapper element can be identifed with the following text content:
50
-
51
- <overlapper_element_text_content>
52
- ${text}
53
- </overlapper_element_text_content>
54
-
55
- The only way to work around this is to Click on any other sidebar link element.
56
-
57
- Don't reattempt the click on Target element, your job is done after the first click.
58
- `;
59
- }
19
+ const task = (0, prompt_1.getTask)(element, text);
60
20
  const { success } = await (0, cache_1.executeFromCache)({
61
21
  page: pageRef,
62
22
  dom: element?.interceptor,
@@ -91,7 +51,6 @@ Don't reattempt the click on Target element, your job is done after the first cl
91
51
  });
92
52
  }
93
53
  }
94
- exports.runAgentOnOverlay = runAgentOnOverlay;
95
54
  function extractInterceptingElement(errorMessage) {
96
55
  // This extract element and parent info from interception error message
97
56
  // Note that error message from the last retry is returned.
@@ -149,23 +108,22 @@ function findAllMatches(str, regex) {
149
108
  }
150
109
  return matches;
151
110
  }
152
- async function handleOverlayDismissal(originalError, page, actionName, testFn, retryAction) {
153
- let overlayElement = undefined;
111
+ async function attemptToDismissOverlay(originalError, page, reporter) {
112
+ let overlayElement;
154
113
  try {
155
114
  overlayElement = extractInterceptingElement(originalError.message);
156
115
  }
157
116
  catch (err) {
158
117
  // Ignoring this error
159
118
  }
160
- (0, utils_1.annotateForReport)(testFn, `Attempting to auto-dismiss overlay: ${(0, utils_1.overlayDescription)(overlayElement)}`);
119
+ const description = (0, utils_1.overlayDescription)(overlayElement);
120
+ reporter(`Attempting to auto-dismiss overlay: ${description}`);
161
121
  try {
162
122
  await runAgentOnOverlay(page, overlayElement);
163
123
  }
164
124
  catch (agentError) {
165
- (0, utils_1.annotateForReport)(testFn, `Error in overlay dismiss: ${agentError.toString()}`);
125
+ reporter(`Error during overlay dismissal agent execution: ${agentError.toString()}`);
166
126
  throw originalError;
167
127
  }
168
- (0, utils_1.annotateForReport)(testFn, `Overlay was dismissed, retrying original ${actionName} action`);
169
- return await retryAction();
170
128
  }
171
- exports.handleOverlayDismissal = handleOverlayDismissal;
129
+ exports.attemptToDismissOverlay = attemptToDismissOverlay;
@@ -0,0 +1,3 @@
1
+ import { OverlayElement } from "./types";
2
+ export declare function getTask(element: OverlayElement | undefined, text: string | undefined): string;
3
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,wBAAgB,OAAO,CACrB,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,IAAI,EAAE,MAAM,GAAG,SAAS,UAkCzB"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTask = void 0;
4
+ const utils_1 = require("./utils");
5
+ function getTask(element, text) {
6
+ if ((0, utils_1.isProductFruitsOverlay)(element)) {
7
+ // TODO: Remove this special handling with app knowledge
8
+ return promptForPFScenario(text);
9
+ }
10
+ const promptAddition = text
11
+ ? `
12
+ In this case, the popup can be identified with its text content:
13
+
14
+ <popup_text_content>
15
+ ${text}
16
+ </popup_text_content>
17
+ `
18
+ : ``;
19
+ let task = `
20
+ Find a way to dismiss the popup. If the popup is non dismissible or there is no popup then return immediately.
21
+ Do all actions required to dismiss the popup - don't ask for user confirmation.
22
+
23
+ Note that you just need to dismiss popup and DO NOTHING ELSE. If you do more steps, the remainder
24
+ of the workflow will fail, because ONLY the popup is expected to be dismissed by your actions.
25
+
26
+ Examples of typical popups:
27
+ 1. Feature announcements, which can be generally dismissed by close/dismiss buttons.
28
+ 2. Product tours which might require going through the tour steps.
29
+ 3. Consents for cookies or updated terms of service, which can be dismissed by clicking on the accept/continue button.
30
+ 4. Forms that capture traffic sources or persona information. Make up content for the input fields, if that's required to dismiss the popup.
31
+ 5. Anything else that can be dismissed by taking a few user actions.
32
+
33
+ ${promptAddition}`;
34
+ return task;
35
+ }
36
+ exports.getTask = getTask;
37
+ function promptForPFScenario(text) {
38
+ const promptAddition = text
39
+ ? `The Overlapper element can be identifed with the following text content:
40
+
41
+ <overlapper_element_text_content>
42
+ ${text}
43
+ </overlapper_element_text_content>`
44
+ : undefined;
45
+ return `
46
+ We are attempting to do a click action on Target element.
47
+
48
+ This action is failing because our Target element is covered with another element (called Overlapper).
49
+ ${promptAddition || ""}
50
+
51
+ The only way to work around this is to Click on some other sidebar link element.
52
+
53
+ Don't reattempt the click on Target element, your job is done after the first click.
54
+ `;
55
+ }
@@ -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;AAOrC,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,EAC/C,MAAM,EAAE,MAAM,QA8Cf"}
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,QA0Df"}
@@ -2,38 +2,51 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.patchClick = void 0;
4
4
  const dismiss_overlays_1 = require("../dismiss-overlays");
5
- const utils_1 = require("../utils");
5
+ const utils_1 = require("../dismiss-overlays/utils");
6
+ const utils_2 = require("../utils");
6
7
  // Static flag to track if click has been patched
7
8
  const isClickPatched = new WeakMap();
8
9
  function patchClick(LocatorClass, testFn) {
9
10
  if (isClickPatched.get(LocatorClass)) {
10
11
  return;
11
12
  }
13
+ const reporter = (description) => (0, utils_1.annotateForReport)(testFn, description);
12
14
  const originalClick = LocatorClass.prototype.click;
13
15
  //ref: github.com/microsoft/playwright/blob/69287f26bc514b740eac40160503d6fac8185d37/packages/playwright-core/src/client/locator.ts#L255
14
16
  LocatorClass.prototype.click = async function (options) {
15
- let result;
16
- const stepName = `locator.click(${(0, utils_1.description)(this)})`;
17
- await testFn.step(stepName, async () => {
18
- try {
19
- result = await originalClick.apply(this, [options]);
20
- }
21
- catch (originalError) {
22
- if (originalError instanceof Error) {
23
- Error.captureStackTrace(originalError, LocatorClass.prototype.click);
24
- }
25
- if (process.env.TEST_GEN_TOKEN) {
26
- // Happening during test-gen, we ignore this
27
- throw originalError;
17
+ const stepName = `locator.click(${(0, utils_2.description)(this)})`;
18
+ return await testFn.step(stepName, async () => {
19
+ let overlayAttemptsRemaining = 2;
20
+ let originalError;
21
+ while (overlayAttemptsRemaining >= 0) {
22
+ overlayAttemptsRemaining--;
23
+ try {
24
+ let result = await originalClick.apply(this, [options]);
25
+ return result; // If click is successful, we're done -- just return
28
26
  }
29
- if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
30
- throw originalError;
27
+ catch (error) {
28
+ originalError = error;
29
+ if (originalError instanceof Error) {
30
+ // Overwrite the stack trace to show the original click (remove patch)
31
+ Error.captureStackTrace(originalError, LocatorClass.prototype.click);
32
+ }
33
+ if (process.env.TEST_GEN_TOKEN) {
34
+ // We skip overlay dismissal if its happening during test-gen
35
+ throw originalError;
36
+ }
37
+ if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
38
+ // TODO: Playwright actionability checks have precedence: if an overlay blocks a
39
+ // disabled button, the error will not show interception -- it will focus on "not enabled".
40
+ // This will cause our overlay dismissal to not run.
41
+ throw originalError;
42
+ }
43
+ await (0, dismiss_overlays_1.attemptToDismissOverlay)(originalError, this._frame._page, reporter);
44
+ // Dismissal attempt finished (implicitly successful if no error thrown)
45
+ reporter(`Overlay dismissal attempted, retrying original action.`);
31
46
  }
32
- // Now that we've confirmed this is an overlay-related error, delegate to handleOverlayDismissal
33
- result = await (0, dismiss_overlays_1.handleOverlayDismissal)(originalError, this._frame._page, "click", testFn, () => originalClick.apply(this, [options]));
34
47
  }
48
+ throw originalError;
35
49
  }, { box: true });
36
- return result;
37
50
  };
38
51
  isClickPatched.set(LocatorClass, true);
39
52
  }
@@ -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;AAMrC,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,QAmDf"}
@@ -2,37 +2,45 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.patchHover = void 0;
4
4
  const dismiss_overlays_1 = require("../dismiss-overlays");
5
- const utils_1 = require("../utils");
5
+ const utils_1 = require("../dismiss-overlays/utils");
6
+ const utils_2 = require("../utils");
6
7
  const isHoverPatched = new WeakMap();
7
8
  function patchHover(LocatorClass, testFn) {
8
9
  if (isHoverPatched.get(LocatorClass)) {
9
10
  return;
10
11
  }
12
+ const reporter = (description) => (0, utils_1.annotateForReport)(testFn, description);
11
13
  const originalHover = LocatorClass.prototype.hover;
12
14
  LocatorClass.prototype.hover = async function (options) {
13
- let result;
14
- const stepName = `locator.hover(${(0, utils_1.description)(this)})`;
15
- await testFn.step(stepName, async () => {
16
- try {
17
- result = await originalHover.apply(this, [options]);
18
- }
19
- catch (originalError) {
20
- if (originalError instanceof Error) {
21
- Error.captureStackTrace(originalError, LocatorClass.prototype.hover);
22
- }
23
- if (process.env.TEST_GEN_TOKEN) {
24
- // Happening during test-gen, we ignore this
25
- throw originalError;
15
+ const stepName = `locator.hover(${(0, utils_2.description)(this)})`;
16
+ return await testFn.step(stepName, async () => {
17
+ let overlayAttemptsRemaining = 2;
18
+ let originalError;
19
+ while (overlayAttemptsRemaining >= 0) {
20
+ overlayAttemptsRemaining--;
21
+ try {
22
+ let result = await originalHover.apply(this, [options]);
23
+ await (0, utils_2.highlight)(this);
24
+ return result; // If hover is successful, we're done -- just return
26
25
  }
27
- if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
28
- throw originalError;
26
+ catch (error) {
27
+ originalError = error;
28
+ if (originalError instanceof Error) {
29
+ Error.captureStackTrace(originalError, LocatorClass.prototype.hover);
30
+ }
31
+ if (process.env.TEST_GEN_TOKEN) {
32
+ // We skip overlay dismissal if its happening during test-gen
33
+ throw originalError;
34
+ }
35
+ if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
36
+ throw originalError;
37
+ }
38
+ await (0, dismiss_overlays_1.attemptToDismissOverlay)(originalError, this._frame._page, reporter);
39
+ reporter(`Overlay dismissal attempted, retrying original action.`);
29
40
  }
30
- // Now that we've confirmed this is an overlay-related error, delegate to handleOverlayDismissal
31
- result = await (0, dismiss_overlays_1.handleOverlayDismissal)(originalError, this._frame._page, "hover", testFn, () => originalHover.apply(this, [options]));
32
41
  }
33
- await (0, utils_1.highlight)(this);
42
+ throw originalError;
34
43
  }, { box: true });
35
- return result;
36
44
  };
37
45
  isHoverPatched.set(LocatorClass, true);
38
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/playwright-utils",
3
- "version": "0.24.1",
3
+ "version": "0.25.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -22,16 +22,16 @@
22
22
  },
23
23
  "author": "Empirical Team <hey@empirical.run>",
24
24
  "devDependencies": {
25
- "playwright-core": "1.47.1",
26
25
  "@playwright/test": "1.47.1",
27
26
  "@types/async-retry": "^1.4.8",
28
27
  "@types/babel__code-frame": "^7.0.6",
29
28
  "@types/console-log-level": "^1.4.5",
30
- "@types/http-server": "^0.12.4",
31
29
  "@types/md5": "^2.3.5",
32
30
  "@types/mime": "3.0.0",
33
31
  "@types/node": "^20.14.9",
34
- "http-server": "^14.1.1"
32
+ "@types/serve-handler": "^6.1.4",
33
+ "playwright-core": "1.47.1",
34
+ "serve-handler": "^6.1.6"
35
35
  },
36
36
  "dependencies": {
37
37
  "@babel/code-frame": "^7.24.7",
@@ -42,9 +42,9 @@
42
42
  "mime": "3.0.0",
43
43
  "puppeteer-extra-plugin-recaptcha": "^3.6.8",
44
44
  "rimraf": "^6.0.1",
45
- "@empiricalrun/llm": "^0.11.5",
45
+ "@empiricalrun/llm": "^0.12.0",
46
46
  "@empiricalrun/r2-uploader": "^0.3.8",
47
- "@empiricalrun/test-gen": "^0.51.6"
47
+ "@empiricalrun/test-gen": "^0.52.1"
48
48
  },
49
49
  "scripts": {
50
50
  "dev": "tsc --build --watch",