@empiricalrun/playwright-utils 0.19.32 → 0.19.34
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,23 @@
|
|
|
1
1
|
# @empiricalrun/playwright-utils
|
|
2
2
|
|
|
3
|
+
## 0.19.34
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [f3f9abf]
|
|
8
|
+
- @empiricalrun/test-gen@0.42.22
|
|
9
|
+
|
|
10
|
+
## 0.19.33
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 7b19602: feat: use overlay text content to improve overlay dismissal accuracy
|
|
15
|
+
- b6d1326: fix: z-index scaling for better overlay dismissals
|
|
16
|
+
- Updated dependencies [7b19602]
|
|
17
|
+
- Updated dependencies [b6d1326]
|
|
18
|
+
- Updated dependencies [f462463]
|
|
19
|
+
- @empiricalrun/test-gen@0.42.21
|
|
20
|
+
|
|
3
21
|
## 0.19.32
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Locator } from "@playwright/test";
|
|
2
|
-
|
|
2
|
+
type OverlayElement = {
|
|
3
3
|
interceptor: string;
|
|
4
4
|
parent: string | undefined;
|
|
5
|
-
}
|
|
5
|
+
};
|
|
6
|
+
export declare function extractInterceptingElement(errorMessage: string): OverlayElement | undefined;
|
|
6
7
|
export declare function patchClick(LocatorClass: Function & {
|
|
7
8
|
prototype: Locator;
|
|
8
9
|
}): void;
|
|
10
|
+
export {};
|
|
9
11
|
//# sourceMappingURL=click.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/click.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAQ,MAAM,kBAAkB,CAAC;AA6BtD,
|
|
1
|
+
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../../../src/test/scripts/pw-locator-patch/highlight/click.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAQ,MAAM,kBAAkB,CAAC;AA6BtD,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAiC5B;AAwGD,wBAAgB,UAAU,CAAC,YAAY,EAAE,QAAQ,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,QA2CzE"}
|
|
@@ -63,27 +63,71 @@ function extractInterceptingElement(errorMessage) {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
exports.extractInterceptingElement = extractInterceptingElement;
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
return `${interceptor}`;
|
|
76
|
-
}
|
|
66
|
+
function description(element) {
|
|
67
|
+
if (element) {
|
|
68
|
+
const { interceptor, parent } = element;
|
|
69
|
+
if (parent) {
|
|
70
|
+
return `${interceptor} inside ${parent}`;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
return `${interceptor}`;
|
|
77
74
|
}
|
|
78
75
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
}
|
|
77
|
+
async function textContent(pageRef, element) {
|
|
78
|
+
if (element) {
|
|
79
|
+
const { interceptor, parent } = element;
|
|
80
|
+
let startTag = parent ? parent : interceptor;
|
|
81
|
+
let endTag;
|
|
82
|
+
const match = startTag.match(/^<\s*([^\s>]+)/);
|
|
83
|
+
if (match) {
|
|
84
|
+
const tagName = match[1]; // "div"
|
|
85
|
+
endTag = `</${tagName}>`;
|
|
86
|
+
}
|
|
87
|
+
if (!startTag || !endTag) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
return await pageRef.evaluate((tags) => {
|
|
91
|
+
const [startTag, endTag] = tags;
|
|
92
|
+
const htmlString = `${startTag}temp${endTag}`;
|
|
93
|
+
const parser = new DOMParser();
|
|
94
|
+
const doc = parser.parseFromString(htmlString, "text/html");
|
|
95
|
+
const tempEl = doc.body.firstElementChild;
|
|
96
|
+
let selector = tempEl.tagName.toLowerCase(); // start with the tag name, e.g., 'div'
|
|
97
|
+
// If there's an id, add it (id is unique and very specific)
|
|
98
|
+
if (tempEl.id) {
|
|
99
|
+
selector += `#${tempEl.id}`;
|
|
100
|
+
}
|
|
101
|
+
// Add all classes (if any)
|
|
102
|
+
if (tempEl.classList.length > 0) {
|
|
103
|
+
tempEl.classList.forEach((cls) => {
|
|
104
|
+
selector += `.${cls}`;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// Add any other attributes that might help narrow it down.
|
|
108
|
+
// (Skip 'id' and 'class' because they are already included.)
|
|
109
|
+
Array.from(tempEl.attributes).forEach((attr) => {
|
|
110
|
+
if (attr.name === "id" || attr.name === "class")
|
|
111
|
+
return;
|
|
112
|
+
// Note: if attribute values contain special characters, consider escaping them.
|
|
113
|
+
selector += `[${attr.name}="${attr.value}"]`;
|
|
114
|
+
});
|
|
115
|
+
const realElement = document.querySelector(selector);
|
|
116
|
+
return realElement?.textContent?.trim();
|
|
117
|
+
}, [startTag, endTag]);
|
|
82
118
|
}
|
|
83
119
|
}
|
|
84
|
-
async function runAgentOnOverlay(pageRef) {
|
|
120
|
+
async function runAgentOnOverlay(pageRef, element) {
|
|
121
|
+
const content = await textContent(pageRef, element);
|
|
122
|
+
const promptAddition = content
|
|
123
|
+
? `
|
|
124
|
+
The popup can be identified with its text content:
|
|
125
|
+
${content}`
|
|
126
|
+
: ``;
|
|
85
127
|
const plannerResp = await (0, planner_1.runtimePlannerWithScreenshot)({
|
|
86
|
-
task:
|
|
128
|
+
task: `
|
|
129
|
+
Find a way to dismiss the popup. If the popup is non dismissible or there is no popup then return immediately.
|
|
130
|
+
Also note that you just need to dismiss popup and do nothing else.`,
|
|
87
131
|
conversation: [],
|
|
88
132
|
page: pageRef,
|
|
89
133
|
});
|
|
@@ -91,7 +135,12 @@ async function runAgentOnOverlay(pageRef) {
|
|
|
91
135
|
throw new Error("No active popup found");
|
|
92
136
|
}
|
|
93
137
|
await (0, run_1.createTestUsingMasterAgent)({
|
|
94
|
-
task:
|
|
138
|
+
task: `
|
|
139
|
+
Find a way to dismiss the popup. If the popup is non dismissible or there is no popup then return immediately.
|
|
140
|
+
Also note that you just need to dismiss popup and do nothing else.
|
|
141
|
+
|
|
142
|
+
${promptAddition}
|
|
143
|
+
`,
|
|
95
144
|
page: pageRef,
|
|
96
145
|
options: {
|
|
97
146
|
useActionSpecificAnnotations: true,
|
|
@@ -106,10 +155,6 @@ function annotateForReport(description) {
|
|
|
106
155
|
description,
|
|
107
156
|
});
|
|
108
157
|
}
|
|
109
|
-
function isSurvicateOverlay(errorMessage) {
|
|
110
|
-
const element = overlayElementInfo(errorMessage);
|
|
111
|
-
return element?.includes("survicate");
|
|
112
|
-
}
|
|
113
158
|
function patchClick(LocatorClass) {
|
|
114
159
|
// Check if already patched
|
|
115
160
|
if (isClickPatched.get(LocatorClass)) {
|
|
@@ -129,15 +174,16 @@ function patchClick(LocatorClass) {
|
|
|
129
174
|
if (!originalError.message?.includes(ERROR_SUBSTRING_INTERCEPTION)) {
|
|
130
175
|
throw originalError;
|
|
131
176
|
}
|
|
132
|
-
|
|
177
|
+
let overlayElement = undefined;
|
|
178
|
+
try {
|
|
179
|
+
overlayElement = extractInterceptingElement(originalError.message);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
// Ignoring this error
|
|
183
|
+
}
|
|
184
|
+
annotateForReport(`Attempting to auto-dismiss overlay: ${description(overlayElement)}`);
|
|
133
185
|
try {
|
|
134
|
-
|
|
135
|
-
// TODO: Survicate specific handling that bypasses the agent; this is temporary!
|
|
136
|
-
await this._frame._page.getByLabel("Close the survey").click();
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
await runAgentOnOverlay(this._frame._page);
|
|
140
|
-
}
|
|
186
|
+
await runAgentOnOverlay(this._frame._page, overlayElement);
|
|
141
187
|
}
|
|
142
188
|
catch (agentError) {
|
|
143
189
|
annotateForReport(`Error in overlay dismiss: ${agentError.toString()}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/playwright-utils",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.34",
|
|
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.32",
|
|
46
46
|
"@empiricalrun/r2-uploader": "^0.3.8",
|
|
47
|
-
"@empiricalrun/test-gen": "^0.42.
|
|
47
|
+
"@empiricalrun/test-gen": "^0.42.22"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"dev": "tsc --build --watch",
|