@xpert-ai/chatkit-host-automation 0.3.2 → 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 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 z = [
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
- ], G = new Set(
15
- z
16
- ), K = [
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(","), D = 100, J = 1e4, Q = 6e4;
32
- function Z(t) {
33
- return G.has(t);
31
+ ].join(","), $ = 100, ot = 1e4, rt = 6e4;
32
+ function it(t) {
33
+ return et.has(t);
34
34
  }
35
- function g(t) {
35
+ function m(t) {
36
36
  return t instanceof Document ? t : t.ownerDocument;
37
37
  }
38
- function N(t) {
39
- return g(t).defaultView ?? window;
38
+ function H(t) {
39
+ return m(t).defaultView ?? window;
40
40
  }
41
- function h(t) {
41
+ function y(t) {
42
42
  return typeof t == "object" && t !== null && !Array.isArray(t) ? t : {};
43
43
  }
44
- function R(t, e) {
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 p(t) {
49
+ function v(t) {
50
50
  return typeof t == "string" && t.trim() ? t : void 0;
51
51
  }
52
- function tt(t) {
52
+ function st(t) {
53
53
  return typeof t == "number" && Number.isInteger(t) ? t : void 0;
54
54
  }
55
- function M(t, e) {
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 T(t) {
60
+ function _(t) {
61
61
  return typeof t == "number" && Number.isFinite(t) ? t : void 0;
62
62
  }
63
- function F(t, e) {
63
+ function W(t, e) {
64
64
  return typeof t == "string" && e.includes(t) ? t : void 0;
65
65
  }
66
- function et(t) {
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 v(t) {
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 V(t) {
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 nt(t) {
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 E(t) {
86
- const e = t.getAttribute("aria-label");
87
- if (e != null && e.trim())
88
- return e.trim();
89
- const n = t.getAttribute("title");
90
- if (n != null && n.trim())
91
- return n.trim();
92
- if (t instanceof HTMLInputElement) {
93
- const r = Array.from(t.labels ?? []).map((c) => v(c)).filter(Boolean);
94
- if (r.length > 0)
95
- return r.join(" ").slice(0, 160);
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 = X(t)[0];
98
- return o || v(t);
128
+ const o = e.join(" ").replace(/\s+/g, " ").trim();
129
+ return o ? o.slice(0, 160) : void 0;
99
130
  }
100
- function ot(t) {
101
- if (!(t instanceof HTMLElement || t instanceof SVGElement) || !m(t) || t.matches(
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 = V(t) ?? v(t);
184
+ const e = R(t) ?? b(t);
106
185
  return !!(e && e.length <= 120);
107
186
  }
108
- function X(t) {
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, s = [], i = e.createTreeWalker(n, NodeFilter.SHOW_ELEMENT);
116
- let a = i.nextNode();
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 && ot(l)) {
120
- const u = l.getBoundingClientRect(), f = V(l) ?? v(l);
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 b = u.top + u.height / 2, w = u.left + u.width / 2, y = u.right <= o.left + 12 && Math.abs(b - r) <= Math.max(28, o.height * 1.25), S = u.bottom <= o.top + 8 && o.top - u.bottom <= 80 && w >= o.left - 80 && w <= o.right + 80;
123
- if (y || S) {
124
- const j = y ? o.left - u.right + Math.abs(b - r) : o.top - u.bottom + Math.abs(w - c);
125
- s.push({
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: j + (y ? 0 : 100)
254
+ score: Z + (g ? 0 : w ? 5 : 100)
128
255
  });
129
256
  }
130
257
  }
131
258
  }
132
- a = i.nextNode();
259
+ a = s.nextNode();
133
260
  }
134
261
  const d = /* @__PURE__ */ new Set();
135
- return s.sort((l, u) => l.score - u.score).map((l) => l.text).filter((l) => d.has(l) ? !1 : (d.add(l), !0)).slice(0, 4);
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 rt(t) {
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 x(t) {
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 q(t) {
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 it(t) {
294
+ function bt(t) {
168
295
  return t instanceof HTMLInputElement && (t.type === "checkbox" || t.type === "radio") ? t.checked : void 0;
169
296
  }
170
- function st(t) {
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 $(t) {
305
+ function U(t) {
179
306
  return {
180
307
  tag: t.tagName.toLowerCase(),
181
- role: x(t),
182
- name: E(t),
183
- selector: P(t)
308
+ role: M(t),
309
+ name: x(t),
310
+ selector: D(t)
184
311
  };
185
312
  }
186
- function m(t) {
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 U(t) {
193
- return t.matches(K) && m(t);
319
+ function J(t) {
320
+ return t.matches(nt) && T(t);
194
321
  }
195
- function ct(t) {
196
- return q(t) !== !0;
322
+ function yt(t) {
323
+ return K(t) !== !0;
197
324
  }
198
- function at(t) {
325
+ function mt(t) {
199
326
  var n;
200
- if (U(t))
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) && m(t);
332
+ return ((e == null ? void 0 : e.cursor) === "pointer" || !!t.onclick) && T(t);
206
333
  }
207
334
  function k(t) {
208
- var c, s;
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 i = r.getBoundingClientRect();
218
- n += i.left, o += i.top;
344
+ const s = r.getBoundingClientRect();
345
+ n += s.left, o += s.top;
219
346
  try {
220
- r = ((s = r.ownerDocument.defaultView) == null ? void 0 : s.frameElement) ?? null;
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 P(t) {
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 lt(t) {
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 W(t, e) {
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 ut(t) {
389
+ function xt(t) {
263
390
  return typeof t.elementsFromPoint == "function" || typeof t.elementFromPoint == "function";
264
391
  }
265
- function C(t, e) {
392
+ function A(t, e) {
266
393
  return t === e || t.contains(e);
267
394
  }
268
- function ft(t) {
395
+ function Tt(t) {
269
396
  let e = t;
270
397
  for (; e; ) {
271
- if (at(e))
398
+ if (mt(e))
272
399
  return e;
273
400
  e = e.parentElement;
274
401
  }
275
402
  return t;
276
403
  }
277
- function B(t) {
404
+ function Y(t) {
278
405
  return (t ?? "").replace(/\([^)]*\)/g, "").replace(/\s+/g, "").trim().toLowerCase();
279
406
  }
280
- function Y(t) {
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) => W(n, r).some(
293
- (c) => C(t, c) || C(c, t)
419
+ (r) => Q(n, r).some(
420
+ (c) => A(t, c) || A(c, t)
294
421
  )
295
422
  );
296
423
  }
297
- function dt(t, e) {
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 = x(e), o = B(E(e));
300
- return o ? ((c = I(t).filter((s) => s !== e).filter((s) => {
301
- const i = x(s), a = B(E(s));
302
- return n && i && n !== i ? !1 : a.includes(o) || o.includes(a);
303
- }).map((s) => ({
304
- candidate: s,
305
- point: Y(s),
306
- rect: k(s)
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
- (s) => !!s.point
309
- ).sort((s, i) => i.rect.y - s.rect.y)[0]) == null ? void 0 : c.candidate) ?? null : null;
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 L(t) {
312
- const e = t.ownerDocument, n = lt(t), o = m(t) && !!n, r = ct(t), c = n ? W(e, n) : [], s = c[0], i = !!(s && (C(t, s) || C(s, t)));
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: i,
317
- actionable: o && r && i,
318
- center: st(t),
319
- hitTarget: s,
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 ht(t, e) {
324
- var i, a, d;
325
- const n = p(e.testId);
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 = (i = p(e.role)) == null ? void 0 : i.toLowerCase(), r = (a = p(e.name)) == null ? void 0 : a.toLowerCase(), c = (d = p(e.text)) == null ? void 0 : d.toLowerCase();
334
- return !o && !r && !c ? null : I(t).find((l) => {
335
- var w, y, S;
336
- const u = (w = x(l)) == null ? void 0 : w.toLowerCase(), f = (y = E(l)) == null ? void 0 : y.toLowerCase(), b = (S = v(l)) == null ? void 0 : S.toLowerCase();
337
- return !(o && u !== o || r && !(f != null && f.includes(r)) || c && !(b != null && b.includes(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 I(t) {
341
- const e = g(t), n = t instanceof Document ? t.body ?? t.documentElement : t;
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 s = e.createTreeWalker(c, NodeFilter.SHOW_ELEMENT);
346
- let i = s.nextNode();
347
- for (; i; ) {
348
- const a = i;
349
- U(a) && o.push(a);
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 >= D)
490
+ if (o.length >= $)
357
491
  return;
358
- i = s.nextNode();
492
+ s = i.nextNode();
359
493
  }
360
494
  };
361
- return r(n), o.slice(0, D);
495
+ return r(n), o.slice(0, $);
362
496
  }
363
- function gt(t, e) {
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 H(t) {
502
+ function I(t) {
369
503
  t.dispatchEvent(new Event("input", { bubbles: !0 })), t.dispatchEvent(new Event("change", { bubbles: !0 }));
370
504
  }
371
- function A(t) {
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 _(t, e) {
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 pt {
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, s;
547
+ var c, i;
414
548
  this.refs.clear(), this.nextRef = 1;
415
- const e = this.getRoot(), n = g(e), o = N(e), r = I(e).map(
416
- (i) => this.snapshotElement(i)
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: ((s = (c = n.getSelection) == null ? void 0 : c.call(n)) == null ? void 0 : s.toString()) || void 0
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((i) => ({
446
- ref: i.ref,
447
- role: i.role,
448
- name: i.name,
449
- value: i.value,
450
- disabled: i.disabled,
451
- checked: i.checked,
452
- focused: n.activeElement === this.refs.get(i.ref)
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 = L(e);
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: x(e),
504
- name: E(e),
505
- text: v(e),
506
- nearbyText: X(e),
507
- testId: rt(e),
508
- value: nt(e),
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: P(e),
511
- disabled: q(e),
648
+ selector: D(e),
649
+ disabled: K(e),
512
650
  enabled: r.enabled,
513
- checked: it(e),
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 ? $(r.hitTarget) : void 0,
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 = p(e.ref) ?? p(e.axRef);
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 = p(e.selector);
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 = ht(this.getRoot(), e);
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: M(e.x, "x"),
543
- y: M(e.y, "y")
544
- }, s = g(this.getRoot()).elementFromPoint(
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 (!s)
686
+ if (!i)
549
687
  throw new Error(`No element found at (${c.x}, ${c.y}).`);
550
- return s;
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 = h(e), o = this.resolveElement(n), r = L(o), s = (r.actionable ? null : dt(this.getRoot(), o)) ?? ft(o), i = Y(s);
558
- if (!i && !r.actionable && ut(o.ownerDocument))
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 "${E(o) ?? o.tagName.toLowerCase()}" is not receiving pointer events. Take a screenshot or use host_page_pointer coordinates.`
698
+ `Target "${x(o) ?? o.tagName.toLowerCase()}" is not receiving pointer events. Take a screenshot or use host_page_pointer coordinates.`
561
699
  );
562
- return A(s), s instanceof HTMLElement ? s.click() : s.dispatchEvent(new MouseEvent("click", { bubbles: !0 })), {
563
- clicked: this.describeElement(s),
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: s === o ? "dom" : "semantic_visible_fallback",
566
- point: i ?? r.center,
711
+ strategy: i === o ? "dom" : "semantic_visible_fallback",
712
+ point: u,
567
713
  actionability: {
568
- visible: r.visible,
569
- enabled: r.enabled,
570
- receivesEvents: r.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 = h(e), o = R(n.value, "value"), r = this.resolveElement(n);
576
- if (A(r), r instanceof HTMLInputElement || r instanceof HTMLTextAreaElement)
577
- return gt(r, o), H(r), { filled: this.describeElement(r), value: o };
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 r.textContent = o, H(r), { filled: this.describeElement(r), value: o };
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 = h(e), o = R(n.key, "key"), r = n.ref || n.selector || n.x !== void 0 && n.y !== void 0 ? this.resolveElement(n) : g(this.getRoot()).activeElement ?? g(this.getRoot()).body;
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
- A(r);
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 = h(e), o = et(n.values ?? n.value), r = this.resolveElement(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
- for (const s of Array.from(r.options))
596
- s.selected = c.has(s.value);
597
- return H(r), {
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
- (s) => s.value
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 = h(e), o = n.x !== void 0 || n.y !== void 0 ? {
607
- x: T(n.x) ?? 0,
608
- y: T(n.y) ?? 0
609
- } : null, r = T(n.deltaX) ?? 0, c = T(n.deltaY) ?? 0, s = this.getRoot(), i = N(s);
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 o ? (a = f.scrollTo) == null || a.call(f, o.x, o.y) : (d = f.scrollBy) == null || d.call(f, r, c), {
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 o ? (l = i.scrollTo) == null || l.call(i, o.x, o.y) : (u = i.scrollBy) == null || u.call(i, r, c), { scroll: { x: i.scrollX, y: i.scrollY } };
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 = h(e), o = this.getRoot(), r = N(o), c = R(n.url, "url"), s = new URL(c, r.location.href);
625
- if (s.protocol !== "http:" && s.protocol !== "https:")
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(s.toString()), { navigated: s.toString() };
819
+ return this.refs.clear(), r.location.assign(i.toString()), { navigated: i.toString() };
628
820
  }
629
- hover(e) {
630
- const n = h(e), o = this.resolveElement(n), r = L(o).center;
631
- return o.dispatchEvent(
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 = h(e), o = this.resolveElement(n);
649
- return A(o), { focused: this.describeElement(o) };
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 = h(e), o = F(n.action, ["move", "down", "up", "click"]) ?? "click", r = tt(n.button) ?? 0, c = n.ref || n.selector || n.role || n.name || n.text || n.testId ? this.resolveElement(n) : null, s = c ? L(c).center : {
653
- x: M(n.x, "x"),
654
- y: M(n.y, "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(`No element found at (${s.x}, ${s.y}).`);
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: s.x,
665
- clientY: s.y,
868
+ clientX: i.x,
869
+ clientY: i.y,
666
870
  button: r
667
871
  };
668
- return o === "move" ? (i.dispatchEvent(_("pointermove", a)), i.dispatchEvent(new MouseEvent("mousemove", a))) : o === "down" ? (i.dispatchEvent(_("pointerdown", a)), i.dispatchEvent(new MouseEvent("mousedown", a))) : o === "up" ? (i.dispatchEvent(_("pointerup", a)), i.dispatchEvent(new MouseEvent("mouseup", a))) : (i.dispatchEvent(_("pointerdown", a)), i.dispatchEvent(new MouseEvent("mousedown", a)), i.dispatchEvent(_("pointerup", a)), i.dispatchEvent(new MouseEvent("mouseup", a)), i instanceof HTMLElement ? i.click() : i.dispatchEvent(new MouseEvent("click", a))), {
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: s,
671
- target: this.describeElement(i)
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 = h(e), o = F(n.state, [
923
+ const n = y(e), o = W(n.state, [
681
924
  "attached",
682
925
  "visible",
683
926
  "hidden",
684
927
  "detached"
685
- ]) ?? "visible", r = T(n.timeoutSeconds), c = Math.min(
686
- Q,
687
- Math.max(0, (r ?? J / 1e3) * 1e3)
688
- ), s = Date.now();
689
- for (; Date.now() - s <= c; ) {
690
- const i = this.tryResolveElement(n);
691
- if (o === "attached" ? !!i : o === "detached" ? !i : o === "hidden" ? !i || !m(i) : !!(i && m(i)))
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() - s,
695
- target: i ? this.describeElement(i) : void 0
944
+ elapsedMs: Date.now() - i,
945
+ target: a ? this.describeElement(a) : void 0
696
946
  };
697
- await new Promise((d) => setTimeout(d, 100));
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: x(e),
712
- name: E(e),
713
- selector: P(e)
961
+ role: M(e),
962
+ name: x(e),
963
+ selector: D(e)
714
964
  };
715
965
  }
716
966
  }
717
- function Et(t) {
967
+ function Ct(t) {
718
968
  return typeof t == "object" && t !== null && !Array.isArray(t) ? t : {};
719
969
  }
720
- function mt(t) {
970
+ function Nt(t) {
721
971
  return JSON.stringify(t);
722
972
  }
723
- function O(t, e, n) {
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: mt(n)
978
+ content: Nt(n)
729
979
  };
730
980
  }
731
- function bt(t) {
981
+ function At(t) {
732
982
  return t instanceof Error ? t.message : String(t);
733
983
  }
734
- function wt(t = {}) {
735
- const e = new pt(t);
984
+ function Rt(t = {}) {
985
+ const e = new kt(t);
736
986
  return async (n) => {
737
- if (!Z(n.name))
738
- return O(n, "error", {
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
- Et(n.params)
995
+ Ct(n.params)
746
996
  );
747
- return O(n, "success", { ok: !0, result: o });
997
+ return P(n, "success", { ok: !0, result: o });
748
998
  } catch (o) {
749
- return O(n, "error", {
999
+ return P(n, "error", {
750
1000
  ok: !1,
751
- error: bt(o)
1001
+ error: At(o)
752
1002
  });
753
1003
  }
754
1004
  };
755
1005
  }
756
1006
  export {
757
- z as HOST_PAGE_AUTOMATION_TOOL_NAMES,
758
- pt as HostPageAutomationExecutor,
759
- wt as createHostPageAutomationClientToolHandler,
760
- Z as isHostPageAutomationToolName
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.2",
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.3"
24
+ "@xpert-ai/chatkit-types": "~0.3.5"
25
25
  },
26
26
  "devDependencies": {
27
27
  "rimraf": "^6.0.0",