@empiricalrun/playwright-utils 0.22.4 → 0.22.6
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 +26 -0
- package/dist/overlay-tests/click.spec.js +33 -88
- package/dist/overlay-tests/fixtures.d.ts +10 -0
- package/dist/overlay-tests/fixtures.d.ts.map +1 -0
- package/dist/overlay-tests/fixtures.js +33 -0
- package/dist/overlay-tests/patch.spec.d.ts +2 -0
- package/dist/overlay-tests/patch.spec.d.ts.map +1 -0
- package/dist/overlay-tests/patch.spec.js +45 -0
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.d.ts +2 -0
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.d.ts.map +1 -1
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/index.js +32 -15
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.d.ts +2 -0
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.d.ts.map +1 -1
- package/dist/test/scripts/pw-locator-patch/dismiss-overlays/utils.js +9 -1
- package/dist/test/scripts/pw-locator-patch/highlight/click.d.ts.map +1 -1
- package/dist/test/scripts/pw-locator-patch/highlight/click.js +4 -27
- package/dist/test/scripts/pw-locator-patch/highlight/hover.d.ts.map +1 -1
- package/dist/test/scripts/pw-locator-patch/highlight/hover.js +13 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @empiricalrun/playwright-utils
|
|
2
2
|
|
|
3
|
+
## 0.22.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [6914e32]
|
|
8
|
+
- Updated dependencies [22ef805]
|
|
9
|
+
- @empiricalrun/test-gen@0.46.9
|
|
10
|
+
|
|
11
|
+
## 0.22.5
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- c8d0e94: fix: revert to older prompt for overlay dismissals
|
|
16
|
+
- 1fe5894: feat: add overlay dismissal to hover action
|
|
17
|
+
- 1922ab3: chore: Refactor playwright overlay tests structure
|
|
18
|
+
- Updated dependencies [353ee4e]
|
|
19
|
+
- Updated dependencies [4c8ec02]
|
|
20
|
+
- Updated dependencies [05329d3]
|
|
21
|
+
- Updated dependencies [46b3e75]
|
|
22
|
+
- Updated dependencies [ef4842b]
|
|
23
|
+
- Updated dependencies [ea5f6ef]
|
|
24
|
+
- Updated dependencies [8ad1b4c]
|
|
25
|
+
- Updated dependencies [1922ab3]
|
|
26
|
+
- Updated dependencies [295b611]
|
|
27
|
+
- @empiricalrun/test-gen@0.46.8
|
|
28
|
+
|
|
3
29
|
## 0.22.4
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
|
@@ -1,123 +1,68 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const test_1 = require("
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const test = test_1.test.extend({
|
|
11
|
-
server: [
|
|
12
|
-
// eslint-disable-next-line no-empty-pattern
|
|
13
|
-
async ({}, use, workerInfo) => {
|
|
14
|
-
const port = 1234 + workerInfo.workerIndex;
|
|
15
|
-
const server = http_server_1.default.createServer({
|
|
16
|
-
root: path_1.default.join(process.cwd(), "test-data"),
|
|
17
|
-
});
|
|
18
|
-
await new Promise((resolve) => {
|
|
19
|
-
server.listen(port, () => {
|
|
20
|
-
console.log(`Server running at http://localhost:${port}`);
|
|
21
|
-
resolve();
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
await use({
|
|
25
|
-
port,
|
|
26
|
-
baseURL: `http://localhost:${port}`,
|
|
27
|
-
});
|
|
28
|
-
server.close();
|
|
29
|
-
},
|
|
30
|
-
{ scope: "worker" },
|
|
31
|
-
],
|
|
3
|
+
const test_1 = require("../test");
|
|
4
|
+
const fixtures_1 = require("./fixtures");
|
|
5
|
+
fixtures_1.test.beforeEach(async ({ page }) => {
|
|
6
|
+
(0, test_1.injectLocatorHighlightScripts)(page, fixtures_1.test);
|
|
32
7
|
});
|
|
33
|
-
test
|
|
34
|
-
(0, test_2.injectLocatorHighlightScripts)(page, test);
|
|
35
|
-
});
|
|
36
|
-
test("should dismiss survicate for click", async ({ page, server }) => {
|
|
8
|
+
(0, fixtures_1.test)("should dismiss survicate for hover", async ({ page, server }) => {
|
|
37
9
|
await page.goto(`${server.baseURL}/survey.html`);
|
|
38
10
|
// Assert that Survicate and button loads
|
|
39
|
-
await (0,
|
|
11
|
+
await (0, fixtures_1.expect)(page.getByText("Start survey")).toBeVisible();
|
|
40
12
|
const targetButton = page.getByRole("button", { name: "Target" });
|
|
41
|
-
await (0,
|
|
13
|
+
await (0, fixtures_1.expect)(targetButton).toBeVisible();
|
|
42
14
|
// Get initial z-index
|
|
43
15
|
const initialZIndex = await targetButton.evaluate((el) => window.getComputedStyle(el).getPropertyValue("z-index"));
|
|
44
|
-
// Do the
|
|
45
|
-
await targetButton.
|
|
16
|
+
// Do the hover, which should pass after survey overlay is dismissed
|
|
17
|
+
await targetButton.hover();
|
|
46
18
|
// Assert z-index hasn't changed
|
|
47
19
|
const finalZIndex = await targetButton.evaluate((el) => window.getComputedStyle(el).getPropertyValue("z-index"));
|
|
48
|
-
(0,
|
|
20
|
+
(0, fixtures_1.expect)(finalZIndex).toBe(initialZIndex);
|
|
49
21
|
});
|
|
50
|
-
test("should dismiss two-step overlay for click", async ({ page, server }) => {
|
|
22
|
+
(0, fixtures_1.test)("should dismiss two-step overlay for click", async ({ page, server }) => {
|
|
51
23
|
await page.goto(`${server.baseURL}/tos.html`);
|
|
52
24
|
// Assert that button and overlay load
|
|
53
|
-
await (0,
|
|
54
|
-
await (0,
|
|
25
|
+
await (0, fixtures_1.expect)(page.getByRole("button", { name: "Target" })).toBeVisible();
|
|
26
|
+
await (0, fixtures_1.expect)(page.getByRole("heading", { name: "Terms of Service" })).toBeVisible();
|
|
55
27
|
// Do the click, which should pass
|
|
56
28
|
await page.getByRole("button", { name: "Target" }).click();
|
|
57
|
-
await (0,
|
|
29
|
+
await (0, fixtures_1.expect)(page.getByRole("heading", { name: "Terms of Service" })).not.toBeVisible();
|
|
58
30
|
});
|
|
59
|
-
test("should choose and dismiss the correct overlay", async ({ page, server, }) => {
|
|
31
|
+
(0, fixtures_1.test)("should choose and dismiss the correct overlay", async ({ page, server, }) => {
|
|
60
32
|
await page.goto(`${server.baseURL}/two-overlays.html`);
|
|
61
33
|
// Assert that button and overlays load
|
|
62
|
-
await (0,
|
|
63
|
-
await (0,
|
|
64
|
-
await (0,
|
|
34
|
+
await (0, fixtures_1.expect)(page.getByRole("button", { name: "Target" })).toBeVisible();
|
|
35
|
+
await (0, fixtures_1.expect)(page.getByText("This is a toast message")).toBeVisible();
|
|
36
|
+
await (0, fixtures_1.expect)(page.getByRole("button", { name: "Close" })).toBeVisible();
|
|
65
37
|
// Do the click, which should pass
|
|
66
38
|
await page.getByRole("button", { name: "Target" }).click();
|
|
67
39
|
// Assert correct overlay was dismissed
|
|
68
|
-
await (0,
|
|
69
|
-
await (0,
|
|
40
|
+
await (0, fixtures_1.expect)(page.getByText("This is a toast message")).not.toBeVisible();
|
|
41
|
+
await (0, fixtures_1.expect)(page.getByRole("button", { name: "Close" })).toBeVisible();
|
|
70
42
|
});
|
|
71
|
-
test("should
|
|
72
|
-
await page.goto(`${server.baseURL}/
|
|
73
|
-
let error;
|
|
74
|
-
try {
|
|
75
|
-
await page.locator("div.some-random-class-name").hover();
|
|
76
|
-
}
|
|
77
|
-
catch (e) {
|
|
78
|
-
error = e;
|
|
79
|
-
}
|
|
80
|
-
(0, test_1.expect)(error).toBeDefined();
|
|
81
|
-
(0, test_1.expect)(error.stack).toBeDefined();
|
|
82
|
-
(0, test_1.expect)(error.stack).not.toContain("pw-locator-patch");
|
|
83
|
-
(0, test_1.expect)(error.stack).not.toContain("hover.ts");
|
|
84
|
-
const firstLineThatStartsWithAt = error
|
|
85
|
-
.stack.split("\n")
|
|
86
|
-
.find((line) => line.trim().startsWith("at "));
|
|
87
|
-
(0, test_1.expect)(firstLineThatStartsWithAt).toBeDefined();
|
|
88
|
-
(0, test_1.expect)(firstLineThatStartsWithAt).toContain("overlay-tests/click.spec.ts:97");
|
|
89
|
-
});
|
|
90
|
-
test("should not return click patch method in error stack", async ({ page, server, }) => {
|
|
91
|
-
await page.goto(`${server.baseURL}/tos.html`);
|
|
43
|
+
(0, fixtures_1.test)("should return from master agent planner", async ({ page, server }) => {
|
|
44
|
+
await page.goto(`${server.baseURL}/no-overlay.html`);
|
|
92
45
|
let error;
|
|
93
46
|
try {
|
|
94
|
-
|
|
47
|
+
// Click on element that is hidden below another button, which is not
|
|
48
|
+
// dismissible
|
|
49
|
+
await page.getByRole("button", { name: "Bottom Button" }).click();
|
|
95
50
|
}
|
|
96
51
|
catch (e) {
|
|
97
52
|
error = e;
|
|
98
53
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
(0,
|
|
102
|
-
(0,
|
|
103
|
-
const firstLineThatStartsWithAt = error
|
|
104
|
-
.stack.split("\n")
|
|
105
|
-
.find((line) => line.trim().startsWith("at "));
|
|
106
|
-
(0, test_1.expect)(firstLineThatStartsWithAt).toBeDefined();
|
|
107
|
-
(0, test_1.expect)(firstLineThatStartsWithAt).toContain("overlay-tests/click.spec.ts:119");
|
|
108
|
-
});
|
|
109
|
-
test.fail("should return from master agent planner", async ({ page, server }) => {
|
|
110
|
-
await page.goto(`${server.baseURL}/no-overlay.html`);
|
|
111
|
-
// Deliberately click on a button that doesn't exist
|
|
112
|
-
await page.getByRole("button", { name: "Bottom Button" }).click();
|
|
54
|
+
// TODO: add better assertions with result from master agent
|
|
55
|
+
console.log(fixtures_1.test.info().annotations);
|
|
56
|
+
(0, fixtures_1.expect)(error).toBeDefined();
|
|
57
|
+
(0, fixtures_1.expect)(error.message).toContain('<button type="button" class="top-button">Top Button</button> intercepts pointer events');
|
|
113
58
|
});
|
|
114
|
-
test("should be able to pass through pf overlay", async ({ page, server }) => {
|
|
59
|
+
(0, fixtures_1.test)("should be able to pass through pf overlay", async ({ page, server }) => {
|
|
115
60
|
await page.goto(`${server.baseURL}/productfruits.html`);
|
|
116
61
|
await page.locator("#sidebar-menu").getByText("Customise UI").click();
|
|
117
|
-
await (0,
|
|
62
|
+
await (0, fixtures_1.expect)(page.getByText("This is the Customise UI page")).toBeVisible();
|
|
118
63
|
});
|
|
119
|
-
test("should be able to fill form and dismiss overlay", async ({ page, server, }) => {
|
|
64
|
+
(0, fixtures_1.test)("should be able to fill form and dismiss overlay", async ({ page, server, }) => {
|
|
120
65
|
await page.goto(`${server.baseURL}/overlay-form.html`);
|
|
121
66
|
await page.getByRole("button", { name: "Target" }).click();
|
|
122
|
-
await (0,
|
|
67
|
+
await (0, fixtures_1.expect)(page.getByText("Target was clicked")).toBeVisible();
|
|
123
68
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type ServerFixture = {
|
|
2
|
+
port: number;
|
|
3
|
+
baseURL: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const expect: import("@playwright/test").Expect<{}>;
|
|
6
|
+
export declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions & {
|
|
7
|
+
server: ServerFixture;
|
|
8
|
+
}>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.test = exports.expect = void 0;
|
|
7
|
+
const test_1 = require("@playwright/test");
|
|
8
|
+
const http_server_1 = __importDefault(require("http-server"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
exports.expect = test_1.test.expect;
|
|
11
|
+
exports.test = test_1.test.extend({
|
|
12
|
+
server: [
|
|
13
|
+
// eslint-disable-next-line no-empty-pattern
|
|
14
|
+
async ({}, use, workerInfo) => {
|
|
15
|
+
const port = 1234 + workerInfo.workerIndex;
|
|
16
|
+
const server = http_server_1.default.createServer({
|
|
17
|
+
root: path_1.default.join(process.cwd(), "test-data"),
|
|
18
|
+
});
|
|
19
|
+
await new Promise((resolve) => {
|
|
20
|
+
server.listen(port, () => {
|
|
21
|
+
console.log(`Server running at http://localhost:${port}`);
|
|
22
|
+
resolve();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
await use({
|
|
26
|
+
port,
|
|
27
|
+
baseURL: `http://localhost:${port}`,
|
|
28
|
+
});
|
|
29
|
+
server.close();
|
|
30
|
+
},
|
|
31
|
+
{ scope: "worker" },
|
|
32
|
+
],
|
|
33
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.spec.d.ts","sourceRoot":"","sources":["../../src/overlay-tests/patch.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("../test");
|
|
4
|
+
const fixtures_1 = require("./fixtures");
|
|
5
|
+
fixtures_1.test.beforeEach(async ({ page }) => {
|
|
6
|
+
(0, test_1.injectLocatorHighlightScripts)(page, fixtures_1.test);
|
|
7
|
+
});
|
|
8
|
+
(0, fixtures_1.test)("should not return hover patch method in error stack", async ({ page, server, }) => {
|
|
9
|
+
await page.goto(`${server.baseURL}/tos.html`);
|
|
10
|
+
let error;
|
|
11
|
+
try {
|
|
12
|
+
await page.locator("div.some-random-class-name").hover();
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
error = e;
|
|
16
|
+
}
|
|
17
|
+
(0, fixtures_1.expect)(error).toBeDefined();
|
|
18
|
+
(0, fixtures_1.expect)(error.stack).toBeDefined();
|
|
19
|
+
(0, fixtures_1.expect)(error.stack).not.toContain("pw-locator-patch");
|
|
20
|
+
(0, fixtures_1.expect)(error.stack).not.toContain("hover.ts");
|
|
21
|
+
const firstLineThatStartsWithAt = error
|
|
22
|
+
.stack.split("\n")
|
|
23
|
+
.find((line) => line.trim().startsWith("at "));
|
|
24
|
+
(0, fixtures_1.expect)(firstLineThatStartsWithAt).toBeDefined();
|
|
25
|
+
(0, fixtures_1.expect)(firstLineThatStartsWithAt).toContain("overlay-tests/patch.spec.ts:15");
|
|
26
|
+
});
|
|
27
|
+
(0, fixtures_1.test)("should not return click patch method in error stack", async ({ page, server, }) => {
|
|
28
|
+
await page.goto(`${server.baseURL}/tos.html`);
|
|
29
|
+
let error;
|
|
30
|
+
try {
|
|
31
|
+
await page.locator("div.some-random-class-name").click();
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
error = e;
|
|
35
|
+
}
|
|
36
|
+
(0, fixtures_1.expect)(error).toBeDefined();
|
|
37
|
+
(0, fixtures_1.expect)(error.stack).toBeDefined();
|
|
38
|
+
(0, fixtures_1.expect)(error.stack).not.toContain("pw-locator-patch");
|
|
39
|
+
(0, fixtures_1.expect)(error.stack).not.toContain("click.ts");
|
|
40
|
+
const firstLineThatStartsWithAt = error
|
|
41
|
+
.stack.split("\n")
|
|
42
|
+
.find((line) => line.trim().startsWith("at "));
|
|
43
|
+
(0, fixtures_1.expect)(firstLineThatStartsWithAt).toBeDefined();
|
|
44
|
+
(0, fixtures_1.expect)(firstLineThatStartsWithAt).toContain("overlay-tests/patch.spec.ts:37");
|
|
45
|
+
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Page } from "@playwright/test";
|
|
2
|
+
import type { TestFn } from "../../types";
|
|
2
3
|
import { OverlayElement } from "./types";
|
|
3
4
|
export declare function isErrorSupported(errorMessage: string | undefined): boolean;
|
|
4
5
|
export declare function runAgentOnOverlay(pageRef: Page, element: OverlayElement | undefined): Promise<void>;
|
|
5
6
|
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>;
|
|
6
8
|
//# 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":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
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;AAExC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAUzC,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,WAKhE;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,cAAc,GAAG,SAAS,iBAwDpC;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,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractInterceptingElement = exports.runAgentOnOverlay = exports.isErrorSupported = void 0;
|
|
3
|
+
exports.handleOverlayDismissal = exports.extractInterceptingElement = exports.runAgentOnOverlay = exports.isErrorSupported = void 0;
|
|
4
4
|
const run_1 = require("@empiricalrun/test-gen/agent/master/run");
|
|
5
5
|
const cache_1 = require("./cache");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
@@ -14,9 +14,19 @@ function isErrorSupported(errorMessage) {
|
|
|
14
14
|
exports.isErrorSupported = isErrorSupported;
|
|
15
15
|
async function runAgentOnOverlay(pageRef, element) {
|
|
16
16
|
const text = await (0, utils_1.textContent)(pageRef, element);
|
|
17
|
+
const promptAddition = text
|
|
18
|
+
? `
|
|
19
|
+
The popup can be identified with its text content:
|
|
20
|
+
|
|
21
|
+
<popup_text_content>
|
|
22
|
+
${text}
|
|
23
|
+
</popup_text_content>
|
|
24
|
+
`
|
|
25
|
+
: ``;
|
|
17
26
|
let task = `
|
|
18
27
|
Find a way to dismiss the popup. If the popup is non dismissible or there is no popup then return immediately.
|
|
19
|
-
Also note that you just need to dismiss popup and do nothing else
|
|
28
|
+
Also note that you just need to dismiss popup and do nothing else.
|
|
29
|
+
${promptAddition}`;
|
|
20
30
|
if ((0, utils_1.isProductFruitsOverlay)(element)) {
|
|
21
31
|
// Special handling for product fruits overlay: Overwrite the task
|
|
22
32
|
task = `
|
|
@@ -35,19 +45,6 @@ The only way to work around this is to Click on any other sidebar link element.
|
|
|
35
45
|
Don't reattempt the click on Target element, your job is done after the first click.
|
|
36
46
|
`;
|
|
37
47
|
}
|
|
38
|
-
else {
|
|
39
|
-
// Append overlay text content to the task for better context
|
|
40
|
-
const promptAddition = text
|
|
41
|
-
? `
|
|
42
|
-
The popup can be identified with its text content:
|
|
43
|
-
|
|
44
|
-
<popup_text_content>
|
|
45
|
-
${text}
|
|
46
|
-
</popup_text_content>
|
|
47
|
-
`
|
|
48
|
-
: ``;
|
|
49
|
-
task += `${promptAddition}`;
|
|
50
|
-
}
|
|
51
48
|
const { success } = await (0, cache_1.executeFromCache)({
|
|
52
49
|
page: pageRef,
|
|
53
50
|
dom: element?.interceptor,
|
|
@@ -127,3 +124,23 @@ function findAllMatches(str, regex) {
|
|
|
127
124
|
}
|
|
128
125
|
return matches;
|
|
129
126
|
}
|
|
127
|
+
async function handleOverlayDismissal(originalError, page, actionName, testFn, retryAction) {
|
|
128
|
+
let overlayElement = undefined;
|
|
129
|
+
try {
|
|
130
|
+
overlayElement = extractInterceptingElement(originalError.message);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
// Ignoring this error
|
|
134
|
+
}
|
|
135
|
+
(0, utils_1.annotateForReport)(testFn, `Attempting to auto-dismiss overlay: ${(0, utils_1.overlayDescription)(overlayElement)}`);
|
|
136
|
+
try {
|
|
137
|
+
await runAgentOnOverlay(page, overlayElement);
|
|
138
|
+
}
|
|
139
|
+
catch (agentError) {
|
|
140
|
+
(0, utils_1.annotateForReport)(testFn, `Error in overlay dismiss: ${agentError.toString()}`);
|
|
141
|
+
throw originalError;
|
|
142
|
+
}
|
|
143
|
+
(0, utils_1.annotateForReport)(testFn, `Overlay was dismissed, retrying original ${actionName} action`);
|
|
144
|
+
return await retryAction();
|
|
145
|
+
}
|
|
146
|
+
exports.handleOverlayDismissal = handleOverlayDismissal;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Page } from "@playwright/test";
|
|
2
|
+
import type { TestFn } from "../../types";
|
|
2
3
|
import { OverlayElement } from "./types";
|
|
3
4
|
export declare function overlayDescription(element: OverlayElement | undefined): string | undefined;
|
|
4
5
|
export declare function isProductFruitsOverlay(element: OverlayElement | undefined): boolean | undefined;
|
|
5
6
|
export declare function textContent(pageRef: Page, element: OverlayElement | undefined): Promise<string | undefined>;
|
|
7
|
+
export declare function annotateForReport(testFn: TestFn, description: string): void;
|
|
6
8
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,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,+BAiDpC"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/dismiss-overlays/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,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,+BAiDpC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAMpE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.textContent = exports.isProductFruitsOverlay = exports.overlayDescription = void 0;
|
|
3
|
+
exports.annotateForReport = exports.textContent = exports.isProductFruitsOverlay = exports.overlayDescription = void 0;
|
|
4
4
|
function overlayDescription(element) {
|
|
5
5
|
if (element) {
|
|
6
6
|
const { interceptor, parent } = element;
|
|
@@ -67,3 +67,11 @@ async function textContent(pageRef, element) {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
exports.textContent = textContent;
|
|
70
|
+
function annotateForReport(testFn, description) {
|
|
71
|
+
console.log(`[Overlay dismissal]: ${description}`);
|
|
72
|
+
testFn.info().annotations.push({
|
|
73
|
+
type: "auto-dismiss-overlay",
|
|
74
|
+
description,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
exports.annotateForReport = annotateForReport;
|
|
@@ -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;
|
|
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"}
|
|
@@ -2,17 +2,9 @@
|
|
|
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("../
|
|
6
|
-
const utils_2 = require("../utils");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
7
6
|
// Static flag to track if click has been patched
|
|
8
7
|
const isClickPatched = new WeakMap();
|
|
9
|
-
function annotateForReport(testFn, description) {
|
|
10
|
-
console.log(`[Overlay dismissal]: ${description}`);
|
|
11
|
-
testFn.info().annotations.push({
|
|
12
|
-
type: "auto-dismiss-overlay",
|
|
13
|
-
description,
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
8
|
function patchClick(LocatorClass, testFn) {
|
|
17
9
|
if (isClickPatched.get(LocatorClass)) {
|
|
18
10
|
return;
|
|
@@ -21,7 +13,7 @@ function patchClick(LocatorClass, testFn) {
|
|
|
21
13
|
//ref: github.com/microsoft/playwright/blob/69287f26bc514b740eac40160503d6fac8185d37/packages/playwright-core/src/client/locator.ts#L255
|
|
22
14
|
LocatorClass.prototype.click = async function (options) {
|
|
23
15
|
let result;
|
|
24
|
-
const stepName = `locator.click(${(0,
|
|
16
|
+
const stepName = `locator.click(${(0, utils_1.description)(this)})`;
|
|
25
17
|
await testFn.step(stepName, async () => {
|
|
26
18
|
try {
|
|
27
19
|
result = await originalClick.apply(this, [options]);
|
|
@@ -37,23 +29,8 @@ function patchClick(LocatorClass, testFn) {
|
|
|
37
29
|
if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
|
|
38
30
|
throw originalError;
|
|
39
31
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
overlayElement = (0, dismiss_overlays_1.extractInterceptingElement)(originalError.message);
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
// Ignoring this error
|
|
46
|
-
}
|
|
47
|
-
annotateForReport(testFn, `Attempting to auto-dismiss overlay: ${(0, utils_1.overlayDescription)(overlayElement)}`);
|
|
48
|
-
try {
|
|
49
|
-
await (0, dismiss_overlays_1.runAgentOnOverlay)(this._frame._page, overlayElement);
|
|
50
|
-
}
|
|
51
|
-
catch (agentError) {
|
|
52
|
-
annotateForReport(testFn, `Error in overlay dismiss: ${agentError.toString()}`);
|
|
53
|
-
throw originalError;
|
|
54
|
-
}
|
|
55
|
-
annotateForReport(testFn, "Overlay was dismissed, retrying original action");
|
|
56
|
-
await originalClick.apply(this, [options]);
|
|
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]));
|
|
57
34
|
}
|
|
58
35
|
}, { box: true });
|
|
59
36
|
return result;
|
|
@@ -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;
|
|
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,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.patchHover = void 0;
|
|
4
|
+
const dismiss_overlays_1 = require("../dismiss-overlays");
|
|
4
5
|
const utils_1 = require("../utils");
|
|
5
6
|
const isHoverPatched = new WeakMap();
|
|
6
7
|
function patchHover(LocatorClass, testFn) {
|
|
@@ -15,11 +16,19 @@ function patchHover(LocatorClass, testFn) {
|
|
|
15
16
|
try {
|
|
16
17
|
result = await originalHover.apply(this, [options]);
|
|
17
18
|
}
|
|
18
|
-
catch (
|
|
19
|
-
if (
|
|
20
|
-
Error.captureStackTrace(
|
|
19
|
+
catch (originalError) {
|
|
20
|
+
if (originalError instanceof Error) {
|
|
21
|
+
Error.captureStackTrace(originalError, LocatorClass.prototype.hover);
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
+
if (process.env.TEST_GEN_TOKEN) {
|
|
24
|
+
// Happening during test-gen, we ignore this
|
|
25
|
+
throw originalError;
|
|
26
|
+
}
|
|
27
|
+
if (!(0, dismiss_overlays_1.isErrorSupported)(originalError.message)) {
|
|
28
|
+
throw originalError;
|
|
29
|
+
}
|
|
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]));
|
|
23
32
|
}
|
|
24
33
|
await (0, utils_1.highlight)(this);
|
|
25
34
|
}, { box: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/playwright-utils",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.6",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"rimraf": "^6.0.1",
|
|
45
45
|
"@empiricalrun/llm": "^0.9.35",
|
|
46
46
|
"@empiricalrun/r2-uploader": "^0.3.8",
|
|
47
|
-
"@empiricalrun/test-gen": "^0.46.
|
|
47
|
+
"@empiricalrun/test-gen": "^0.46.9"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"dev": "tsc --build --watch",
|