@xpert-ai/chatkit-host-automation 0.3.3 → 0.3.4
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/dist/index.d.ts +45 -0
- package/dist/index.js +488 -238
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,15 @@ export declare function createHostPageAutomationClientToolHandler(options?: Host
|
|
|
4
4
|
|
|
5
5
|
export declare const HOST_PAGE_AUTOMATION_TOOL_NAMES: readonly ["host_page_snapshot", "host_page_click", "host_page_fill", "host_page_press", "host_page_select", "host_page_scroll", "host_page_navigate", "host_page_hover", "host_page_focus", "host_page_pointer", "host_page_screenshot", "host_page_wait_for"];
|
|
6
6
|
|
|
7
|
+
declare type HostPageAutomationClickEffectContext = {
|
|
8
|
+
point: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
};
|
|
12
|
+
target: Element;
|
|
13
|
+
requested?: Element;
|
|
14
|
+
};
|
|
15
|
+
|
|
7
16
|
export declare type HostPageAutomationClientToolCall = {
|
|
8
17
|
name: string;
|
|
9
18
|
params?: Record<string, unknown>;
|
|
@@ -18,10 +27,19 @@ export declare type HostPageAutomationElementSnapshot = {
|
|
|
18
27
|
tag: string;
|
|
19
28
|
role?: string;
|
|
20
29
|
name?: string;
|
|
30
|
+
label?: string;
|
|
31
|
+
groupLabel?: string;
|
|
21
32
|
text?: string;
|
|
22
33
|
nearbyText?: string[];
|
|
23
34
|
testId?: string;
|
|
24
35
|
value?: string;
|
|
36
|
+
selectedLabel?: string;
|
|
37
|
+
options?: Array<{
|
|
38
|
+
label: string;
|
|
39
|
+
value: string;
|
|
40
|
+
selected?: boolean;
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
}>;
|
|
25
43
|
placeholder?: string;
|
|
26
44
|
selector?: string;
|
|
27
45
|
disabled?: boolean;
|
|
@@ -77,6 +95,7 @@ export declare class HostPageAutomationExecutor {
|
|
|
77
95
|
private focus;
|
|
78
96
|
private pointer;
|
|
79
97
|
private screenshot;
|
|
98
|
+
private showVisualEffect;
|
|
80
99
|
private waitFor;
|
|
81
100
|
private tryResolveElement;
|
|
82
101
|
private describeElement;
|
|
@@ -86,10 +105,36 @@ export declare type HostPageAutomationOptions = {
|
|
|
86
105
|
enabled?: boolean;
|
|
87
106
|
root?: Document | ShadowRoot;
|
|
88
107
|
allowNavigation?: boolean;
|
|
108
|
+
showVisualEffect?: (context: HostPageAutomationVisualEffectContext) => Promise<void> | void;
|
|
109
|
+
showClickEffect?: (context: HostPageAutomationClickEffectContext) => Promise<void> | void;
|
|
89
110
|
};
|
|
90
111
|
|
|
91
112
|
export declare type HostPageAutomationToolName = (typeof HOST_PAGE_AUTOMATION_TOOL_NAMES)[number];
|
|
92
113
|
|
|
114
|
+
declare type HostPageAutomationVisualEffectContext = {
|
|
115
|
+
type: HostPageAutomationVisualEffectType;
|
|
116
|
+
point?: {
|
|
117
|
+
x: number;
|
|
118
|
+
y: number;
|
|
119
|
+
};
|
|
120
|
+
anchor?: 'target' | 'point';
|
|
121
|
+
target?: Element;
|
|
122
|
+
requested?: Element;
|
|
123
|
+
action?: 'move' | 'down' | 'up' | 'click';
|
|
124
|
+
key?: string;
|
|
125
|
+
value?: string;
|
|
126
|
+
values?: string[];
|
|
127
|
+
state?: 'attached' | 'visible' | 'hidden' | 'detached';
|
|
128
|
+
deltaX?: number;
|
|
129
|
+
deltaY?: number;
|
|
130
|
+
scroll?: {
|
|
131
|
+
x: number;
|
|
132
|
+
y: number;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
declare type HostPageAutomationVisualEffectType = 'click' | 'fill' | 'select' | 'press' | 'scroll' | 'hover' | 'focus' | 'pointer' | 'wait_for' | 'screenshot';
|
|
137
|
+
|
|
93
138
|
export declare type HostPageSnapshot = {
|
|
94
139
|
url: string;
|
|
95
140
|
title: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const tt = [
|
|
2
2
|
"host_page_snapshot",
|
|
3
3
|
"host_page_click",
|
|
4
4
|
"host_page_fill",
|
|
@@ -11,9 +11,9 @@ const z = [
|
|
|
11
11
|
"host_page_pointer",
|
|
12
12
|
"host_page_screenshot",
|
|
13
13
|
"host_page_wait_for"
|
|
14
|
-
],
|
|
15
|
-
|
|
16
|
-
),
|
|
14
|
+
], et = new Set(
|
|
15
|
+
tt
|
|
16
|
+
), nt = [
|
|
17
17
|
"a[href]",
|
|
18
18
|
"button",
|
|
19
19
|
"input",
|
|
@@ -28,116 +28,243 @@ const z = [
|
|
|
28
28
|
"[data-testid]",
|
|
29
29
|
"[data-test-id]",
|
|
30
30
|
"[data-qa]"
|
|
31
|
-
].join(","),
|
|
32
|
-
function
|
|
33
|
-
return
|
|
31
|
+
].join(","), $ = 100, ot = 1e4, rt = 6e4;
|
|
32
|
+
function it(t) {
|
|
33
|
+
return et.has(t);
|
|
34
34
|
}
|
|
35
|
-
function
|
|
35
|
+
function m(t) {
|
|
36
36
|
return t instanceof Document ? t : t.ownerDocument;
|
|
37
37
|
}
|
|
38
|
-
function
|
|
39
|
-
return
|
|
38
|
+
function H(t) {
|
|
39
|
+
return m(t).defaultView ?? window;
|
|
40
40
|
}
|
|
41
|
-
function
|
|
41
|
+
function y(t) {
|
|
42
42
|
return typeof t == "object" && t !== null && !Array.isArray(t) ? t : {};
|
|
43
43
|
}
|
|
44
|
-
function
|
|
44
|
+
function O(t, e) {
|
|
45
45
|
if (typeof t != "string" || t.trim() === "")
|
|
46
46
|
throw new Error(`${e} must be a non-empty string.`);
|
|
47
47
|
return t;
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function v(t) {
|
|
50
50
|
return typeof t == "string" && t.trim() ? t : void 0;
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function st(t) {
|
|
53
53
|
return typeof t == "number" && Number.isInteger(t) ? t : void 0;
|
|
54
54
|
}
|
|
55
|
-
function
|
|
55
|
+
function C(t, e) {
|
|
56
56
|
if (typeof t != "number" || !Number.isFinite(t))
|
|
57
57
|
throw new Error(`${e} must be a finite number.`);
|
|
58
58
|
return t;
|
|
59
59
|
}
|
|
60
|
-
function
|
|
60
|
+
function _(t) {
|
|
61
61
|
return typeof t == "number" && Number.isFinite(t) ? t : void 0;
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function W(t, e) {
|
|
64
64
|
return typeof t == "string" && e.includes(t) ? t : void 0;
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function ct(t) {
|
|
67
67
|
if (typeof t == "string")
|
|
68
68
|
return [t];
|
|
69
69
|
if (Array.isArray(t) && t.every((e) => typeof e == "string"))
|
|
70
70
|
return t;
|
|
71
71
|
throw new Error("value or values must be a string or an array of strings.");
|
|
72
72
|
}
|
|
73
|
-
function
|
|
73
|
+
function b(t) {
|
|
74
74
|
const e = (t.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
75
75
|
return e ? e.slice(0, 160) : void 0;
|
|
76
76
|
}
|
|
77
|
-
function
|
|
77
|
+
function R(t) {
|
|
78
78
|
const e = Array.from(t.childNodes).filter((n) => n.nodeType === Node.TEXT_NODE).map((n) => n.textContent ?? "").join(" ").replace(/\s+/g, " ").trim();
|
|
79
79
|
return e ? e.slice(0, 160) : void 0;
|
|
80
80
|
}
|
|
81
|
-
function
|
|
81
|
+
function at(t) {
|
|
82
82
|
if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement)
|
|
83
83
|
return t.value;
|
|
84
84
|
}
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
function G(t) {
|
|
86
|
+
return t instanceof HTMLInputElement && (t.type === "checkbox" || t.type === "radio");
|
|
87
|
+
}
|
|
88
|
+
function lt(t) {
|
|
89
|
+
return t instanceof HTMLInputElement || t instanceof HTMLSelectElement || t instanceof HTMLTextAreaElement ? Array.from(t.labels ?? []) : [];
|
|
90
|
+
}
|
|
91
|
+
function ut(t, e) {
|
|
92
|
+
var o;
|
|
93
|
+
return (((o = t.getAttribute(e)) == null ? void 0 : o.trim().split(/\s+/)) ?? []).map((r) => t.ownerDocument.getElementById(r)).filter((r) => !!r).map((r) => b(r)).filter((r) => !!r);
|
|
94
|
+
}
|
|
95
|
+
function ft(t) {
|
|
96
|
+
const e = ut(t, "aria-labelledby");
|
|
97
|
+
if (e.length > 0)
|
|
98
|
+
return e.join(" ").slice(0, 160);
|
|
99
|
+
const n = lt(t).map((o) => b(o)).filter((o) => !!o);
|
|
100
|
+
if (n.length > 0)
|
|
101
|
+
return n.join(" ").slice(0, 160);
|
|
102
|
+
}
|
|
103
|
+
function dt(t) {
|
|
104
|
+
const e = [];
|
|
105
|
+
let n = t.nextSibling;
|
|
106
|
+
for (; n; ) {
|
|
107
|
+
if (n.nodeType === Node.TEXT_NODE) {
|
|
108
|
+
const r = (n.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
109
|
+
r && e.push(r);
|
|
110
|
+
} else {
|
|
111
|
+
if (n.nodeType === Node.ELEMENT_NODE && n.tagName.toLowerCase() === "br")
|
|
112
|
+
break;
|
|
113
|
+
if (n.nodeType === Node.ELEMENT_NODE) {
|
|
114
|
+
const r = n;
|
|
115
|
+
if (r.matches(
|
|
116
|
+
'input,textarea,select,button,a[href],[role="button"],[role="link"]'
|
|
117
|
+
))
|
|
118
|
+
break;
|
|
119
|
+
const c = b(r);
|
|
120
|
+
c && e.push(c);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (e.join(" ").length >= 120)
|
|
125
|
+
break;
|
|
126
|
+
n = n.nextSibling;
|
|
96
127
|
}
|
|
97
|
-
const o =
|
|
98
|
-
return o
|
|
128
|
+
const o = e.join(" ").replace(/\s+/g, " ").trim();
|
|
129
|
+
return o ? o.slice(0, 160) : void 0;
|
|
99
130
|
}
|
|
100
|
-
function
|
|
101
|
-
|
|
131
|
+
function X(t, e) {
|
|
132
|
+
var d;
|
|
133
|
+
const n = t.ownerDocument, o = n.body;
|
|
134
|
+
if (!o)
|
|
135
|
+
return;
|
|
136
|
+
const r = t.getBoundingClientRect();
|
|
137
|
+
if (r.width <= 0 || r.height <= 0)
|
|
138
|
+
return;
|
|
139
|
+
const c = r.top + r.height / 2, i = [], s = n.createTreeWalker(o, NodeFilter.SHOW_ELEMENT);
|
|
140
|
+
let a = s.nextNode();
|
|
141
|
+
for (; a; ) {
|
|
142
|
+
const l = a;
|
|
143
|
+
if (l !== t && !l.contains(t) && B(l)) {
|
|
144
|
+
const u = l.getBoundingClientRect(), f = R(l) ?? b(l);
|
|
145
|
+
if (f) {
|
|
146
|
+
const h = u.top + u.height / 2, E = Math.abs(h - c) <= Math.max(28, r.height * 1.25), g = e === "left" ? r.left - u.right : u.left - r.right;
|
|
147
|
+
E && g >= -8 && g <= 240 && i.push({
|
|
148
|
+
text: f,
|
|
149
|
+
score: Math.abs(g) + Math.abs(h - c)
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
a = s.nextNode();
|
|
154
|
+
}
|
|
155
|
+
return (d = i.sort((l, u) => l.score - u.score)[0]) == null ? void 0 : d.text;
|
|
156
|
+
}
|
|
157
|
+
function z(t) {
|
|
158
|
+
if (!(t instanceof HTMLInputElement || t instanceof HTMLSelectElement || t instanceof HTMLTextAreaElement))
|
|
159
|
+
return;
|
|
160
|
+
const e = ft(t);
|
|
161
|
+
return e || (G(t) ? X(t, "right") ?? dt(t) ?? N(t)[0] : X(t, "left") ?? N(t)[0]);
|
|
162
|
+
}
|
|
163
|
+
function j(t, e) {
|
|
164
|
+
const n = e.trim().toLowerCase();
|
|
165
|
+
return t instanceof HTMLInputElement && t.type === "radio" ? n === "radio" || n === "radio button" : t instanceof HTMLInputElement && t.type === "checkbox" ? n === "checkbox" || n === "check box" : t instanceof HTMLSelectElement ? n === "select" || n === "select menu" || n === "combobox" || n === "combo box" : !1;
|
|
166
|
+
}
|
|
167
|
+
function x(t) {
|
|
168
|
+
const e = z(t), n = t.getAttribute("aria-label");
|
|
169
|
+
if (n != null && n.trim() && !j(t, n))
|
|
170
|
+
return n.trim();
|
|
171
|
+
const o = t.getAttribute("title");
|
|
172
|
+
if (o != null && o.trim() && !j(t, o))
|
|
173
|
+
return o.trim();
|
|
174
|
+
if (e)
|
|
175
|
+
return e;
|
|
176
|
+
const r = N(t)[0];
|
|
177
|
+
return r || b(t);
|
|
178
|
+
}
|
|
179
|
+
function B(t) {
|
|
180
|
+
if (!(t instanceof HTMLElement || t instanceof SVGElement) || !T(t) || t.matches(
|
|
102
181
|
'input,textarea,select,button,a[href],[role="button"],[role="link"]'
|
|
103
182
|
))
|
|
104
183
|
return !1;
|
|
105
|
-
const e =
|
|
184
|
+
const e = R(t) ?? b(t);
|
|
106
185
|
return !!(e && e.length <= 120);
|
|
107
186
|
}
|
|
108
|
-
function
|
|
187
|
+
function ht(t) {
|
|
188
|
+
var u;
|
|
189
|
+
if (!G(t))
|
|
190
|
+
return;
|
|
191
|
+
const e = t.closest("fieldset"), n = e == null ? void 0 : e.querySelector("legend"), o = n ? b(n) : void 0;
|
|
192
|
+
if (o)
|
|
193
|
+
return o;
|
|
194
|
+
const r = t.ownerDocument, c = r.body;
|
|
195
|
+
if (!c)
|
|
196
|
+
return;
|
|
197
|
+
const i = t.getBoundingClientRect();
|
|
198
|
+
if (i.width <= 0 || i.height <= 0)
|
|
199
|
+
return;
|
|
200
|
+
const s = i.left + i.width / 2, a = [], d = r.createTreeWalker(c, NodeFilter.SHOW_ELEMENT);
|
|
201
|
+
let l = d.nextNode();
|
|
202
|
+
for (; l; ) {
|
|
203
|
+
const f = l;
|
|
204
|
+
if (f !== t && !f.contains(t) && f.matches('legend,strong,b,[role="heading"],h1,h2,h3,h4,h5,h6') && B(f)) {
|
|
205
|
+
const h = f.getBoundingClientRect(), E = R(f) ?? b(f);
|
|
206
|
+
if (E && h.bottom <= i.top + 8) {
|
|
207
|
+
const g = i.top - h.bottom, w = h.left + h.width / 2;
|
|
208
|
+
g <= 160 && w >= i.left - 120 && w <= i.right + 320 && a.push({
|
|
209
|
+
text: E,
|
|
210
|
+
score: g + Math.abs(w - s) * 0.25
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
l = d.nextNode();
|
|
215
|
+
}
|
|
216
|
+
return (u = a.sort((f, h) => f.score - h.score)[0]) == null ? void 0 : u.text;
|
|
217
|
+
}
|
|
218
|
+
function gt(t) {
|
|
219
|
+
if (!(t instanceof HTMLSelectElement))
|
|
220
|
+
return;
|
|
221
|
+
const e = Array.from(t.options).map((n) => ({
|
|
222
|
+
label: ((n.label || n.textContent || n.value).replace(/\s+/g, " ").trim() || n.value).slice(0, 160),
|
|
223
|
+
value: n.value,
|
|
224
|
+
selected: n.selected || void 0,
|
|
225
|
+
disabled: n.disabled || void 0
|
|
226
|
+
}));
|
|
227
|
+
return e.length ? e : void 0;
|
|
228
|
+
}
|
|
229
|
+
function pt(t) {
|
|
230
|
+
if (!(t instanceof HTMLSelectElement))
|
|
231
|
+
return;
|
|
232
|
+
const e = t.selectedOptions[0], n = e ? (e.label || e.textContent || e.value).replace(/\s+/g, " ").trim() : void 0;
|
|
233
|
+
return n ? n.slice(0, 160) : void 0;
|
|
234
|
+
}
|
|
235
|
+
function N(t) {
|
|
109
236
|
const e = t.ownerDocument, n = e.body;
|
|
110
237
|
if (!n)
|
|
111
238
|
return [];
|
|
112
239
|
const o = t.getBoundingClientRect();
|
|
113
240
|
if (o.width <= 0 || o.height <= 0)
|
|
114
241
|
return [];
|
|
115
|
-
const r = o.top + o.height / 2, c = o.left + o.width / 2,
|
|
116
|
-
let a =
|
|
242
|
+
const r = o.top + o.height / 2, c = o.left + o.width / 2, i = [], s = e.createTreeWalker(n, NodeFilter.SHOW_ELEMENT);
|
|
243
|
+
let a = s.nextNode();
|
|
117
244
|
for (; a; ) {
|
|
118
245
|
const l = a;
|
|
119
|
-
if (l !== t &&
|
|
120
|
-
const u = l.getBoundingClientRect(), f =
|
|
246
|
+
if (l !== t && !l.contains(t) && B(l)) {
|
|
247
|
+
const u = l.getBoundingClientRect(), f = R(l) ?? b(l);
|
|
121
248
|
if (f) {
|
|
122
|
-
const
|
|
123
|
-
if (
|
|
124
|
-
const
|
|
125
|
-
|
|
249
|
+
const h = u.top + u.height / 2, E = u.left + u.width / 2, g = u.right <= o.left + 12 && Math.abs(h - r) <= Math.max(28, o.height * 1.25), w = u.left >= o.right - 8 && u.left - o.right <= 240 && Math.abs(h - r) <= Math.max(28, o.height * 1.25), q = u.bottom <= o.top + 8 && o.top - u.bottom <= 80 && E >= o.left - 80 && E <= o.right + 80;
|
|
250
|
+
if (g || w || q) {
|
|
251
|
+
const Z = g ? o.left - u.right + Math.abs(h - r) : w ? u.left - o.right + Math.abs(h - r) : o.top - u.bottom + Math.abs(E - c);
|
|
252
|
+
i.push({
|
|
126
253
|
text: f,
|
|
127
|
-
score:
|
|
254
|
+
score: Z + (g ? 0 : w ? 5 : 100)
|
|
128
255
|
});
|
|
129
256
|
}
|
|
130
257
|
}
|
|
131
258
|
}
|
|
132
|
-
a =
|
|
259
|
+
a = s.nextNode();
|
|
133
260
|
}
|
|
134
261
|
const d = /* @__PURE__ */ new Set();
|
|
135
|
-
return
|
|
262
|
+
return i.sort((l, u) => l.score - u.score).map((l) => l.text).filter((l) => d.has(l) ? !1 : (d.add(l), !0)).slice(0, 4);
|
|
136
263
|
}
|
|
137
|
-
function
|
|
264
|
+
function Et(t) {
|
|
138
265
|
return t.getAttribute("data-testid") ?? t.getAttribute("data-test-id") ?? t.getAttribute("data-qa") ?? void 0;
|
|
139
266
|
}
|
|
140
|
-
function
|
|
267
|
+
function M(t) {
|
|
141
268
|
const e = t.getAttribute("role");
|
|
142
269
|
if (e != null && e.trim())
|
|
143
270
|
return e.trim();
|
|
@@ -161,13 +288,13 @@ function x(t) {
|
|
|
161
288
|
return "textbox";
|
|
162
289
|
}
|
|
163
290
|
}
|
|
164
|
-
function
|
|
291
|
+
function K(t) {
|
|
165
292
|
return t instanceof HTMLButtonElement || t instanceof HTMLInputElement || t instanceof HTMLSelectElement || t instanceof HTMLTextAreaElement ? t.disabled || void 0 : t.getAttribute("aria-disabled") === "true" || void 0;
|
|
166
293
|
}
|
|
167
|
-
function
|
|
294
|
+
function bt(t) {
|
|
168
295
|
return t instanceof HTMLInputElement && (t.type === "checkbox" || t.type === "radio") ? t.checked : void 0;
|
|
169
296
|
}
|
|
170
|
-
function
|
|
297
|
+
function wt(t) {
|
|
171
298
|
const e = k(t);
|
|
172
299
|
if (!(e.width <= 0 || e.height <= 0))
|
|
173
300
|
return {
|
|
@@ -175,37 +302,37 @@ function st(t) {
|
|
|
175
302
|
y: e.y + e.height / 2
|
|
176
303
|
};
|
|
177
304
|
}
|
|
178
|
-
function
|
|
305
|
+
function U(t) {
|
|
179
306
|
return {
|
|
180
307
|
tag: t.tagName.toLowerCase(),
|
|
181
|
-
role:
|
|
182
|
-
name:
|
|
183
|
-
selector:
|
|
308
|
+
role: M(t),
|
|
309
|
+
name: x(t),
|
|
310
|
+
selector: D(t)
|
|
184
311
|
};
|
|
185
312
|
}
|
|
186
|
-
function
|
|
313
|
+
function T(t) {
|
|
187
314
|
if (!(t instanceof HTMLElement || t instanceof SVGElement) || t instanceof HTMLElement && t.hidden)
|
|
188
315
|
return !1;
|
|
189
316
|
const e = t.ownerDocument.defaultView, n = e == null ? void 0 : e.getComputedStyle(t);
|
|
190
317
|
return !(n && (n.display === "none" || n.visibility === "hidden" || n.opacity === "0"));
|
|
191
318
|
}
|
|
192
|
-
function
|
|
193
|
-
return t.matches(
|
|
319
|
+
function J(t) {
|
|
320
|
+
return t.matches(nt) && T(t);
|
|
194
321
|
}
|
|
195
|
-
function
|
|
196
|
-
return
|
|
322
|
+
function yt(t) {
|
|
323
|
+
return K(t) !== !0;
|
|
197
324
|
}
|
|
198
|
-
function
|
|
325
|
+
function mt(t) {
|
|
199
326
|
var n;
|
|
200
|
-
if (
|
|
327
|
+
if (J(t))
|
|
201
328
|
return !0;
|
|
202
329
|
if (!(t instanceof HTMLElement))
|
|
203
330
|
return !1;
|
|
204
331
|
const e = (n = t.ownerDocument.defaultView) == null ? void 0 : n.getComputedStyle(t);
|
|
205
|
-
return ((e == null ? void 0 : e.cursor) === "pointer" || !!t.onclick) &&
|
|
332
|
+
return ((e == null ? void 0 : e.cursor) === "pointer" || !!t.onclick) && T(t);
|
|
206
333
|
}
|
|
207
334
|
function k(t) {
|
|
208
|
-
var c,
|
|
335
|
+
var c, i;
|
|
209
336
|
const e = t.getBoundingClientRect();
|
|
210
337
|
let n = e.left, o = e.top, r = null;
|
|
211
338
|
try {
|
|
@@ -214,10 +341,10 @@ function k(t) {
|
|
|
214
341
|
r = null;
|
|
215
342
|
}
|
|
216
343
|
for (; r; ) {
|
|
217
|
-
const
|
|
218
|
-
n +=
|
|
344
|
+
const s = r.getBoundingClientRect();
|
|
345
|
+
n += s.left, o += s.top;
|
|
219
346
|
try {
|
|
220
|
-
r = ((
|
|
347
|
+
r = ((i = r.ownerDocument.defaultView) == null ? void 0 : i.frameElement) ?? null;
|
|
221
348
|
} catch {
|
|
222
349
|
r = null;
|
|
223
350
|
}
|
|
@@ -229,7 +356,7 @@ function k(t) {
|
|
|
229
356
|
height: e.height
|
|
230
357
|
};
|
|
231
358
|
}
|
|
232
|
-
function
|
|
359
|
+
function D(t) {
|
|
233
360
|
const e = (o) => typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(o) : o.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
|
|
234
361
|
if (t.id)
|
|
235
362
|
return `#${e(t.id)}`;
|
|
@@ -243,7 +370,7 @@ function P(t) {
|
|
|
243
370
|
n
|
|
244
371
|
)}"]` : t.tagName.toLowerCase();
|
|
245
372
|
}
|
|
246
|
-
function
|
|
373
|
+
function vt(t) {
|
|
247
374
|
const e = t.getBoundingClientRect();
|
|
248
375
|
if (!(e.width <= 0 || e.height <= 0))
|
|
249
376
|
return {
|
|
@@ -251,7 +378,7 @@ function lt(t) {
|
|
|
251
378
|
y: e.top + e.height / 2
|
|
252
379
|
};
|
|
253
380
|
}
|
|
254
|
-
function
|
|
381
|
+
function Q(t, e) {
|
|
255
382
|
if (typeof t.elementsFromPoint == "function")
|
|
256
383
|
return t.elementsFromPoint(e.x, e.y);
|
|
257
384
|
if (typeof t.elementFromPoint != "function")
|
|
@@ -259,25 +386,25 @@ function W(t, e) {
|
|
|
259
386
|
const n = t.elementFromPoint(e.x, e.y);
|
|
260
387
|
return n ? [n] : [];
|
|
261
388
|
}
|
|
262
|
-
function
|
|
389
|
+
function xt(t) {
|
|
263
390
|
return typeof t.elementsFromPoint == "function" || typeof t.elementFromPoint == "function";
|
|
264
391
|
}
|
|
265
|
-
function
|
|
392
|
+
function A(t, e) {
|
|
266
393
|
return t === e || t.contains(e);
|
|
267
394
|
}
|
|
268
|
-
function
|
|
395
|
+
function Tt(t) {
|
|
269
396
|
let e = t;
|
|
270
397
|
for (; e; ) {
|
|
271
|
-
if (
|
|
398
|
+
if (mt(e))
|
|
272
399
|
return e;
|
|
273
400
|
e = e.parentElement;
|
|
274
401
|
}
|
|
275
402
|
return t;
|
|
276
403
|
}
|
|
277
|
-
function
|
|
404
|
+
function Y(t) {
|
|
278
405
|
return (t ?? "").replace(/\([^)]*\)/g, "").replace(/\s+/g, "").trim().toLowerCase();
|
|
279
406
|
}
|
|
280
|
-
function
|
|
407
|
+
function V(t) {
|
|
281
408
|
const e = t.getBoundingClientRect();
|
|
282
409
|
if (e.width <= 0 || e.height <= 0)
|
|
283
410
|
return;
|
|
@@ -289,40 +416,47 @@ function Y(t) {
|
|
|
289
416
|
{ x: e.left + e.width / 2, y: e.top + Math.min(8, e.height / 2) },
|
|
290
417
|
{ x: e.left + e.width / 2, y: e.bottom - Math.min(8, e.height / 2) }
|
|
291
418
|
].find(
|
|
292
|
-
(r) =>
|
|
293
|
-
(c) =>
|
|
419
|
+
(r) => Q(n, r).some(
|
|
420
|
+
(c) => A(t, c) || A(c, t)
|
|
294
421
|
)
|
|
295
422
|
);
|
|
296
423
|
}
|
|
297
|
-
function
|
|
424
|
+
function Mt(t, e) {
|
|
425
|
+
const n = t.getBoundingClientRect(), o = k(t);
|
|
426
|
+
return {
|
|
427
|
+
x: e.x + o.x - n.left,
|
|
428
|
+
y: e.y + o.y - n.top
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function _t(t, e) {
|
|
298
432
|
var c;
|
|
299
|
-
const n =
|
|
300
|
-
return o ? ((c =
|
|
301
|
-
const
|
|
302
|
-
return n &&
|
|
303
|
-
}).map((
|
|
304
|
-
candidate:
|
|
305
|
-
point:
|
|
306
|
-
rect: k(
|
|
433
|
+
const n = M(e), o = Y(x(e));
|
|
434
|
+
return o ? ((c = F(t).filter((i) => i !== e).filter((i) => {
|
|
435
|
+
const s = M(i), a = Y(x(i));
|
|
436
|
+
return n && s && n !== s ? !1 : a.includes(o) || o.includes(a);
|
|
437
|
+
}).map((i) => ({
|
|
438
|
+
candidate: i,
|
|
439
|
+
point: V(i),
|
|
440
|
+
rect: k(i)
|
|
307
441
|
})).filter(
|
|
308
|
-
(
|
|
309
|
-
).sort((
|
|
442
|
+
(i) => !!i.point
|
|
443
|
+
).sort((i, s) => s.rect.y - i.rect.y)[0]) == null ? void 0 : c.candidate) ?? null : null;
|
|
310
444
|
}
|
|
311
|
-
function
|
|
312
|
-
const e = t.ownerDocument, n =
|
|
445
|
+
function p(t) {
|
|
446
|
+
const e = t.ownerDocument, n = vt(t), o = T(t) && !!n, r = yt(t), c = n ? Q(e, n) : [], i = c[0], s = !!(i && (A(t, i) || A(i, t)));
|
|
313
447
|
return {
|
|
314
448
|
visible: o,
|
|
315
449
|
enabled: r,
|
|
316
|
-
receivesEvents:
|
|
317
|
-
actionable: o && r &&
|
|
318
|
-
center:
|
|
319
|
-
hitTarget:
|
|
450
|
+
receivesEvents: s,
|
|
451
|
+
actionable: o && r && s,
|
|
452
|
+
center: wt(t),
|
|
453
|
+
hitTarget: i,
|
|
320
454
|
hitStack: c
|
|
321
455
|
};
|
|
322
456
|
}
|
|
323
|
-
function
|
|
324
|
-
var
|
|
325
|
-
const n =
|
|
457
|
+
function St(t, e) {
|
|
458
|
+
var s, a, d;
|
|
459
|
+
const n = v(e.testId);
|
|
326
460
|
if (n) {
|
|
327
461
|
const l = typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(n) : n.replaceAll("\\", "\\\\").replaceAll('"', '\\"'), u = t.querySelector(
|
|
328
462
|
`[data-testid="${l}"],[data-test-id="${l}"],[data-qa="${l}"]`
|
|
@@ -330,52 +464,52 @@ function ht(t, e) {
|
|
|
330
464
|
if (u)
|
|
331
465
|
return u;
|
|
332
466
|
}
|
|
333
|
-
const o = (
|
|
334
|
-
return !o && !r && !c ? null :
|
|
335
|
-
var
|
|
336
|
-
const u = (
|
|
337
|
-
return !(o && u !== o || r && !(f != null && f.includes(r)) || c && !(
|
|
467
|
+
const o = (s = v(e.role)) == null ? void 0 : s.toLowerCase(), r = (a = v(e.name)) == null ? void 0 : a.toLowerCase(), c = (d = v(e.text)) == null ? void 0 : d.toLowerCase();
|
|
468
|
+
return !o && !r && !c ? null : F(t).find((l) => {
|
|
469
|
+
var E, g, w;
|
|
470
|
+
const u = (E = M(l)) == null ? void 0 : E.toLowerCase(), f = (g = x(l)) == null ? void 0 : g.toLowerCase(), h = (w = b(l)) == null ? void 0 : w.toLowerCase();
|
|
471
|
+
return !(o && u !== o || r && !(f != null && f.includes(r)) || c && !(h != null && h.includes(c)));
|
|
338
472
|
}) ?? null;
|
|
339
473
|
}
|
|
340
|
-
function
|
|
341
|
-
const e =
|
|
474
|
+
function F(t) {
|
|
475
|
+
const e = m(t), n = t instanceof Document ? t.body ?? t.documentElement : t;
|
|
342
476
|
if (!n)
|
|
343
477
|
return [];
|
|
344
478
|
const o = [], r = (c) => {
|
|
345
|
-
const
|
|
346
|
-
let
|
|
347
|
-
for (;
|
|
348
|
-
const a =
|
|
349
|
-
|
|
479
|
+
const i = e.createTreeWalker(c, NodeFilter.SHOW_ELEMENT);
|
|
480
|
+
let s = i.nextNode();
|
|
481
|
+
for (; s; ) {
|
|
482
|
+
const a = s;
|
|
483
|
+
J(a) && o.push(a);
|
|
350
484
|
const d = a.shadowRoot;
|
|
351
485
|
if (d && r(d), a instanceof HTMLIFrameElement)
|
|
352
486
|
try {
|
|
353
487
|
a.contentDocument && r(a.contentDocument);
|
|
354
488
|
} catch {
|
|
355
489
|
}
|
|
356
|
-
if (o.length >=
|
|
490
|
+
if (o.length >= $)
|
|
357
491
|
return;
|
|
358
|
-
|
|
492
|
+
s = i.nextNode();
|
|
359
493
|
}
|
|
360
494
|
};
|
|
361
|
-
return r(n), o.slice(0,
|
|
495
|
+
return r(n), o.slice(0, $);
|
|
362
496
|
}
|
|
363
|
-
function
|
|
497
|
+
function Lt(t, e) {
|
|
364
498
|
var r;
|
|
365
499
|
const n = Object.getPrototypeOf(t), o = Object.getOwnPropertyDescriptor(n, "value");
|
|
366
500
|
(r = o == null ? void 0 : o.set) == null || r.call(t, e);
|
|
367
501
|
}
|
|
368
|
-
function
|
|
502
|
+
function I(t) {
|
|
369
503
|
t.dispatchEvent(new Event("input", { bubbles: !0 })), t.dispatchEvent(new Event("change", { bubbles: !0 }));
|
|
370
504
|
}
|
|
371
|
-
function
|
|
505
|
+
function S(t) {
|
|
372
506
|
var e, n;
|
|
373
507
|
(t instanceof HTMLElement || t instanceof SVGElement) && ((e = t.scrollIntoView) == null || e.call(t, { block: "center", inline: "center" })), t instanceof HTMLElement && ((n = t.focus) == null || n.call(t));
|
|
374
508
|
}
|
|
375
|
-
function
|
|
509
|
+
function L(t, e) {
|
|
376
510
|
return typeof PointerEvent == "function" ? new PointerEvent(t, e) : new MouseEvent(t.replace("pointer", "mouse"), e);
|
|
377
511
|
}
|
|
378
|
-
class
|
|
512
|
+
class kt {
|
|
379
513
|
constructor(e = {}) {
|
|
380
514
|
this.options = e, this.refs = /* @__PURE__ */ new Map(), this.nextRef = 1;
|
|
381
515
|
}
|
|
@@ -410,10 +544,10 @@ class pt {
|
|
|
410
544
|
}
|
|
411
545
|
}
|
|
412
546
|
snapshot() {
|
|
413
|
-
var c,
|
|
547
|
+
var c, i;
|
|
414
548
|
this.refs.clear(), this.nextRef = 1;
|
|
415
|
-
const e = this.getRoot(), n =
|
|
416
|
-
(
|
|
549
|
+
const e = this.getRoot(), n = m(e), o = H(e), r = F(e).map(
|
|
550
|
+
(s) => this.snapshotElement(s)
|
|
417
551
|
);
|
|
418
552
|
return {
|
|
419
553
|
url: o.location.href,
|
|
@@ -438,18 +572,18 @@ class pt {
|
|
|
438
572
|
readyState: n.readyState,
|
|
439
573
|
visibilityState: n.visibilityState,
|
|
440
574
|
focusedElement: n.activeElement && n.activeElement !== n.body ? this.snapshotElementWithoutRef(n.activeElement) : void 0,
|
|
441
|
-
selection: ((
|
|
575
|
+
selection: ((i = (c = n.getSelection) == null ? void 0 : c.call(n)) == null ? void 0 : i.toString()) || void 0
|
|
442
576
|
},
|
|
443
577
|
navigation: this.getNavigationState(o),
|
|
444
578
|
frames: this.getFrameState(n),
|
|
445
|
-
accessibility: r.map((
|
|
446
|
-
ref:
|
|
447
|
-
role:
|
|
448
|
-
name:
|
|
449
|
-
value:
|
|
450
|
-
disabled:
|
|
451
|
-
checked:
|
|
452
|
-
focused: n.activeElement === this.refs.get(
|
|
579
|
+
accessibility: r.map((s) => ({
|
|
580
|
+
ref: s.ref,
|
|
581
|
+
role: s.role,
|
|
582
|
+
name: s.name,
|
|
583
|
+
value: s.value,
|
|
584
|
+
disabled: s.disabled,
|
|
585
|
+
checked: s.checked,
|
|
586
|
+
focused: n.activeElement === this.refs.get(s.ref)
|
|
453
587
|
})),
|
|
454
588
|
elements: r
|
|
455
589
|
};
|
|
@@ -496,139 +630,203 @@ class pt {
|
|
|
496
630
|
return this.createElementSnapshot(e, "");
|
|
497
631
|
}
|
|
498
632
|
createElementSnapshot(e, n) {
|
|
499
|
-
const o = (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) && e.placeholder || void 0, r =
|
|
633
|
+
const o = (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) && e.placeholder || void 0, r = p(e);
|
|
500
634
|
return {
|
|
501
635
|
ref: n,
|
|
502
636
|
tag: e.tagName.toLowerCase(),
|
|
503
|
-
role:
|
|
504
|
-
name:
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
637
|
+
role: M(e),
|
|
638
|
+
name: x(e),
|
|
639
|
+
label: z(e),
|
|
640
|
+
groupLabel: ht(e),
|
|
641
|
+
text: b(e),
|
|
642
|
+
nearbyText: N(e),
|
|
643
|
+
testId: Et(e),
|
|
644
|
+
value: at(e),
|
|
645
|
+
selectedLabel: pt(e),
|
|
646
|
+
options: gt(e),
|
|
509
647
|
placeholder: o,
|
|
510
|
-
selector:
|
|
511
|
-
disabled:
|
|
648
|
+
selector: D(e),
|
|
649
|
+
disabled: K(e),
|
|
512
650
|
enabled: r.enabled,
|
|
513
|
-
checked:
|
|
651
|
+
checked: bt(e),
|
|
514
652
|
visible: r.visible,
|
|
515
653
|
actionable: r.actionable,
|
|
516
654
|
rect: k(e),
|
|
517
655
|
center: r.center,
|
|
518
|
-
hitTarget: r.hitTarget ?
|
|
519
|
-
hitStack: r.hitStack.slice(0, 5).map(
|
|
656
|
+
hitTarget: r.hitTarget ? U(r.hitTarget) : void 0,
|
|
657
|
+
hitStack: r.hitStack.slice(0, 5).map(U)
|
|
520
658
|
};
|
|
521
659
|
}
|
|
522
660
|
resolveElement(e) {
|
|
523
|
-
const n =
|
|
661
|
+
const n = v(e.ref) ?? v(e.axRef);
|
|
524
662
|
if (n) {
|
|
525
663
|
const c = this.refs.get(n);
|
|
526
664
|
if (!c)
|
|
527
665
|
throw new Error(`Unknown element ref: ${n}. Take a new snapshot.`);
|
|
528
666
|
return c;
|
|
529
667
|
}
|
|
530
|
-
const o =
|
|
668
|
+
const o = v(e.selector);
|
|
531
669
|
if (o) {
|
|
532
670
|
const c = this.getRoot().querySelector(o);
|
|
533
671
|
if (!c)
|
|
534
672
|
throw new Error(`No element matches selector: ${o}.`);
|
|
535
673
|
return c;
|
|
536
674
|
}
|
|
537
|
-
const r =
|
|
675
|
+
const r = St(this.getRoot(), e);
|
|
538
676
|
if (r)
|
|
539
677
|
return r;
|
|
540
678
|
if (typeof e.x < "u" || typeof e.y < "u") {
|
|
541
679
|
const c = {
|
|
542
|
-
x:
|
|
543
|
-
y:
|
|
544
|
-
},
|
|
680
|
+
x: C(e.x, "x"),
|
|
681
|
+
y: C(e.y, "y")
|
|
682
|
+
}, i = m(this.getRoot()).elementFromPoint(
|
|
545
683
|
c.x,
|
|
546
684
|
c.y
|
|
547
685
|
);
|
|
548
|
-
if (!
|
|
686
|
+
if (!i)
|
|
549
687
|
throw new Error(`No element found at (${c.x}, ${c.y}).`);
|
|
550
|
-
return
|
|
688
|
+
return i;
|
|
551
689
|
}
|
|
552
690
|
throw new Error(
|
|
553
691
|
"Expected one of ref, selector, role/name/text/testId, or x/y."
|
|
554
692
|
);
|
|
555
693
|
}
|
|
556
|
-
click(e) {
|
|
557
|
-
const n =
|
|
558
|
-
if (!i && !r.actionable &&
|
|
694
|
+
async click(e) {
|
|
695
|
+
const n = y(e), o = this.resolveElement(n), r = p(o), i = (r.actionable ? null : _t(this.getRoot(), o)) ?? Tt(o);
|
|
696
|
+
if (!V(i) && !r.actionable && xt(o.ownerDocument))
|
|
559
697
|
throw new Error(
|
|
560
|
-
`Target "${
|
|
698
|
+
`Target "${x(o) ?? o.tagName.toLowerCase()}" is not receiving pointer events. Take a screenshot or use host_page_pointer coordinates.`
|
|
561
699
|
);
|
|
562
|
-
|
|
563
|
-
|
|
700
|
+
S(i);
|
|
701
|
+
const a = V(i), d = p(i), l = p(o), u = a ? Mt(i, a) : d.center ?? r.center;
|
|
702
|
+
return u && await this.showVisualEffect({
|
|
703
|
+
type: "click",
|
|
704
|
+
point: u,
|
|
705
|
+
anchor: "target",
|
|
706
|
+
target: i,
|
|
707
|
+
requested: o
|
|
708
|
+
}), i instanceof HTMLElement ? i.click() : i.dispatchEvent(new MouseEvent("click", { bubbles: !0 })), {
|
|
709
|
+
clicked: this.describeElement(i),
|
|
564
710
|
requested: this.describeElement(o),
|
|
565
|
-
strategy:
|
|
566
|
-
point:
|
|
711
|
+
strategy: i === o ? "dom" : "semantic_visible_fallback",
|
|
712
|
+
point: u,
|
|
567
713
|
actionability: {
|
|
568
|
-
visible:
|
|
569
|
-
enabled:
|
|
570
|
-
receivesEvents:
|
|
714
|
+
visible: l.visible,
|
|
715
|
+
enabled: l.enabled,
|
|
716
|
+
receivesEvents: l.receivesEvents
|
|
571
717
|
}
|
|
572
718
|
};
|
|
573
719
|
}
|
|
574
|
-
fill(e) {
|
|
575
|
-
const n =
|
|
576
|
-
if (
|
|
577
|
-
return
|
|
720
|
+
async fill(e) {
|
|
721
|
+
const n = y(e), o = O(n.value, "value"), r = this.resolveElement(n);
|
|
722
|
+
if (S(r), r instanceof HTMLInputElement || r instanceof HTMLTextAreaElement)
|
|
723
|
+
return await this.showVisualEffect({
|
|
724
|
+
type: "fill",
|
|
725
|
+
target: r,
|
|
726
|
+
requested: r,
|
|
727
|
+
value: o,
|
|
728
|
+
anchor: "target",
|
|
729
|
+
point: p(r).center
|
|
730
|
+
}), Lt(r, o), I(r), { filled: this.describeElement(r), value: o };
|
|
578
731
|
if (r instanceof HTMLElement && r.isContentEditable)
|
|
579
|
-
return
|
|
732
|
+
return await this.showVisualEffect({
|
|
733
|
+
type: "fill",
|
|
734
|
+
target: r,
|
|
735
|
+
requested: r,
|
|
736
|
+
value: o,
|
|
737
|
+
anchor: "target",
|
|
738
|
+
point: p(r).center
|
|
739
|
+
}), r.textContent = o, I(r), { filled: this.describeElement(r), value: o };
|
|
580
740
|
throw new Error("Target element cannot be filled.");
|
|
581
741
|
}
|
|
582
|
-
press(e) {
|
|
583
|
-
const n =
|
|
742
|
+
async press(e) {
|
|
743
|
+
const n = y(e), o = O(n.key, "key"), r = n.ref || n.selector || n.x !== void 0 && n.y !== void 0 ? this.resolveElement(n) : m(this.getRoot()).activeElement ?? m(this.getRoot()).body;
|
|
584
744
|
if (!r)
|
|
585
745
|
throw new Error("No target element is available for key press.");
|
|
586
|
-
|
|
746
|
+
S(r), await this.showVisualEffect({
|
|
747
|
+
type: "press",
|
|
748
|
+
target: r,
|
|
749
|
+
requested: r,
|
|
750
|
+
key: o,
|
|
751
|
+
anchor: "target",
|
|
752
|
+
point: p(r).center
|
|
753
|
+
});
|
|
587
754
|
const c = { key: o, bubbles: !0, cancelable: !0 };
|
|
588
755
|
return r.dispatchEvent(new KeyboardEvent("keydown", c)), o.length === 1 && r.dispatchEvent(new KeyboardEvent("keypress", c)), r.dispatchEvent(new KeyboardEvent("keyup", c)), { pressed: o, target: this.describeElement(r) };
|
|
589
756
|
}
|
|
590
|
-
select(e) {
|
|
591
|
-
const n =
|
|
757
|
+
async select(e) {
|
|
758
|
+
const n = y(e), o = ct(n.values ?? n.value), r = this.resolveElement(n);
|
|
592
759
|
if (!(r instanceof HTMLSelectElement))
|
|
593
760
|
throw new Error("Target element is not a select.");
|
|
761
|
+
S(r);
|
|
594
762
|
const c = new Set(o);
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
763
|
+
await this.showVisualEffect({
|
|
764
|
+
type: "select",
|
|
765
|
+
target: r,
|
|
766
|
+
requested: r,
|
|
767
|
+
values: o,
|
|
768
|
+
anchor: "target",
|
|
769
|
+
point: p(r).center
|
|
770
|
+
});
|
|
771
|
+
for (const i of Array.from(r.options))
|
|
772
|
+
i.selected = c.has(i.value);
|
|
773
|
+
return I(r), {
|
|
598
774
|
selected: Array.from(r.selectedOptions).map(
|
|
599
|
-
(
|
|
775
|
+
(i) => i.value
|
|
600
776
|
),
|
|
601
777
|
target: this.describeElement(r)
|
|
602
778
|
};
|
|
603
779
|
}
|
|
604
|
-
scroll(e) {
|
|
780
|
+
async scroll(e) {
|
|
605
781
|
var a, d, l, u;
|
|
606
|
-
const n =
|
|
607
|
-
x:
|
|
608
|
-
y:
|
|
609
|
-
} : null, r =
|
|
782
|
+
const n = y(e), o = n.x !== void 0 || n.y !== void 0 ? {
|
|
783
|
+
x: _(n.x) ?? 0,
|
|
784
|
+
y: _(n.y) ?? 0
|
|
785
|
+
} : null, r = _(n.deltaX) ?? 0, c = _(n.deltaY) ?? 0, i = this.getRoot(), s = H(i);
|
|
610
786
|
if (n.ref || n.selector || n.role || n.name || n.text || n.testId) {
|
|
611
787
|
const f = this.resolveElement(n);
|
|
612
788
|
if (!(f instanceof HTMLElement))
|
|
613
789
|
throw new Error("Target element cannot be scrolled.");
|
|
614
|
-
return
|
|
790
|
+
return await this.showVisualEffect({
|
|
791
|
+
type: "scroll",
|
|
792
|
+
target: f,
|
|
793
|
+
requested: f,
|
|
794
|
+
deltaX: r,
|
|
795
|
+
deltaY: c,
|
|
796
|
+
anchor: "target",
|
|
797
|
+
point: p(f).center
|
|
798
|
+
}), o ? (a = f.scrollTo) == null || a.call(f, o.x, o.y) : (d = f.scrollBy) == null || d.call(f, r, c), {
|
|
615
799
|
scrolled: this.describeElement(f),
|
|
616
800
|
scroll: { x: f.scrollLeft, y: f.scrollTop }
|
|
617
801
|
};
|
|
618
802
|
}
|
|
619
|
-
return
|
|
803
|
+
return await this.showVisualEffect({
|
|
804
|
+
type: "scroll",
|
|
805
|
+
deltaX: r,
|
|
806
|
+
deltaY: c,
|
|
807
|
+
point: {
|
|
808
|
+
x: s.innerWidth / 2,
|
|
809
|
+
y: s.innerHeight / 2
|
|
810
|
+
}
|
|
811
|
+
}), o ? (l = s.scrollTo) == null || l.call(s, o.x, o.y) : (u = s.scrollBy) == null || u.call(s, r, c), { scroll: { x: s.scrollX, y: s.scrollY } };
|
|
620
812
|
}
|
|
621
813
|
navigate(e) {
|
|
622
814
|
if (this.options.allowNavigation === !1)
|
|
623
815
|
throw new Error("Navigation is disabled for host page automation.");
|
|
624
|
-
const n =
|
|
625
|
-
if (
|
|
816
|
+
const n = y(e), o = this.getRoot(), r = H(o), c = O(n.url, "url"), i = new URL(c, r.location.href);
|
|
817
|
+
if (i.protocol !== "http:" && i.protocol !== "https:")
|
|
626
818
|
throw new Error("Navigation only supports HTTP(S) URLs.");
|
|
627
|
-
return this.refs.clear(), r.location.assign(
|
|
819
|
+
return this.refs.clear(), r.location.assign(i.toString()), { navigated: i.toString() };
|
|
628
820
|
}
|
|
629
|
-
hover(e) {
|
|
630
|
-
const n =
|
|
631
|
-
return
|
|
821
|
+
async hover(e) {
|
|
822
|
+
const n = y(e), o = this.resolveElement(n), r = p(o).center;
|
|
823
|
+
return await this.showVisualEffect({
|
|
824
|
+
type: "hover",
|
|
825
|
+
target: o,
|
|
826
|
+
requested: o,
|
|
827
|
+
anchor: "target",
|
|
828
|
+
point: r
|
|
829
|
+
}), o.dispatchEvent(
|
|
632
830
|
new MouseEvent("mouseover", {
|
|
633
831
|
bubbles: !0,
|
|
634
832
|
cancelable: !0,
|
|
@@ -644,31 +842,60 @@ class pt {
|
|
|
644
842
|
})
|
|
645
843
|
), { hovered: this.describeElement(o), point: r };
|
|
646
844
|
}
|
|
647
|
-
focus(e) {
|
|
648
|
-
const n =
|
|
649
|
-
return
|
|
845
|
+
async focus(e) {
|
|
846
|
+
const n = y(e), o = this.resolveElement(n);
|
|
847
|
+
return S(o), await this.showVisualEffect({
|
|
848
|
+
type: "focus",
|
|
849
|
+
target: o,
|
|
850
|
+
requested: o,
|
|
851
|
+
anchor: "target",
|
|
852
|
+
point: p(o).center
|
|
853
|
+
}), { focused: this.describeElement(o) };
|
|
650
854
|
}
|
|
651
|
-
pointer(e) {
|
|
652
|
-
const n =
|
|
653
|
-
x:
|
|
654
|
-
y:
|
|
855
|
+
async pointer(e) {
|
|
856
|
+
const n = y(e), o = W(n.action, ["move", "down", "up", "click"]) ?? "click", r = st(n.button) ?? 0, c = n.ref || n.selector || n.role || n.name || n.text || n.testId ? this.resolveElement(n) : null, i = c ? p(c).center : {
|
|
857
|
+
x: C(n.x, "x"),
|
|
858
|
+
y: C(n.y, "y")
|
|
655
859
|
};
|
|
656
|
-
if (!s)
|
|
657
|
-
throw new Error("Target element has no clickable point.");
|
|
658
|
-
const i = c ?? g(this.getRoot()).elementFromPoint(s.x, s.y);
|
|
659
860
|
if (!i)
|
|
660
|
-
throw new Error(
|
|
861
|
+
throw new Error("Target element has no clickable point.");
|
|
862
|
+
const s = c ?? m(this.getRoot()).elementFromPoint(i.x, i.y);
|
|
863
|
+
if (!s)
|
|
864
|
+
throw new Error(`No element found at (${i.x}, ${i.y}).`);
|
|
661
865
|
const a = {
|
|
662
866
|
bubbles: !0,
|
|
663
867
|
cancelable: !0,
|
|
664
|
-
clientX:
|
|
665
|
-
clientY:
|
|
868
|
+
clientX: i.x,
|
|
869
|
+
clientY: i.y,
|
|
666
870
|
button: r
|
|
667
871
|
};
|
|
668
|
-
return o === "move" ? (
|
|
872
|
+
return o === "move" ? (await this.showVisualEffect({
|
|
873
|
+
type: "pointer",
|
|
874
|
+
action: o,
|
|
875
|
+
anchor: "point",
|
|
876
|
+
point: i,
|
|
877
|
+
target: s
|
|
878
|
+
}), s.dispatchEvent(L("pointermove", a)), s.dispatchEvent(new MouseEvent("mousemove", a))) : o === "down" ? (await this.showVisualEffect({
|
|
879
|
+
type: "pointer",
|
|
880
|
+
action: o,
|
|
881
|
+
anchor: "point",
|
|
882
|
+
point: i,
|
|
883
|
+
target: s
|
|
884
|
+
}), s.dispatchEvent(L("pointerdown", a)), s.dispatchEvent(new MouseEvent("mousedown", a))) : o === "up" ? (await this.showVisualEffect({
|
|
885
|
+
type: "pointer",
|
|
886
|
+
action: o,
|
|
887
|
+
anchor: "point",
|
|
888
|
+
point: i,
|
|
889
|
+
target: s
|
|
890
|
+
}), s.dispatchEvent(L("pointerup", a)), s.dispatchEvent(new MouseEvent("mouseup", a))) : (await this.showVisualEffect({
|
|
891
|
+
type: "click",
|
|
892
|
+
anchor: "point",
|
|
893
|
+
point: i,
|
|
894
|
+
target: s
|
|
895
|
+
}), s.dispatchEvent(L("pointerdown", a)), s.dispatchEvent(new MouseEvent("mousedown", a)), s.dispatchEvent(L("pointerup", a)), s.dispatchEvent(new MouseEvent("mouseup", a)), s instanceof HTMLElement ? s.click() : s.dispatchEvent(new MouseEvent("click", a))), {
|
|
669
896
|
pointer: o,
|
|
670
|
-
point:
|
|
671
|
-
target: this.describeElement(
|
|
897
|
+
point: i,
|
|
898
|
+
target: this.describeElement(s)
|
|
672
899
|
};
|
|
673
900
|
}
|
|
674
901
|
screenshot() {
|
|
@@ -676,25 +903,48 @@ class pt {
|
|
|
676
903
|
"host_page_screenshot requires the browser extension CDP adapter."
|
|
677
904
|
);
|
|
678
905
|
}
|
|
906
|
+
async showVisualEffect(e) {
|
|
907
|
+
var n, o, r, c;
|
|
908
|
+
try {
|
|
909
|
+
await ((o = (n = this.options).showVisualEffect) == null ? void 0 : o.call(n, e));
|
|
910
|
+
} catch {
|
|
911
|
+
}
|
|
912
|
+
if (!(e.type !== "click" || !e.point || !e.target || this.options.showVisualEffect))
|
|
913
|
+
try {
|
|
914
|
+
await ((c = (r = this.options).showClickEffect) == null ? void 0 : c.call(r, {
|
|
915
|
+
point: e.point,
|
|
916
|
+
target: e.target,
|
|
917
|
+
requested: e.requested
|
|
918
|
+
}));
|
|
919
|
+
} catch {
|
|
920
|
+
}
|
|
921
|
+
}
|
|
679
922
|
async waitFor(e) {
|
|
680
|
-
const n =
|
|
923
|
+
const n = y(e), o = W(n.state, [
|
|
681
924
|
"attached",
|
|
682
925
|
"visible",
|
|
683
926
|
"hidden",
|
|
684
927
|
"detached"
|
|
685
|
-
]) ?? "visible", r =
|
|
686
|
-
|
|
687
|
-
Math.max(0, (r ??
|
|
688
|
-
),
|
|
689
|
-
for (
|
|
690
|
-
|
|
691
|
-
|
|
928
|
+
]) ?? "visible", r = _(n.timeoutSeconds), c = Math.min(
|
|
929
|
+
rt,
|
|
930
|
+
Math.max(0, (r ?? ot / 1e3) * 1e3)
|
|
931
|
+
), i = Date.now(), s = this.tryResolveElement(n);
|
|
932
|
+
for (await this.showVisualEffect({
|
|
933
|
+
type: "wait_for",
|
|
934
|
+
state: o,
|
|
935
|
+
target: s ?? void 0,
|
|
936
|
+
requested: s ?? void 0,
|
|
937
|
+
...s ? { anchor: "target" } : {},
|
|
938
|
+
point: s ? p(s).center : void 0
|
|
939
|
+
}); Date.now() - i <= c; ) {
|
|
940
|
+
const a = this.tryResolveElement(n);
|
|
941
|
+
if (o === "attached" ? !!a : o === "detached" ? !a : o === "hidden" ? !a || !T(a) : !!(a && T(a)))
|
|
692
942
|
return {
|
|
693
943
|
waitedFor: o,
|
|
694
|
-
elapsedMs: Date.now() -
|
|
695
|
-
target:
|
|
944
|
+
elapsedMs: Date.now() - i,
|
|
945
|
+
target: a ? this.describeElement(a) : void 0
|
|
696
946
|
};
|
|
697
|
-
await new Promise((
|
|
947
|
+
await new Promise((l) => setTimeout(l, 100));
|
|
698
948
|
}
|
|
699
949
|
throw new Error(`Timed out waiting for target to become ${o}.`);
|
|
700
950
|
}
|
|
@@ -708,54 +958,54 @@ class pt {
|
|
|
708
958
|
describeElement(e) {
|
|
709
959
|
return {
|
|
710
960
|
tag: e.tagName.toLowerCase(),
|
|
711
|
-
role:
|
|
712
|
-
name:
|
|
713
|
-
selector:
|
|
961
|
+
role: M(e),
|
|
962
|
+
name: x(e),
|
|
963
|
+
selector: D(e)
|
|
714
964
|
};
|
|
715
965
|
}
|
|
716
966
|
}
|
|
717
|
-
function
|
|
967
|
+
function Ct(t) {
|
|
718
968
|
return typeof t == "object" && t !== null && !Array.isArray(t) ? t : {};
|
|
719
969
|
}
|
|
720
|
-
function
|
|
970
|
+
function Nt(t) {
|
|
721
971
|
return JSON.stringify(t);
|
|
722
972
|
}
|
|
723
|
-
function
|
|
973
|
+
function P(t, e, n) {
|
|
724
974
|
return {
|
|
725
975
|
tool_call_id: t.tool_call_id ?? t.id,
|
|
726
976
|
name: t.name,
|
|
727
977
|
status: e,
|
|
728
|
-
content:
|
|
978
|
+
content: Nt(n)
|
|
729
979
|
};
|
|
730
980
|
}
|
|
731
|
-
function
|
|
981
|
+
function At(t) {
|
|
732
982
|
return t instanceof Error ? t.message : String(t);
|
|
733
983
|
}
|
|
734
|
-
function
|
|
735
|
-
const e = new
|
|
984
|
+
function Rt(t = {}) {
|
|
985
|
+
const e = new kt(t);
|
|
736
986
|
return async (n) => {
|
|
737
|
-
if (!
|
|
738
|
-
return
|
|
987
|
+
if (!it(n.name))
|
|
988
|
+
return P(n, "error", {
|
|
739
989
|
ok: !1,
|
|
740
990
|
error: `Unknown host page automation tool: ${n.name}`
|
|
741
991
|
});
|
|
742
992
|
try {
|
|
743
993
|
const o = await e.execute(
|
|
744
994
|
n.name,
|
|
745
|
-
|
|
995
|
+
Ct(n.params)
|
|
746
996
|
);
|
|
747
|
-
return
|
|
997
|
+
return P(n, "success", { ok: !0, result: o });
|
|
748
998
|
} catch (o) {
|
|
749
|
-
return
|
|
999
|
+
return P(n, "error", {
|
|
750
1000
|
ok: !1,
|
|
751
|
-
error:
|
|
1001
|
+
error: At(o)
|
|
752
1002
|
});
|
|
753
1003
|
}
|
|
754
1004
|
};
|
|
755
1005
|
}
|
|
756
1006
|
export {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
1007
|
+
tt as HOST_PAGE_AUTOMATION_TOOL_NAMES,
|
|
1008
|
+
kt as HostPageAutomationExecutor,
|
|
1009
|
+
Rt as createHostPageAutomationClientToolHandler,
|
|
1010
|
+
it as isHostPageAutomationToolName
|
|
761
1011
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xpert-ai/chatkit-host-automation",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Host page automation tools for Xpert ChatKit client tools",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"!**/*.tsbuildinfo"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@xpert-ai/chatkit-types": "~0.3.
|
|
24
|
+
"@xpert-ai/chatkit-types": "~0.3.5"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"rimraf": "^6.0.0",
|