@midscene/web 0.7.2 → 0.7.3-beta-20241104100519.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1428 +1,1660 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __defProps = Object.defineProperties;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
- var __getProtoOf = Object.getPrototypeOf;
9
- var __hasOwnProp = Object.prototype.hasOwnProperty;
10
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
- var __spreadValues = (a, b) => {
13
- for (var prop in b || (b = {}))
14
- if (__hasOwnProp.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- if (__getOwnPropSymbols)
17
- for (var prop of __getOwnPropSymbols(b)) {
18
- if (__propIsEnum.call(b, prop))
19
- __defNormalProp(a, prop, b[prop]);
20
- }
21
- return a;
22
- };
23
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
- var __commonJS = (cb, mod) => function __require() {
25
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
26
- };
27
- var __copyProps = (to, from, except, desc) => {
28
- if (from && typeof from === "object" || typeof from === "function") {
29
- for (let key of __getOwnPropNames(from))
30
- if (!__hasOwnProp.call(to, key) && key !== except)
31
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
32
- }
33
- return to;
34
- };
35
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
36
- // If the importer is in node compatibility mode or this is not an ESM
37
- // file that has been converted to a CommonJS file using a Babel-
38
- // compatible transform (i.e. "__esModule" has not been set), then set
39
- // "default" to the CommonJS "module.exports" for node compatibility.
40
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
41
- mod
42
- ));
43
-
44
- // ../../node_modules/.pnpm/dayjs@1.11.11/node_modules/dayjs/dayjs.min.js
45
- var require_dayjs_min = __commonJS({
46
- "../../node_modules/.pnpm/dayjs@1.11.11/node_modules/dayjs/dayjs.min.js"(exports, module) {
1
+ (function(global, factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") factory(exports, require("crypto"), require("@midscene/core"), require("@midscene/shared/constants"), require("@midscene/core/utils"), require("assert"), require("fs"), require("path"), require("@midscene/shared/fs"), require("@midscene/shared/utils"), require("@midscene/shared/img"), require("@playwright/test"));
3
+ else if (typeof define === "function" && define.amd) define([
4
+ "exports",
5
+ "crypto",
6
+ "@midscene/core",
7
+ "@midscene/shared/constants",
8
+ "@midscene/core/utils",
9
+ "assert",
10
+ "fs",
11
+ "path",
12
+ "@midscene/shared/fs",
13
+ "@midscene/shared/utils",
14
+ "@midscene/shared/img",
15
+ "@playwright/test"
16
+ ], factory);
17
+ else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.playwright = {}, global.crypto, global.core, global.constants, global.utils, global.assert, global.fs, global.path, global.fs, global.utils, global.img, global.test);
18
+ })(this, function(exports, _crypto, _core, _constants, _utils, _assert, _fs, _path, _fs1, _utils1, _img, _test) {
47
19
  "use strict";
48
- !function(t, e) {
49
- "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
50
- }(exports, function() {
51
- "use strict";
52
- var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) {
53
- var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100;
54
- return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
55
- } }, m = function(t2, e2, n2) {
56
- var r2 = String(t2);
57
- return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
58
- }, v = { s: m, z: function(t2) {
59
- var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
60
- return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
61
- }, m: function t2(e2, n2) {
62
- if (e2.date() < n2.date())
63
- return -t2(n2, e2);
64
- var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c);
65
- return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
66
- }, a: function(t2) {
67
- return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
68
- }, p: function(t2) {
69
- return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, "");
70
- }, u: function(t2) {
71
- return void 0 === t2;
72
- } }, g = "en", D = {};
73
- D[g] = M;
74
- var p = "$isDayjsObject", S = function(t2) {
75
- return t2 instanceof _ || !(!t2 || !t2[p]);
76
- }, w = function t2(e2, n2, r2) {
77
- var i2;
78
- if (!e2)
79
- return g;
80
- if ("string" == typeof e2) {
81
- var s2 = e2.toLowerCase();
82
- D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
83
- var u2 = e2.split("-");
84
- if (!i2 && u2.length > 1)
85
- return t2(u2[0]);
86
- } else {
87
- var a2 = e2.name;
88
- D[a2] = e2, i2 = a2;
89
- }
90
- return !r2 && i2 && (g = i2), i2 || !r2 && g;
91
- }, O = function(t2, e2) {
92
- if (S(t2))
93
- return t2.clone();
94
- var n2 = "object" == typeof e2 ? e2 : {};
95
- return n2.date = t2, n2.args = arguments, new _(n2);
96
- }, b = v;
97
- b.l = w, b.i = S, b.w = function(t2, e2) {
98
- return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
99
- };
100
- var _ = function() {
101
- function M2(t2) {
102
- this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
103
- }
104
- var m2 = M2.prototype;
105
- return m2.parse = function(t2) {
106
- this.$d = function(t3) {
107
- var e2 = t3.date, n2 = t3.utc;
108
- if (null === e2)
109
- return /* @__PURE__ */ new Date(NaN);
110
- if (b.u(e2))
111
- return /* @__PURE__ */ new Date();
112
- if (e2 instanceof Date)
113
- return new Date(e2);
114
- if ("string" == typeof e2 && !/Z$/i.test(e2)) {
115
- var r2 = e2.match($);
116
- if (r2) {
117
- var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
118
- return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2);
119
- }
120
- }
121
- return new Date(e2);
122
- }(t2), this.init();
123
- }, m2.init = function() {
124
- var t2 = this.$d;
125
- this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds();
126
- }, m2.$utils = function() {
127
- return b;
128
- }, m2.isValid = function() {
129
- return !(this.$d.toString() === l);
130
- }, m2.isSame = function(t2, e2) {
131
- var n2 = O(t2);
132
- return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
133
- }, m2.isAfter = function(t2, e2) {
134
- return O(t2) < this.startOf(e2);
135
- }, m2.isBefore = function(t2, e2) {
136
- return this.endOf(e2) < O(t2);
137
- }, m2.$g = function(t2, e2, n2) {
138
- return b.u(t2) ? this[e2] : this.set(n2, t2);
139
- }, m2.unix = function() {
140
- return Math.floor(this.valueOf() / 1e3);
141
- }, m2.valueOf = function() {
142
- return this.$d.getTime();
143
- }, m2.startOf = function(t2, e2) {
144
- var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) {
145
- var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
146
- return r2 ? i2 : i2.endOf(a);
147
- }, $2 = function(t3, e3) {
148
- return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2);
149
- }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
150
- switch (f2) {
151
- case h:
152
- return r2 ? l2(1, 0) : l2(31, 11);
153
- case c:
154
- return r2 ? l2(1, M3) : l2(0, M3 + 1);
155
- case o:
156
- var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
157
- return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
158
- case a:
159
- case d:
160
- return $2(v2 + "Hours", 0);
161
- case u:
162
- return $2(v2 + "Minutes", 1);
163
- case s:
164
- return $2(v2 + "Seconds", 2);
165
- case i:
166
- return $2(v2 + "Milliseconds", 3);
167
- default:
168
- return this.clone();
169
- }
170
- }, m2.endOf = function(t2) {
171
- return this.startOf(t2, false);
172
- }, m2.$set = function(t2, e2) {
173
- var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2;
174
- if (o2 === c || o2 === h) {
175
- var y2 = this.clone().set(d, 1);
176
- y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
177
- } else
178
- l2 && this.$d[l2]($2);
179
- return this.init(), this;
180
- }, m2.set = function(t2, e2) {
181
- return this.clone().$set(t2, e2);
182
- }, m2.get = function(t2) {
183
- return this[b.p(t2)]();
184
- }, m2.add = function(r2, f2) {
185
- var d2, l2 = this;
186
- r2 = Number(r2);
187
- var $2 = b.p(f2), y2 = function(t2) {
188
- var e2 = O(l2);
189
- return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
190
- };
191
- if ($2 === c)
192
- return this.set(c, this.$M + r2);
193
- if ($2 === h)
194
- return this.set(h, this.$y + r2);
195
- if ($2 === a)
196
- return y2(1);
197
- if ($2 === o)
198
- return y2(7);
199
- var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3;
200
- return b.w(m3, this);
201
- }, m2.subtract = function(t2, e2) {
202
- return this.add(-1 * t2, e2);
203
- }, m2.format = function(t2) {
204
- var e2 = this, n2 = this.$locale();
205
- if (!this.isValid())
206
- return n2.invalidDate || l;
207
- var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) {
208
- return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
209
- }, d2 = function(t3) {
210
- return b.s(s2 % 12 || 12, t3, "0");
211
- }, $2 = f2 || function(t3, e3, n3) {
212
- var r3 = t3 < 12 ? "AM" : "PM";
213
- return n3 ? r3.toLowerCase() : r3;
214
- };
215
- return r2.replace(y, function(t3, r3) {
216
- return r3 || function(t4) {
217
- switch (t4) {
218
- case "YY":
219
- return String(e2.$y).slice(-2);
220
- case "YYYY":
221
- return b.s(e2.$y, 4, "0");
222
- case "M":
223
- return a2 + 1;
224
- case "MM":
225
- return b.s(a2 + 1, 2, "0");
226
- case "MMM":
227
- return h2(n2.monthsShort, a2, c2, 3);
228
- case "MMMM":
229
- return h2(c2, a2);
230
- case "D":
231
- return e2.$D;
232
- case "DD":
233
- return b.s(e2.$D, 2, "0");
234
- case "d":
235
- return String(e2.$W);
236
- case "dd":
237
- return h2(n2.weekdaysMin, e2.$W, o2, 2);
238
- case "ddd":
239
- return h2(n2.weekdaysShort, e2.$W, o2, 3);
240
- case "dddd":
241
- return o2[e2.$W];
242
- case "H":
243
- return String(s2);
244
- case "HH":
245
- return b.s(s2, 2, "0");
246
- case "h":
247
- return d2(1);
248
- case "hh":
249
- return d2(2);
250
- case "a":
251
- return $2(s2, u2, true);
252
- case "A":
253
- return $2(s2, u2, false);
254
- case "m":
255
- return String(u2);
256
- case "mm":
257
- return b.s(u2, 2, "0");
258
- case "s":
259
- return String(e2.$s);
260
- case "ss":
261
- return b.s(e2.$s, 2, "0");
262
- case "SSS":
263
- return b.s(e2.$ms, 3, "0");
264
- case "Z":
265
- return i2;
266
- }
267
- return null;
268
- }(t3) || i2.replace(":", "");
269
- });
270
- }, m2.utcOffset = function() {
271
- return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
272
- }, m2.diff = function(r2, d2, l2) {
273
- var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() {
274
- return b.m(y2, m3);
275
- };
276
- switch (M3) {
277
- case h:
278
- $2 = D2() / 12;
279
- break;
280
- case c:
281
- $2 = D2();
282
- break;
283
- case f:
284
- $2 = D2() / 3;
285
- break;
286
- case o:
287
- $2 = (g2 - v2) / 6048e5;
288
- break;
289
- case a:
290
- $2 = (g2 - v2) / 864e5;
291
- break;
292
- case u:
293
- $2 = g2 / n;
294
- break;
295
- case s:
296
- $2 = g2 / e;
297
- break;
298
- case i:
299
- $2 = g2 / t;
300
- break;
301
- default:
302
- $2 = g2;
303
- }
304
- return l2 ? $2 : b.a($2);
305
- }, m2.daysInMonth = function() {
306
- return this.endOf(c).$D;
307
- }, m2.$locale = function() {
308
- return D[this.$L];
309
- }, m2.locale = function(t2, e2) {
310
- if (!t2)
311
- return this.$L;
312
- var n2 = this.clone(), r2 = w(t2, e2, true);
313
- return r2 && (n2.$L = r2), n2;
314
- }, m2.clone = function() {
315
- return b.w(this.$d, this);
316
- }, m2.toDate = function() {
317
- return new Date(this.valueOf());
318
- }, m2.toJSON = function() {
319
- return this.isValid() ? this.toISOString() : null;
320
- }, m2.toISOString = function() {
321
- return this.$d.toISOString();
322
- }, m2.toString = function() {
323
- return this.$d.toUTCString();
324
- }, M2;
325
- }(), k = _.prototype;
326
- return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) {
327
- k[t2[1]] = function(e2) {
328
- return this.$g(e2, t2[0], t2[1]);
329
- };
330
- }), O.extend = function(t2, e2) {
331
- return t2.$i || (t2(e2, _, O), t2.$i = true), O;
332
- }, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
333
- return O(1e3 * t2);
334
- }, O.en = D[g], O.Ls = D, O.p = {}, O;
20
+ Object.defineProperty(exports, "__esModule", {
21
+ value: true
335
22
  });
336
- }
337
- });
338
-
339
- // src/playwright/ai-fixture.ts
340
- import { randomUUID as randomUUID2 } from "crypto";
341
-
342
- // src/common/agent.ts
343
- import {
344
- groupedActionDumpFileExt,
345
- stringifyDumpData as stringifyDumpData2,
346
- writeLogFile as writeLogFile2
347
- } from "@midscene/core/utils";
348
-
349
- // src/common/tasks.ts
350
- import assert2 from "assert";
351
- import {
352
- Executor,
353
- Insight,
354
- plan
355
- } from "@midscene/core";
356
- import { sleep } from "@midscene/core/utils";
357
- import { base64Encoded as base64Encoded2 } from "@midscene/shared/img";
358
-
359
- // src/common/task-cache.ts
360
- import { existsSync, readFileSync as readFileSync2 } from "fs";
361
- import { join } from "path";
362
- import {
363
- getLogDirByType,
364
- stringifyDumpData,
365
- writeLogFile
366
- } from "@midscene/core/utils";
367
- import { getMidscenePkgInfo } from "@midscene/shared/fs";
368
-
369
- // src/common/utils.ts
370
- var import_dayjs = __toESM(require_dayjs_min());
371
- import assert from "assert";
372
- import { randomUUID } from "crypto";
373
- import { readFileSync } from "fs";
374
- import path from "path";
375
- import { NodeType } from "@midscene/shared/constants";
376
- import { findNearestPackageJson } from "@midscene/shared/fs";
377
- import {
378
- base64Encoded,
379
- imageInfoOfBase64
380
- } from "@midscene/shared/img";
381
- import { compositeElementInfoImg } from "@midscene/shared/img";
382
-
383
- // src/web-element.ts
384
- var WebElementInfo = class {
385
- constructor({
386
- content,
387
- rect,
388
- page,
389
- locator,
390
- id,
391
- attributes,
392
- indexId
393
- }) {
394
- this.content = content;
395
- this.rect = rect;
396
- this.center = [
397
- Math.floor(rect.left + rect.width / 2),
398
- Math.floor(rect.top + rect.height / 2)
399
- ];
400
- this.page = page;
401
- this.locator = locator;
402
- this.id = id;
403
- this.attributes = attributes;
404
- this.indexId = indexId;
405
- }
406
- };
407
-
408
- // src/common/utils.ts
409
- async function parseContextFromWebPage(page, _opt) {
410
- assert(page, "page is required");
411
- if (page._forceUsePageContext) {
412
- return await page._forceUsePageContext();
413
- }
414
- const url = page.url();
415
- const file = await page.screenshot();
416
- const screenshotBase64 = base64Encoded(file);
417
- const captureElementSnapshot = await page.getElementInfos();
418
- const elementsInfo = await alignElements(captureElementSnapshot, page);
419
- const elementsPositionInfoWithoutText = elementsInfo.filter((elementInfo) => {
420
- if (elementInfo.attributes.nodeType === NodeType.TEXT) {
421
- return false;
23
+ function _export(target, all) {
24
+ for(var name in all)Object.defineProperty(target, name, {
25
+ enumerable: true,
26
+ get: all[name]
27
+ });
422
28
  }
423
- return true;
424
- });
425
- const size = await imageInfoOfBase64(screenshotBase64);
426
- const screenshotBase64WithElementMarker = await compositeElementInfoImg({
427
- inputImgBase64: screenshotBase64.split(";base64,").pop(),
428
- elementsPositionInfo: elementsPositionInfoWithoutText
429
- });
430
- return {
431
- content: elementsInfo,
432
- size,
433
- screenshotBase64,
434
- screenshotBase64WithElementMarker: `data:image/png;base64,${screenshotBase64WithElementMarker}`,
435
- url
436
- };
437
- }
438
- async function getExtraReturnLogic() {
439
- const pathDir = findNearestPackageJson(__dirname);
440
- assert(pathDir, `can't find pathDir, with ${__dirname}`);
441
- const scriptPath = path.join(pathDir, "./dist/script/htmlElement.js");
442
- const elementInfosScriptContent = readFileSync(scriptPath, "utf-8");
443
- return `${elementInfosScriptContent}midscene_element_inspector.webExtractTextWithPosition()`;
444
- }
445
- var sizeThreshold = 3;
446
- async function alignElements(elements, page) {
447
- const validElements = elements.filter((item) => {
448
- return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
449
- });
450
- const textsAligned = [];
451
- for (const item of validElements) {
452
- const { rect, id, content, attributes, locator, indexId } = item;
453
- textsAligned.push(
454
- new WebElementInfo({
455
- rect,
456
- locator,
457
- id,
458
- content,
459
- attributes,
460
- page,
461
- indexId
462
- })
463
- );
464
- }
465
- return textsAligned;
466
- }
467
- function reportFileName(tag = "web") {
468
- const dateTimeInFileName = (0, import_dayjs.default)().format("YYYY-MM-DD_HH-mm-ss-SSS");
469
- return `${tag}-${dateTimeInFileName}`;
470
- }
471
- function printReportMsg(filepath) {
472
- console.log("Midscene - report file updated:", filepath);
473
- }
474
- function getCurrentExecutionFile(trace) {
475
- const error = new Error();
476
- const stackTrace = trace || error.stack;
477
- const pkgDir = process.cwd() || "";
478
- if (stackTrace) {
479
- const stackLines = stackTrace.split("\n");
480
- for (const line of stackLines) {
481
- if (line.includes(".spec.") || line.includes(".test.") || line.includes(".ts") || line.includes(".js")) {
482
- const match = line.match(/(?:at\s+)?(.*?\.(?:spec|test)\.[jt]s)/);
483
- if (match == null ? void 0 : match[1]) {
484
- const targetFileName = match[1].replace(pkgDir, "").trim().replace("at ", "");
485
- return targetFileName;
29
+ _export(exports, {
30
+ PlaywrightAgent: function() {
31
+ return PageAgent;
32
+ },
33
+ PlaywrightAiFixture: function() {
34
+ return PlaywrightAiFixture;
35
+ },
36
+ PlaywrightWebPage: function() {
37
+ return WebPage;
486
38
  }
487
- }
39
+ });
40
+ _assert = /*#__PURE__*/ _interop_require_default(_assert);
41
+ _path = /*#__PURE__*/ _interop_require_wildcard(_path);
42
+ function _interop_require_default(obj) {
43
+ return obj && obj.__esModule ? obj : {
44
+ default: obj
45
+ };
488
46
  }
489
- }
490
- return false;
491
- }
492
- var testFileIndex = /* @__PURE__ */ new Map();
493
- function generateCacheId(fileName) {
494
- let taskFile = fileName || getCurrentExecutionFile();
495
- if (!taskFile) {
496
- taskFile = randomUUID();
497
- console.warn(
498
- "Midscene - using random UUID for cache id. Cache may be invalid."
499
- );
500
- }
501
- if (testFileIndex.has(taskFile)) {
502
- const currentIndex = testFileIndex.get(taskFile);
503
- if (currentIndex !== void 0) {
504
- testFileIndex.set(taskFile, currentIndex + 1);
47
+ function _getRequireWildcardCache(nodeInterop) {
48
+ if (typeof WeakMap !== "function") return null;
49
+ var cacheBabelInterop = new WeakMap();
50
+ var cacheNodeInterop = new WeakMap();
51
+ return (_getRequireWildcardCache = function(nodeInterop) {
52
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
53
+ })(nodeInterop);
505
54
  }
506
- } else {
507
- testFileIndex.set(taskFile, 1);
508
- }
509
- return `${taskFile}-${testFileIndex.get(taskFile)}`;
510
- }
511
-
512
- // src/common/task-cache.ts
513
- var TaskCache = class {
514
- constructor(opts) {
515
- this.midscenePkgInfo = getMidscenePkgInfo(__dirname);
516
- this.cacheId = generateCacheId(opts == null ? void 0 : opts.fileName);
517
- this.cache = this.readCacheFromFile() || {
518
- aiTasks: []
55
+ function _interop_require_wildcard(obj, nodeInterop) {
56
+ if (!nodeInterop && obj && obj.__esModule) {
57
+ return obj;
58
+ }
59
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
60
+ return {
61
+ default: obj
62
+ };
63
+ }
64
+ var cache = _getRequireWildcardCache(nodeInterop);
65
+ if (cache && cache.has(obj)) {
66
+ return cache.get(obj);
67
+ }
68
+ var newObj = {
69
+ __proto__: null
70
+ };
71
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
72
+ for(var key in obj){
73
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
74
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
75
+ if (desc && (desc.get || desc.set)) {
76
+ Object.defineProperty(newObj, key, desc);
77
+ } else {
78
+ newObj[key] = obj[key];
79
+ }
80
+ }
81
+ }
82
+ newObj.default = obj;
83
+ if (cache) {
84
+ cache.set(obj, newObj);
85
+ }
86
+ return newObj;
87
+ }
88
+ var __create = Object.create;
89
+ var __defProp = Object.defineProperty;
90
+ var __defProps = Object.defineProperties;
91
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
92
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
93
+ var __getOwnPropNames = Object.getOwnPropertyNames;
94
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
95
+ var __getProtoOf = Object.getPrototypeOf;
96
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
97
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
98
+ var __defNormalProp = (obj, key, value)=>key in obj ? __defProp(obj, key, {
99
+ enumerable: true,
100
+ configurable: true,
101
+ writable: true,
102
+ value
103
+ }) : obj[key] = value;
104
+ var __spreadValues = (a, b)=>{
105
+ for(var prop in b || (b = {}))if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
106
+ if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)){
107
+ if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
108
+ }
109
+ return a;
519
110
  };
520
- this.newCache = {
521
- aiTasks: []
111
+ var __spreadProps = (a, b)=>__defProps(a, __getOwnPropDescs(b));
112
+ var __commonJS = (cb, mod)=>function __require() {
113
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = {
114
+ exports: {}
115
+ }).exports, mod), mod.exports;
116
+ };
117
+ var __copyProps = (to, from, except, desc)=>{
118
+ if (from && typeof from === "object" || typeof from === "function") {
119
+ for (let key of __getOwnPropNames(from))if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
120
+ get: ()=>from[key],
121
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
122
+ });
123
+ }
124
+ return to;
522
125
  };
523
- }
524
- getCacheGroupByPrompt(aiActionPrompt) {
525
- const { aiTasks = [] } = this.cache || { aiTasks: [] };
526
- const index = aiTasks.findIndex((item) => item.prompt === aiActionPrompt);
527
- const newCacheGroup = [];
528
- this.newCache.aiTasks.push({
529
- prompt: aiActionPrompt,
530
- tasks: newCacheGroup
531
- });
532
- return {
533
- readCache: (pageContext, type, actionPrompt) => {
534
- if (index === -1) {
535
- return false;
126
+ var __toESM = (mod, isNodeMode, target)=>(target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(// If the importer is in node compatibility mode or this is not an ESM
127
+ // file that has been converted to a CommonJS file using a Babel-
128
+ // compatible transform (i.e. "__esModule" has not been set), then set
129
+ // "default" to the CommonJS "module.exports" for node compatibility.
130
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
131
+ value: mod,
132
+ enumerable: true
133
+ }) : target, mod));
134
+ var __async = (__this, __arguments, generator)=>{
135
+ return new Promise((resolve, reject)=>{
136
+ var fulfilled = (value)=>{
137
+ try {
138
+ step(generator.next(value));
139
+ } catch (e) {
140
+ reject(e);
141
+ }
142
+ };
143
+ var rejected = (value)=>{
144
+ try {
145
+ step(generator.throw(value));
146
+ } catch (e) {
147
+ reject(e);
148
+ }
149
+ };
150
+ var step = (x)=>x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
151
+ step((generator = generator.apply(__this, __arguments)).next());
152
+ });
153
+ };
154
+ // ../../node_modules/.pnpm/dayjs@1.11.11/node_modules/dayjs/dayjs.min.js
155
+ var require_dayjs_min = __commonJS({
156
+ "../../node_modules/.pnpm/dayjs@1.11.11/node_modules/dayjs/dayjs.min.js" (exports, module1) {
157
+ "use strict";
158
+ !function(t, e) {
159
+ "object" == typeof exports && "undefined" != typeof module1 ? module1.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
160
+ }(exports, function() {
161
+ "use strict";
162
+ var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = {
163
+ name: "en",
164
+ weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
165
+ months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
166
+ ordinal: function(t2) {
167
+ var e2 = [
168
+ "th",
169
+ "st",
170
+ "nd",
171
+ "rd"
172
+ ], n2 = t2 % 100;
173
+ return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
174
+ }
175
+ }, m = function(t2, e2, n2) {
176
+ var r2 = String(t2);
177
+ return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
178
+ }, v = {
179
+ s: m,
180
+ z: function(t2) {
181
+ var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
182
+ return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
183
+ },
184
+ m: function t2(e2, n2) {
185
+ if (e2.date() < n2.date()) return -t2(n2, e2);
186
+ var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c);
187
+ return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
188
+ },
189
+ a: function(t2) {
190
+ return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
191
+ },
192
+ p: function(t2) {
193
+ return ({
194
+ M: c,
195
+ y: h,
196
+ w: o,
197
+ d: a,
198
+ D: d,
199
+ h: u,
200
+ m: s,
201
+ s: i,
202
+ ms: r,
203
+ Q: f
204
+ })[t2] || String(t2 || "").toLowerCase().replace(/s$/, "");
205
+ },
206
+ u: function(t2) {
207
+ return void 0 === t2;
208
+ }
209
+ }, g = "en", D = {};
210
+ D[g] = M;
211
+ var p = "$isDayjsObject", S = function(t2) {
212
+ return t2 instanceof _ || !(!t2 || !t2[p]);
213
+ }, w = function t2(e2, n2, r2) {
214
+ var i2;
215
+ if (!e2) return g;
216
+ if ("string" == typeof e2) {
217
+ var s2 = e2.toLowerCase();
218
+ D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
219
+ var u2 = e2.split("-");
220
+ if (!i2 && u2.length > 1) return t2(u2[0]);
221
+ } else {
222
+ var a2 = e2.name;
223
+ D[a2] = e2, i2 = a2;
224
+ }
225
+ return !r2 && i2 && (g = i2), i2 || !r2 && g;
226
+ }, O = function(t2, e2) {
227
+ if (S(t2)) return t2.clone();
228
+ var n2 = "object" == typeof e2 ? e2 : {};
229
+ return n2.date = t2, n2.args = arguments, new _(n2);
230
+ }, b = v;
231
+ b.l = w, b.i = S, b.w = function(t2, e2) {
232
+ return O(t2, {
233
+ locale: e2.$L,
234
+ utc: e2.$u,
235
+ x: e2.$x,
236
+ $offset: e2.$offset
237
+ });
238
+ };
239
+ var _ = function() {
240
+ function M2(t2) {
241
+ this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
242
+ }
243
+ var m2 = M2.prototype;
244
+ return m2.parse = function(t2) {
245
+ this.$d = function(t3) {
246
+ var e2 = t3.date, n2 = t3.utc;
247
+ if (null === e2) return /* @__PURE__ */ new Date(NaN);
248
+ if (b.u(e2)) return /* @__PURE__ */ new Date();
249
+ if (e2 instanceof Date) return new Date(e2);
250
+ if ("string" == typeof e2 && !/Z$/i.test(e2)) {
251
+ var r2 = e2.match($);
252
+ if (r2) {
253
+ var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
254
+ return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2);
255
+ }
256
+ }
257
+ return new Date(e2);
258
+ }(t2), this.init();
259
+ }, m2.init = function() {
260
+ var t2 = this.$d;
261
+ this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds();
262
+ }, m2.$utils = function() {
263
+ return b;
264
+ }, m2.isValid = function() {
265
+ return !(this.$d.toString() === l);
266
+ }, m2.isSame = function(t2, e2) {
267
+ var n2 = O(t2);
268
+ return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
269
+ }, m2.isAfter = function(t2, e2) {
270
+ return O(t2) < this.startOf(e2);
271
+ }, m2.isBefore = function(t2, e2) {
272
+ return this.endOf(e2) < O(t2);
273
+ }, m2.$g = function(t2, e2, n2) {
274
+ return b.u(t2) ? this[e2] : this.set(n2, t2);
275
+ }, m2.unix = function() {
276
+ return Math.floor(this.valueOf() / 1e3);
277
+ }, m2.valueOf = function() {
278
+ return this.$d.getTime();
279
+ }, m2.startOf = function(t2, e2) {
280
+ var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) {
281
+ var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
282
+ return r2 ? i2 : i2.endOf(a);
283
+ }, $2 = function(t3, e3) {
284
+ return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [
285
+ 0,
286
+ 0,
287
+ 0,
288
+ 0
289
+ ] : [
290
+ 23,
291
+ 59,
292
+ 59,
293
+ 999
294
+ ]).slice(e3)), n2);
295
+ }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
296
+ switch(f2){
297
+ case h:
298
+ return r2 ? l2(1, 0) : l2(31, 11);
299
+ case c:
300
+ return r2 ? l2(1, M3) : l2(0, M3 + 1);
301
+ case o:
302
+ var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
303
+ return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
304
+ case a:
305
+ case d:
306
+ return $2(v2 + "Hours", 0);
307
+ case u:
308
+ return $2(v2 + "Minutes", 1);
309
+ case s:
310
+ return $2(v2 + "Seconds", 2);
311
+ case i:
312
+ return $2(v2 + "Milliseconds", 3);
313
+ default:
314
+ return this.clone();
315
+ }
316
+ }, m2.endOf = function(t2) {
317
+ return this.startOf(t2, false);
318
+ }, m2.$set = function(t2, e2) {
319
+ var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2;
320
+ if (o2 === c || o2 === h) {
321
+ var y2 = this.clone().set(d, 1);
322
+ y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
323
+ } else l2 && this.$d[l2]($2);
324
+ return this.init(), this;
325
+ }, m2.set = function(t2, e2) {
326
+ return this.clone().$set(t2, e2);
327
+ }, m2.get = function(t2) {
328
+ return this[b.p(t2)]();
329
+ }, m2.add = function(r2, f2) {
330
+ var d2, l2 = this;
331
+ r2 = Number(r2);
332
+ var $2 = b.p(f2), y2 = function(t2) {
333
+ var e2 = O(l2);
334
+ return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
335
+ };
336
+ if ($2 === c) return this.set(c, this.$M + r2);
337
+ if ($2 === h) return this.set(h, this.$y + r2);
338
+ if ($2 === a) return y2(1);
339
+ if ($2 === o) return y2(7);
340
+ var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3;
341
+ return b.w(m3, this);
342
+ }, m2.subtract = function(t2, e2) {
343
+ return this.add(-1 * t2, e2);
344
+ }, m2.format = function(t2) {
345
+ var e2 = this, n2 = this.$locale();
346
+ if (!this.isValid()) return n2.invalidDate || l;
347
+ var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) {
348
+ return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
349
+ }, d2 = function(t3) {
350
+ return b.s(s2 % 12 || 12, t3, "0");
351
+ }, $2 = f2 || function(t3, e3, n3) {
352
+ var r3 = t3 < 12 ? "AM" : "PM";
353
+ return n3 ? r3.toLowerCase() : r3;
354
+ };
355
+ return r2.replace(y, function(t3, r3) {
356
+ return r3 || function(t4) {
357
+ switch(t4){
358
+ case "YY":
359
+ return String(e2.$y).slice(-2);
360
+ case "YYYY":
361
+ return b.s(e2.$y, 4, "0");
362
+ case "M":
363
+ return a2 + 1;
364
+ case "MM":
365
+ return b.s(a2 + 1, 2, "0");
366
+ case "MMM":
367
+ return h2(n2.monthsShort, a2, c2, 3);
368
+ case "MMMM":
369
+ return h2(c2, a2);
370
+ case "D":
371
+ return e2.$D;
372
+ case "DD":
373
+ return b.s(e2.$D, 2, "0");
374
+ case "d":
375
+ return String(e2.$W);
376
+ case "dd":
377
+ return h2(n2.weekdaysMin, e2.$W, o2, 2);
378
+ case "ddd":
379
+ return h2(n2.weekdaysShort, e2.$W, o2, 3);
380
+ case "dddd":
381
+ return o2[e2.$W];
382
+ case "H":
383
+ return String(s2);
384
+ case "HH":
385
+ return b.s(s2, 2, "0");
386
+ case "h":
387
+ return d2(1);
388
+ case "hh":
389
+ return d2(2);
390
+ case "a":
391
+ return $2(s2, u2, true);
392
+ case "A":
393
+ return $2(s2, u2, false);
394
+ case "m":
395
+ return String(u2);
396
+ case "mm":
397
+ return b.s(u2, 2, "0");
398
+ case "s":
399
+ return String(e2.$s);
400
+ case "ss":
401
+ return b.s(e2.$s, 2, "0");
402
+ case "SSS":
403
+ return b.s(e2.$ms, 3, "0");
404
+ case "Z":
405
+ return i2;
406
+ }
407
+ return null;
408
+ }(t3) || i2.replace(":", "");
409
+ });
410
+ }, m2.utcOffset = function() {
411
+ return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
412
+ }, m2.diff = function(r2, d2, l2) {
413
+ var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() {
414
+ return b.m(y2, m3);
415
+ };
416
+ switch(M3){
417
+ case h:
418
+ $2 = D2() / 12;
419
+ break;
420
+ case c:
421
+ $2 = D2();
422
+ break;
423
+ case f:
424
+ $2 = D2() / 3;
425
+ break;
426
+ case o:
427
+ $2 = (g2 - v2) / 6048e5;
428
+ break;
429
+ case a:
430
+ $2 = (g2 - v2) / 864e5;
431
+ break;
432
+ case u:
433
+ $2 = g2 / n;
434
+ break;
435
+ case s:
436
+ $2 = g2 / e;
437
+ break;
438
+ case i:
439
+ $2 = g2 / t;
440
+ break;
441
+ default:
442
+ $2 = g2;
443
+ }
444
+ return l2 ? $2 : b.a($2);
445
+ }, m2.daysInMonth = function() {
446
+ return this.endOf(c).$D;
447
+ }, m2.$locale = function() {
448
+ return D[this.$L];
449
+ }, m2.locale = function(t2, e2) {
450
+ if (!t2) return this.$L;
451
+ var n2 = this.clone(), r2 = w(t2, e2, true);
452
+ return r2 && (n2.$L = r2), n2;
453
+ }, m2.clone = function() {
454
+ return b.w(this.$d, this);
455
+ }, m2.toDate = function() {
456
+ return new Date(this.valueOf());
457
+ }, m2.toJSON = function() {
458
+ return this.isValid() ? this.toISOString() : null;
459
+ }, m2.toISOString = function() {
460
+ return this.$d.toISOString();
461
+ }, m2.toString = function() {
462
+ return this.$d.toUTCString();
463
+ }, M2;
464
+ }(), k = _.prototype;
465
+ return O.prototype = k, [
466
+ [
467
+ "$ms",
468
+ r
469
+ ],
470
+ [
471
+ "$s",
472
+ i
473
+ ],
474
+ [
475
+ "$m",
476
+ s
477
+ ],
478
+ [
479
+ "$H",
480
+ u
481
+ ],
482
+ [
483
+ "$W",
484
+ a
485
+ ],
486
+ [
487
+ "$M",
488
+ c
489
+ ],
490
+ [
491
+ "$y",
492
+ h
493
+ ],
494
+ [
495
+ "$D",
496
+ d
497
+ ]
498
+ ].forEach(function(t2) {
499
+ k[t2[1]] = function(e2) {
500
+ return this.$g(e2, t2[0], t2[1]);
501
+ };
502
+ }), O.extend = function(t2, e2) {
503
+ return t2.$i || (t2(e2, _, O), t2.$i = true), O;
504
+ }, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
505
+ return O(1e3 * t2);
506
+ }, O.en = D[g], O.Ls = D, O.p = {}, O;
507
+ });
536
508
  }
537
- if (type === "plan") {
538
- return this.readCache(
539
- pageContext,
540
- type,
541
- actionPrompt,
542
- aiTasks[index].tasks
543
- );
509
+ });
510
+ // src/common/utils.ts
511
+ var import_dayjs = __toESM(require_dayjs_min());
512
+ // src/web-element.ts
513
+ var WebElementInfo = class {
514
+ constructor({ content, rect, page, locator, id, attributes, indexId }){
515
+ this.content = content;
516
+ this.rect = rect;
517
+ this.center = [
518
+ Math.floor(rect.left + rect.width / 2),
519
+ Math.floor(rect.top + rect.height / 2)
520
+ ];
521
+ this.page = page;
522
+ this.locator = locator;
523
+ this.id = id;
524
+ this.attributes = attributes;
525
+ this.indexId = indexId;
544
526
  }
545
- return this.readCache(
546
- pageContext,
547
- type,
548
- actionPrompt,
549
- aiTasks[index].tasks
550
- );
551
- },
552
- saveCache: (cache) => {
553
- newCacheGroup.push(cache);
554
- this.writeCacheToFile();
555
- }
556
527
  };
557
- }
558
- readCache(pageContext, type, userPrompt, cacheGroup) {
559
- var _a;
560
- if (cacheGroup.length > 0) {
561
- const index = cacheGroup.findIndex((item) => item.prompt === userPrompt);
562
- if (index === -1) {
563
- return false;
564
- }
565
- const taskRes = cacheGroup.splice(index, 1)[0];
566
- if ((taskRes == null ? void 0 : taskRes.type) === "locate" && !((_a = taskRes.response) == null ? void 0 : _a.elements.every((element) => {
567
- const findIndex = pageContext.content.findIndex(
568
- (contentElement) => contentElement.id === element.id
569
- );
570
- if (findIndex === -1) {
571
- return false;
528
+ // src/common/utils.ts
529
+ function parseContextFromWebPage(page, _opt) {
530
+ return __async(this, null, function*() {
531
+ (0, _assert.default)(page, "page is required");
532
+ if (page._forceUsePageContext) {
533
+ return yield page._forceUsePageContext();
534
+ }
535
+ const url = yield page.url();
536
+ let screenshotBase64;
537
+ let elementsInfo;
538
+ yield Promise.all([
539
+ page.screenshotBase64().then((base64)=>{
540
+ screenshotBase64 = base64;
541
+ }),
542
+ page.getElementInfos().then((snapshot)=>__async(this, null, function*() {
543
+ elementsInfo = yield alignElements(snapshot, page);
544
+ }))
545
+ ]);
546
+ (0, _assert.default)(screenshotBase64, "screenshotBase64 is required");
547
+ const elementsPositionInfoWithoutText = elementsInfo.filter((elementInfo)=>{
548
+ if (elementInfo.attributes.nodeType === _constants.NodeType.TEXT) {
549
+ return false;
550
+ }
551
+ return true;
552
+ });
553
+ const size = yield page.size();
554
+ const width = size.width;
555
+ const height = size.height;
556
+ const screenshotBase64WithElementMarker = (_opt == null ? void 0 : _opt.ignoreMarker) ? void 0 : yield (0, _img.compositeElementInfoImg)({
557
+ inputImgBase64: screenshotBase64,
558
+ elementsPositionInfo: elementsPositionInfoWithoutText,
559
+ size: {
560
+ width,
561
+ height
562
+ }
563
+ });
564
+ return {
565
+ content: elementsInfo,
566
+ size: {
567
+ width,
568
+ height
569
+ },
570
+ screenshotBase64,
571
+ screenshotBase64WithElementMarker,
572
+ url
573
+ };
574
+ });
575
+ }
576
+ function getExtraReturnLogic() {
577
+ return __async(this, null, function*() {
578
+ const pathDir = (0, _fs1.findNearestPackageJson)(__dirname);
579
+ (0, _assert.default)(pathDir, `can't find pathDir, with ${__dirname}`);
580
+ const scriptPath = _path.default.join(pathDir, "./dist/script/htmlElement.js");
581
+ const elementInfosScriptContent = (0, _fs.readFileSync)(scriptPath, "utf-8");
582
+ return `${elementInfosScriptContent}midscene_element_inspector.webExtractTextWithPosition()`;
583
+ });
584
+ }
585
+ var sizeThreshold = 3;
586
+ function alignElements(elements, page) {
587
+ return __async(this, null, function*() {
588
+ const validElements = elements.filter((item)=>{
589
+ return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
590
+ });
591
+ const textsAligned = [];
592
+ for (const item of validElements){
593
+ const { rect, id, content, attributes, locator, indexId } = item;
594
+ textsAligned.push(new WebElementInfo({
595
+ rect,
596
+ locator,
597
+ id,
598
+ content,
599
+ attributes,
600
+ page,
601
+ indexId
602
+ }));
603
+ }
604
+ return textsAligned;
605
+ });
606
+ }
607
+ function reportFileName(tag = "web") {
608
+ const dateTimeInFileName = (0, import_dayjs.default)().format("YYYY-MM-DD_HH-mm-ss-SSS");
609
+ return `${tag}-${dateTimeInFileName}`;
610
+ }
611
+ function printReportMsg(filepath) {
612
+ console.log("Midscene - report file updated:", filepath);
613
+ }
614
+ function getCurrentExecutionFile(trace) {
615
+ const error = new Error();
616
+ const stackTrace = trace || error.stack;
617
+ const pkgDir = process.cwd() || "";
618
+ if (stackTrace) {
619
+ const stackLines = stackTrace.split("\n");
620
+ for (const line of stackLines){
621
+ if (line.includes(".spec.") || line.includes(".test.") || line.includes(".ts") || line.includes(".js")) {
622
+ const match = line.match(/(?:at\s+)?(.*?\.(?:spec|test)\.[jt]s)/);
623
+ if (match == null ? void 0 : match[1]) {
624
+ const targetFileName = match[1].replace(pkgDir, "").trim().replace("at ", "");
625
+ return targetFileName;
626
+ }
627
+ }
628
+ }
572
629
  }
573
- return true;
574
- }))) {
575
630
  return false;
576
- }
577
- if (taskRes && taskRes.type === type && taskRes.prompt === userPrompt && this.pageContextEqual(taskRes.pageContext, pageContext)) {
578
- return taskRes.response;
579
- }
580
631
  }
581
- return false;
582
- }
583
- pageContextEqual(taskPageContext, pageContext) {
584
- return taskPageContext.size.width === pageContext.size.width && taskPageContext.size.height === pageContext.size.height;
585
- }
586
- /**
632
+ var testFileIndex = /* @__PURE__ */ new Map();
633
+ function generateCacheId(fileName) {
634
+ let taskFile = fileName || getCurrentExecutionFile();
635
+ if (!taskFile) {
636
+ taskFile = (0, _utils1.uuid)();
637
+ console.warn("Midscene - using random UUID for cache id. Cache may be invalid.");
638
+ }
639
+ if (testFileIndex.has(taskFile)) {
640
+ const currentIndex = testFileIndex.get(taskFile);
641
+ if (currentIndex !== void 0) {
642
+ testFileIndex.set(taskFile, currentIndex + 1);
643
+ }
644
+ } else {
645
+ testFileIndex.set(taskFile, 1);
646
+ }
647
+ return `${taskFile}-${testFileIndex.get(taskFile)}`;
648
+ }
649
+ // src/common/task-cache.ts
650
+ var TaskCache = class {
651
+ getCacheGroupByPrompt(aiActionPrompt) {
652
+ const { aiTasks = [] } = this.cache || {
653
+ aiTasks: []
654
+ };
655
+ const index = aiTasks.findIndex((item)=>item.prompt === aiActionPrompt);
656
+ const newCacheGroup = [];
657
+ this.newCache.aiTasks.push({
658
+ prompt: aiActionPrompt,
659
+ tasks: newCacheGroup
660
+ });
661
+ return {
662
+ readCache: (pageContext, type, actionPrompt)=>{
663
+ if (index === -1) {
664
+ return false;
665
+ }
666
+ if (type === "plan") {
667
+ return this.readCache(pageContext, type, actionPrompt, aiTasks[index].tasks);
668
+ }
669
+ return this.readCache(pageContext, type, actionPrompt, aiTasks[index].tasks);
670
+ },
671
+ saveCache: (cache)=>{
672
+ newCacheGroup.push(cache);
673
+ this.writeCacheToFile();
674
+ }
675
+ };
676
+ }
677
+ readCache(pageContext, type, userPrompt, cacheGroup) {
678
+ var _a;
679
+ if (cacheGroup.length > 0) {
680
+ const index = cacheGroup.findIndex((item)=>item.prompt === userPrompt);
681
+ if (index === -1) {
682
+ return false;
683
+ }
684
+ const taskRes = cacheGroup.splice(index, 1)[0];
685
+ if ((taskRes == null ? void 0 : taskRes.type) === "locate" && !((_a = taskRes.response) == null ? void 0 : _a.elements.every((element)=>{
686
+ const findIndex = pageContext.content.findIndex((contentElement)=>contentElement.id === element.id);
687
+ if (findIndex === -1) {
688
+ return false;
689
+ }
690
+ return true;
691
+ }))) {
692
+ return false;
693
+ }
694
+ if (taskRes && taskRes.type === type && taskRes.prompt === userPrompt && this.pageContextEqual(taskRes.pageContext, pageContext)) {
695
+ return taskRes.response;
696
+ }
697
+ }
698
+ return false;
699
+ }
700
+ pageContextEqual(taskPageContext, pageContext) {
701
+ return taskPageContext.size.width === pageContext.size.width && taskPageContext.size.height === pageContext.size.height;
702
+ }
703
+ /**
587
704
  * Generate task cache data.
588
705
  * This method is mainly used to create or obtain some cached data for tasks, and it returns a new cache object.
589
706
  * In the cache object, it may contain task-related information, states, or other necessary data.
590
707
  * It is assumed that the `newCache` property already exists in the current class or object and is a data structure used to store task cache.
591
708
  * @returns {Object} Returns a new cache object, which may include task cache data.
592
- */
593
- generateTaskCache() {
594
- return this.newCache;
595
- }
596
- readCacheFromFile() {
597
- const cacheFile = join(getLogDirByType("cache"), `${this.cacheId}.json`);
598
- if (process.env.MIDSCENE_CACHE === "true" && existsSync(cacheFile)) {
599
- try {
600
- const data = readFileSync2(cacheFile, "utf8");
601
- const jsonData = JSON.parse(data);
602
- if (jsonData.pkgName !== this.midscenePkgInfo.name || jsonData.pkgVersion !== this.midscenePkgInfo.version) {
603
- return void 0;
709
+ */ generateTaskCache() {
710
+ return this.newCache;
604
711
  }
605
- return jsonData;
606
- } catch (err) {
607
- return void 0;
608
- }
609
- }
610
- return void 0;
611
- }
612
- writeCacheToFile() {
613
- const midscenePkgInfo = getMidscenePkgInfo(__dirname);
614
- writeLogFile({
615
- fileName: `${this.cacheId}`,
616
- fileExt: "json",
617
- fileContent: stringifyDumpData(
618
- __spreadValues({
619
- pkgName: midscenePkgInfo.name,
620
- pkgVersion: midscenePkgInfo.version,
621
- cacheId: this.cacheId
622
- }, this.newCache),
623
- 2
624
- ),
625
- type: "cache"
626
- });
627
- }
628
- };
629
-
630
- // src/common/tasks.ts
631
- var PageTaskExecutor = class {
632
- constructor(page, opts) {
633
- this.page = page;
634
- this.insight = new Insight(async () => {
635
- return await parseContextFromWebPage(page);
636
- });
637
- this.taskCache = new TaskCache({
638
- fileName: opts == null ? void 0 : opts.cacheId
639
- });
640
- }
641
- async recordScreenshot(timing) {
642
- const file = await this.page.screenshot();
643
- const item = {
644
- type: "screenshot",
645
- ts: Date.now(),
646
- screenshot: base64Encoded2(file),
647
- timing
648
- };
649
- return item;
650
- }
651
- wrapExecutorWithScreenshot(taskApply) {
652
- const taskWithScreenshot = __spreadProps(__spreadValues({}, taskApply), {
653
- executor: async (param, context, ...args) => {
654
- const recorder = [];
655
- const { task } = context;
656
- task.recorder = recorder;
657
- const shot = await this.recordScreenshot(`before ${task.type}`);
658
- recorder.push(shot);
659
- const result = await taskApply.executor(param, context, ...args);
660
- if (taskApply.type === "Action") {
661
- await sleep(1e3);
662
- const shot2 = await this.recordScreenshot("after Action");
663
- recorder.push(shot2);
664
- }
665
- return result;
666
- }
667
- });
668
- return taskWithScreenshot;
669
- }
670
- async convertPlanToExecutable(plans, cacheGroup) {
671
- const tasks = plans.map((plan2) => {
672
- if (plan2.type === "Locate") {
673
- const taskFind = {
674
- type: "Insight",
675
- subType: "Locate",
676
- param: plan2.param,
677
- executor: async (param, taskContext) => {
678
- const { task } = taskContext;
679
- let insightDump;
680
- const dumpCollector = (dump) => {
681
- insightDump = dump;
682
- };
683
- this.insight.onceDumpUpdatedFn = dumpCollector;
684
- const pageContext = await this.insight.contextRetrieverFn();
685
- const locateCache = cacheGroup == null ? void 0 : cacheGroup.readCache(
686
- pageContext,
687
- "locate",
688
- param.prompt
689
- );
690
- let locateResult;
691
- const callAI = this.insight.aiVendorFn;
692
- const element = await this.insight.locate(param.prompt, {
693
- quickAnswer: plan2.quickAnswer,
694
- callAI: async (...message) => {
695
- if (locateCache) {
696
- locateResult = locateCache;
697
- return Promise.resolve(locateCache);
712
+ readCacheFromFile() {
713
+ if (_utils1.ifInBrowser) {
714
+ return void 0;
715
+ }
716
+ const cacheFile = (0, _path.join)((0, _utils.getLogDirByType)("cache"), `${this.cacheId}.json`);
717
+ if (process.env.MIDSCENE_CACHE === "true" && (0, _fs.existsSync)(cacheFile)) {
718
+ try {
719
+ const data = (0, _fs.readFileSync)(cacheFile, "utf8");
720
+ const jsonData = JSON.parse(data);
721
+ if (!this.midscenePkgInfo) {
722
+ return void 0;
723
+ }
724
+ if (jsonData.pkgName !== this.midscenePkgInfo.name || jsonData.pkgVersion !== this.midscenePkgInfo.version) {
725
+ return void 0;
726
+ }
727
+ return jsonData;
728
+ } catch (err) {
729
+ return void 0;
698
730
  }
699
- locateResult = await callAI(...message);
700
- assert2(locateResult);
701
- return locateResult;
702
- }
703
- });
704
- if (locateResult) {
705
- cacheGroup == null ? void 0 : cacheGroup.saveCache({
706
- type: "locate",
707
- pageContext: {
708
- url: pageContext.url,
709
- size: pageContext.size
710
- },
711
- prompt: param.prompt,
712
- response: locateResult
713
- });
714
731
  }
715
- if (!element) {
716
- task.log = {
717
- dump: insightDump
718
- };
719
- throw new Error(`Element not found: ${param.prompt}`);
732
+ return void 0;
733
+ }
734
+ writeCacheToFile() {
735
+ const midscenePkgInfo = (0, _fs1.getRunningPkgInfo)();
736
+ if (!midscenePkgInfo) {
737
+ return;
720
738
  }
721
- return {
722
- output: {
723
- element
724
- },
725
- log: {
726
- dump: insightDump
727
- },
728
- cache: {
729
- hit: Boolean(locateCache)
730
- }
739
+ if (!_utils1.ifInBrowser) {
740
+ (0, _utils.writeLogFile)({
741
+ fileName: `${this.cacheId}`,
742
+ fileExt: "json",
743
+ fileContent: (0, _utils.stringifyDumpData)(__spreadValues({
744
+ pkgName: midscenePkgInfo.name,
745
+ pkgVersion: midscenePkgInfo.version,
746
+ cacheId: this.cacheId
747
+ }, this.newCache), 2),
748
+ type: "cache"
749
+ });
750
+ }
751
+ }
752
+ constructor(opts){
753
+ this.midscenePkgInfo = (0, _fs1.getRunningPkgInfo)();
754
+ this.cacheId = generateCacheId(opts == null ? void 0 : opts.fileName);
755
+ this.cache = this.readCacheFromFile() || {
756
+ aiTasks: []
731
757
  };
732
- }
733
- };
734
- return taskFind;
735
- }
736
- if (plan2.type === "Assert" || plan2.type === "AssertWithoutThrow") {
737
- const assertPlan = plan2;
738
- const taskAssert = {
739
- type: "Insight",
740
- subType: "Assert",
741
- param: assertPlan.param,
742
- executor: async (param, taskContext) => {
743
- const { task } = taskContext;
744
- let insightDump;
745
- const dumpCollector = (dump) => {
746
- insightDump = dump;
758
+ this.newCache = {
759
+ aiTasks: []
747
760
  };
748
- this.insight.onceDumpUpdatedFn = dumpCollector;
749
- const assertion = await this.insight.assert(
750
- assertPlan.param.assertion
751
- );
752
- if (!assertion.pass) {
753
- if (plan2.type === "Assert") {
754
- task.output = assertion;
755
- task.log = {
756
- dump: insightDump
761
+ }
762
+ };
763
+ // src/common/tasks.ts
764
+ var PageTaskExecutor = class {
765
+ recordScreenshot(timing) {
766
+ return __async(this, null, function*() {
767
+ const base64 = yield this.page.screenshotBase64();
768
+ const item = {
769
+ type: "screenshot",
770
+ ts: Date.now(),
771
+ screenshot: base64,
772
+ timing
757
773
  };
758
- throw new Error(
759
- assertion.thought || "Assertion failed without reason"
760
- );
761
- }
762
- task.error = assertion.thought;
763
- }
764
- return {
765
- output: assertion,
766
- log: {
767
- dump: insightDump
768
- }
774
+ return item;
775
+ });
776
+ }
777
+ wrapExecutorWithScreenshot(taskApply) {
778
+ const taskWithScreenshot = __spreadProps(__spreadValues({}, taskApply), {
779
+ executor: (param, context, ...args)=>__async(this, null, function*() {
780
+ const recorder = [];
781
+ const { task } = context;
782
+ task.recorder = recorder;
783
+ const shot = yield this.recordScreenshot(`before ${task.type}`);
784
+ recorder.push(shot);
785
+ const result = yield taskApply.executor(param, context, ...args);
786
+ if (taskApply.type === "Action") {
787
+ yield (0, _utils.sleep)(1e3);
788
+ const shot2 = yield this.recordScreenshot("after Action");
789
+ recorder.push(shot2);
790
+ }
791
+ return result;
792
+ })
793
+ });
794
+ return taskWithScreenshot;
795
+ }
796
+ convertPlanToExecutable(plans, cacheGroup) {
797
+ return __async(this, null, function*() {
798
+ const tasks = plans.map((plan2)=>{
799
+ if (plan2.type === "Locate") {
800
+ const taskFind = {
801
+ type: "Insight",
802
+ subType: "Locate",
803
+ param: plan2.param,
804
+ quickAnswer: plan2.quickAnswer,
805
+ executor: (param, taskContext)=>__async(this, null, function*() {
806
+ const { task } = taskContext;
807
+ let insightDump;
808
+ const dumpCollector = (dump)=>{
809
+ insightDump = dump;
810
+ };
811
+ this.insight.onceDumpUpdatedFn = dumpCollector;
812
+ const pageContext = yield this.insight.contextRetrieverFn();
813
+ const locateCache = cacheGroup == null ? void 0 : cacheGroup.readCache(pageContext, "locate", param.prompt);
814
+ let locateResult;
815
+ const callAI = this.insight.aiVendorFn;
816
+ const element = yield this.insight.locate(param.prompt, {
817
+ quickAnswer: task.quickAnswer,
818
+ callAI: (...message)=>__async(this, null, function*() {
819
+ if (locateCache) {
820
+ locateResult = locateCache;
821
+ return Promise.resolve(locateCache);
822
+ }
823
+ const aiResult = yield callAI(...message);
824
+ locateResult = (0, _core.transformElementPositionToId)(aiResult, pageContext.content);
825
+ (0, _assert.default)(locateResult);
826
+ return locateResult;
827
+ })
828
+ });
829
+ if (locateResult) {
830
+ cacheGroup == null ? void 0 : cacheGroup.saveCache({
831
+ type: "locate",
832
+ pageContext: {
833
+ url: pageContext.url,
834
+ size: pageContext.size
835
+ },
836
+ prompt: param.prompt,
837
+ response: locateResult
838
+ });
839
+ }
840
+ if (!element) {
841
+ task.log = {
842
+ dump: insightDump
843
+ };
844
+ throw new Error(`Element not found: ${param.prompt}`);
845
+ }
846
+ return {
847
+ output: {
848
+ element
849
+ },
850
+ log: {
851
+ dump: insightDump
852
+ },
853
+ cache: {
854
+ hit: Boolean(locateCache)
855
+ }
856
+ };
857
+ })
858
+ };
859
+ return taskFind;
860
+ }
861
+ if (plan2.type === "Assert" || plan2.type === "AssertWithoutThrow") {
862
+ const assertPlan = plan2;
863
+ const taskAssert = {
864
+ type: "Insight",
865
+ subType: "Assert",
866
+ param: assertPlan.param,
867
+ executor: (param, taskContext)=>__async(this, null, function*() {
868
+ const { task } = taskContext;
869
+ let insightDump;
870
+ const dumpCollector = (dump)=>{
871
+ insightDump = dump;
872
+ };
873
+ this.insight.onceDumpUpdatedFn = dumpCollector;
874
+ const assertion = yield this.insight.assert(assertPlan.param.assertion);
875
+ if (!assertion.pass) {
876
+ if (plan2.type === "Assert") {
877
+ task.output = assertion;
878
+ task.log = {
879
+ dump: insightDump
880
+ };
881
+ throw new Error(assertion.thought || "Assertion failed without reason");
882
+ }
883
+ task.error = assertion.thought;
884
+ }
885
+ return {
886
+ output: assertion,
887
+ log: {
888
+ dump: insightDump
889
+ }
890
+ };
891
+ })
892
+ };
893
+ return taskAssert;
894
+ }
895
+ if (plan2.type === "Input") {
896
+ const taskActionInput = {
897
+ type: "Action",
898
+ subType: "Input",
899
+ param: plan2.param,
900
+ executor: (_0, _1)=>__async(this, [
901
+ _0,
902
+ _1
903
+ ], function*(taskParam, { element }) {
904
+ if (element) {
905
+ yield this.page.clearInput(element);
906
+ if (taskParam.value === "") {
907
+ return;
908
+ }
909
+ yield this.page.keyboard.type(taskParam.value);
910
+ }
911
+ })
912
+ };
913
+ return taskActionInput;
914
+ }
915
+ if (plan2.type === "KeyboardPress") {
916
+ const taskActionKeyboardPress = {
917
+ type: "Action",
918
+ subType: "KeyboardPress",
919
+ param: plan2.param,
920
+ executor: (taskParam)=>__async(this, null, function*() {
921
+ (0, _assert.default)(taskParam.value, "No key to press");
922
+ yield this.page.keyboard.press(taskParam.value);
923
+ })
924
+ };
925
+ return taskActionKeyboardPress;
926
+ }
927
+ if (plan2.type === "Tap") {
928
+ const taskActionTap = {
929
+ type: "Action",
930
+ subType: "Tap",
931
+ executor: (_0, _1)=>__async(this, [
932
+ _0,
933
+ _1
934
+ ], function*(param, { element }) {
935
+ (0, _assert.default)(element, "Element not found, cannot tap");
936
+ yield this.page.mouse.click(element.center[0], element.center[1]);
937
+ })
938
+ };
939
+ return taskActionTap;
940
+ }
941
+ if (plan2.type === "Hover") {
942
+ const taskActionHover = {
943
+ type: "Action",
944
+ subType: "Hover",
945
+ executor: (_0, _1)=>__async(this, [
946
+ _0,
947
+ _1
948
+ ], function*(param, { element }) {
949
+ (0, _assert.default)(element, "Element not found, cannot hover");
950
+ yield this.page.mouse.move(element.center[0], element.center[1]);
951
+ })
952
+ };
953
+ return taskActionHover;
954
+ }
955
+ if (plan2.type === "Scroll") {
956
+ const taskActionScroll = {
957
+ type: "Action",
958
+ subType: "Scroll",
959
+ param: plan2.param,
960
+ executor: (taskParam)=>__async(this, null, function*() {
961
+ const scrollToEventName = taskParam.scrollType;
962
+ switch(scrollToEventName){
963
+ case "scrollUntilTop":
964
+ yield this.page.scrollUntilTop();
965
+ break;
966
+ case "scrollUntilBottom":
967
+ yield this.page.scrollUntilBottom();
968
+ break;
969
+ case "scrollUpOneScreen":
970
+ yield this.page.scrollUpOneScreen();
971
+ break;
972
+ case "scrollDownOneScreen":
973
+ yield this.page.scrollDownOneScreen();
974
+ break;
975
+ default:
976
+ console.error("Unknown scroll event type:", scrollToEventName);
977
+ }
978
+ })
979
+ };
980
+ return taskActionScroll;
981
+ }
982
+ if (plan2.type === "Sleep") {
983
+ const taskActionSleep = {
984
+ type: "Action",
985
+ subType: "Sleep",
986
+ param: plan2.param,
987
+ executor: (taskParam)=>__async(this, null, function*() {
988
+ yield (0, _utils.sleep)(taskParam.timeMs || 3e3);
989
+ })
990
+ };
991
+ return taskActionSleep;
992
+ }
993
+ if (plan2.type === "Error") {
994
+ const taskActionError = {
995
+ type: "Action",
996
+ subType: "Error",
997
+ param: plan2.param,
998
+ executor: (taskParam)=>__async(this, null, function*() {
999
+ (0, _assert.default)(taskParam.thought, "An error occurred, but no thought provided");
1000
+ throw new Error(taskParam.thought);
1001
+ })
1002
+ };
1003
+ return taskActionError;
1004
+ }
1005
+ throw new Error(`Unknown or Unsupported task type: ${plan2.type}`);
1006
+ }).map((task)=>{
1007
+ return this.wrapExecutorWithScreenshot(task);
1008
+ });
1009
+ return tasks;
1010
+ });
1011
+ }
1012
+ action(userPrompt) {
1013
+ return __async(this, null, function*() {
1014
+ const taskExecutor = new _core.Executor(userPrompt);
1015
+ const cacheGroup = this.taskCache.getCacheGroupByPrompt(userPrompt);
1016
+ let plans = [];
1017
+ const planningTask = {
1018
+ type: "Planning",
1019
+ param: {
1020
+ userPrompt
1021
+ },
1022
+ executor: (param)=>__async(this, null, function*() {
1023
+ const pageContext = yield this.insight.contextRetrieverFn();
1024
+ let planResult;
1025
+ const planCache = cacheGroup.readCache(pageContext, "plan", userPrompt);
1026
+ if (planCache) {
1027
+ planResult = planCache;
1028
+ } else {
1029
+ planResult = yield (0, _core.plan)(param.userPrompt, {
1030
+ context: pageContext
1031
+ });
1032
+ }
1033
+ (0, _assert.default)(planResult.plans.length > 0, "No plans found");
1034
+ plans = planResult.plans;
1035
+ cacheGroup.saveCache({
1036
+ type: "plan",
1037
+ pageContext: {
1038
+ url: pageContext.url,
1039
+ size: pageContext.size
1040
+ },
1041
+ prompt: userPrompt,
1042
+ response: planResult
1043
+ });
1044
+ return {
1045
+ output: planResult,
1046
+ pageContext,
1047
+ cache: {
1048
+ hit: Boolean(planCache)
1049
+ }
1050
+ };
1051
+ })
1052
+ };
1053
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(planningTask));
1054
+ let output = yield taskExecutor.flush();
1055
+ if (taskExecutor.isInErrorState()) {
1056
+ return {
1057
+ output,
1058
+ executor: taskExecutor
1059
+ };
1060
+ }
1061
+ const executables = yield this.convertPlanToExecutable(plans, cacheGroup);
1062
+ yield taskExecutor.append(executables);
1063
+ output = yield taskExecutor.flush();
1064
+ return {
1065
+ output,
1066
+ executor: taskExecutor
1067
+ };
1068
+ });
1069
+ }
1070
+ query(demand) {
1071
+ return __async(this, null, function*() {
1072
+ const description = typeof demand === "string" ? demand : JSON.stringify(demand);
1073
+ const taskExecutor = new _core.Executor(description);
1074
+ const queryTask = {
1075
+ type: "Insight",
1076
+ subType: "Query",
1077
+ param: {
1078
+ dataDemand: demand
1079
+ },
1080
+ executor: (param)=>__async(this, null, function*() {
1081
+ let insightDump;
1082
+ const dumpCollector = (dump)=>{
1083
+ insightDump = dump;
1084
+ };
1085
+ this.insight.onceDumpUpdatedFn = dumpCollector;
1086
+ const data = yield this.insight.extract(param.dataDemand);
1087
+ return {
1088
+ output: data,
1089
+ log: {
1090
+ dump: insightDump
1091
+ }
1092
+ };
1093
+ })
1094
+ };
1095
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(queryTask));
1096
+ const output = yield taskExecutor.flush();
1097
+ return {
1098
+ output,
1099
+ executor: taskExecutor
1100
+ };
1101
+ });
1102
+ }
1103
+ assert(assertion) {
1104
+ return __async(this, null, function*() {
1105
+ const description = `assert: ${assertion}`;
1106
+ const taskExecutor = new _core.Executor(description);
1107
+ const assertionPlan = {
1108
+ type: "Assert",
1109
+ param: {
1110
+ assertion
1111
+ }
1112
+ };
1113
+ const assertTask = yield this.convertPlanToExecutable([
1114
+ assertionPlan
1115
+ ]);
1116
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
1117
+ const output = yield taskExecutor.flush();
1118
+ return {
1119
+ output,
1120
+ executor: taskExecutor
1121
+ };
1122
+ });
1123
+ }
1124
+ waitFor(assertion, opt) {
1125
+ return __async(this, null, function*() {
1126
+ const description = `waitFor: ${assertion}`;
1127
+ const taskExecutor = new _core.Executor(description);
1128
+ const { timeoutMs, checkIntervalMs } = opt;
1129
+ (0, _assert.default)(assertion, "No assertion for waitFor");
1130
+ (0, _assert.default)(timeoutMs, "No timeoutMs for waitFor");
1131
+ (0, _assert.default)(checkIntervalMs, "No checkIntervalMs for waitFor");
1132
+ const overallStartTime = Date.now();
1133
+ let startTime = Date.now();
1134
+ let errorThought = "";
1135
+ while(Date.now() - overallStartTime < timeoutMs){
1136
+ startTime = Date.now();
1137
+ const assertPlan = {
1138
+ type: "AssertWithoutThrow",
1139
+ param: {
1140
+ assertion
1141
+ }
1142
+ };
1143
+ const assertTask = yield this.convertPlanToExecutable([
1144
+ assertPlan
1145
+ ]);
1146
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
1147
+ const output = yield taskExecutor.flush();
1148
+ if (output == null ? void 0 : output.pass) {
1149
+ return {
1150
+ output: void 0,
1151
+ executor: taskExecutor
1152
+ };
1153
+ }
1154
+ errorThought = (output == null ? void 0 : output.thought) || "unknown error";
1155
+ const now = Date.now();
1156
+ if (now - startTime < checkIntervalMs) {
1157
+ const timeRemaining = checkIntervalMs - (now - startTime);
1158
+ const sleepPlan = {
1159
+ type: "Sleep",
1160
+ param: {
1161
+ timeMs: timeRemaining
1162
+ }
1163
+ };
1164
+ const sleepTask = yield this.convertPlanToExecutable([
1165
+ sleepPlan
1166
+ ]);
1167
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(sleepTask[0]));
1168
+ yield taskExecutor.flush();
1169
+ }
1170
+ }
1171
+ const errorPlan = {
1172
+ type: "Error",
1173
+ param: {
1174
+ thought: `waitFor timeout: ${errorThought}`
1175
+ }
1176
+ };
1177
+ const errorTask = yield this.convertPlanToExecutable([
1178
+ errorPlan
1179
+ ]);
1180
+ yield taskExecutor.append(errorTask[0]);
1181
+ yield taskExecutor.flush();
1182
+ return {
1183
+ output: void 0,
1184
+ executor: taskExecutor
1185
+ };
1186
+ });
1187
+ }
1188
+ constructor(page, insight, opts){
1189
+ this.page = page;
1190
+ this.insight = insight;
1191
+ this.taskCache = new TaskCache({
1192
+ fileName: opts == null ? void 0 : opts.cacheId
1193
+ });
1194
+ }
1195
+ };
1196
+ // src/common/agent.ts
1197
+ var PageAgent = class {
1198
+ getUIContext() {
1199
+ return __async(this, null, function*() {
1200
+ return yield parseContextFromWebPage(this.page);
1201
+ });
1202
+ }
1203
+ resetDump() {
1204
+ this.dump = {
1205
+ groupName: this.opts.groupName,
1206
+ groupDescription: this.opts.groupDescription,
1207
+ executions: []
769
1208
  };
770
- }
771
- };
772
- return taskAssert;
773
- }
774
- if (plan2.type === "Input") {
775
- const taskActionInput = {
776
- type: "Action",
777
- subType: "Input",
778
- param: plan2.param,
779
- executor: async (taskParam, { element }) => {
780
- if (element) {
781
- await this.page.clearInput(element);
782
- if (taskParam.value === "") {
783
- return;
784
- }
785
- await this.page.keyboard.type(taskParam.value);
786
- }
787
- }
788
- };
789
- return taskActionInput;
790
- }
791
- if (plan2.type === "KeyboardPress") {
792
- const taskActionKeyboardPress = {
793
- type: "Action",
794
- subType: "KeyboardPress",
795
- param: plan2.param,
796
- executor: async (taskParam) => {
797
- assert2(taskParam.value, "No key to press");
798
- await this.page.keyboard.press(taskParam.value);
799
- }
800
- };
801
- return taskActionKeyboardPress;
802
- }
803
- if (plan2.type === "Tap") {
804
- const taskActionTap = {
805
- type: "Action",
806
- subType: "Tap",
807
- executor: async (param, { element }) => {
808
- assert2(element, "Element not found, cannot tap");
809
- await this.page.mouse.click(
810
- element.center[0],
811
- element.center[1]
812
- );
813
- }
814
- };
815
- return taskActionTap;
816
- }
817
- if (plan2.type === "Hover") {
818
- const taskActionHover = {
819
- type: "Action",
820
- subType: "Hover",
821
- executor: async (param, { element }) => {
822
- assert2(element, "Element not found, cannot hover");
823
- await this.page.mouse.move(
824
- element.center[0],
825
- element.center[1]
826
- );
827
- }
828
- };
829
- return taskActionHover;
830
- }
831
- if (plan2.type === "Scroll") {
832
- const taskActionScroll = {
833
- type: "Action",
834
- subType: "Scroll",
835
- param: plan2.param,
836
- executor: async (taskParam) => {
837
- const scrollToEventName = taskParam.scrollType;
838
- switch (scrollToEventName) {
839
- case "scrollUntilTop":
840
- await this.page.scrollUntilTop();
841
- break;
842
- case "scrollUntilBottom":
843
- await this.page.scrollUntilBottom();
844
- break;
845
- case "scrollUpOneScreen":
846
- await this.page.scrollUpOneScreen();
847
- break;
848
- case "scrollDownOneScreen":
849
- await this.page.scrollDownOneScreen();
850
- break;
851
- default:
852
- console.error(
853
- "Unknown scroll event type:",
854
- scrollToEventName
855
- );
1209
+ return this.dump;
1210
+ }
1211
+ appendExecutionDump(execution) {
1212
+ const currentDump = this.dump;
1213
+ currentDump.executions.push(execution);
1214
+ }
1215
+ dumpDataString() {
1216
+ this.dump.groupName = this.opts.groupName;
1217
+ this.dump.groupDescription = this.opts.groupDescription;
1218
+ return (0, _utils.stringifyDumpData)(this.dump);
1219
+ }
1220
+ reportHTMLString() {
1221
+ return (0, _utils.reportHTMLContent)(this.dumpDataString());
1222
+ }
1223
+ writeOutActionDumps() {
1224
+ const { generateReport, autoPrintReportMsg } = this.opts;
1225
+ this.reportFile = (0, _utils.writeLogFile)({
1226
+ fileName: this.reportFileName,
1227
+ fileExt: _utils.groupedActionDumpFileExt,
1228
+ fileContent: this.dumpDataString(),
1229
+ type: "dump",
1230
+ generateReport
1231
+ });
1232
+ if (generateReport && autoPrintReportMsg && this.reportFile) {
1233
+ printReportMsg(this.reportFile);
856
1234
  }
857
- }
858
- };
859
- return taskActionScroll;
860
- }
861
- if (plan2.type === "Sleep") {
862
- const taskActionSleep = {
863
- type: "Action",
864
- subType: "Sleep",
865
- param: plan2.param,
866
- executor: async (taskParam) => {
867
- await sleep(taskParam.timeMs || 3e3);
868
- }
869
- };
870
- return taskActionSleep;
871
- }
872
- if (plan2.type === "Error") {
873
- const taskActionError = {
874
- type: "Action",
875
- subType: "Error",
876
- param: plan2.param,
877
- executor: async (taskParam) => {
878
- assert2(
879
- taskParam.thought,
880
- "An error occurred, but no thought provided"
881
- );
882
- throw new Error(taskParam.thought);
883
- }
884
- };
885
- return taskActionError;
886
- }
887
- throw new Error(`Unknown or Unsupported task type: ${plan2.type}`);
888
- }).map((task) => {
889
- return this.wrapExecutorWithScreenshot(task);
890
- });
891
- return tasks;
892
- }
893
- async action(userPrompt) {
894
- const taskExecutor = new Executor(userPrompt);
895
- const cacheGroup = this.taskCache.getCacheGroupByPrompt(userPrompt);
896
- let plans = [];
897
- const planningTask = {
898
- type: "Planning",
899
- param: {
900
- userPrompt
901
- },
902
- executor: async (param) => {
903
- const pageContext = await this.insight.contextRetrieverFn();
904
- let planResult;
905
- const planCache = cacheGroup.readCache(pageContext, "plan", userPrompt);
906
- if (planCache) {
907
- planResult = planCache;
1235
+ }
1236
+ aiAction(taskPrompt) {
1237
+ return __async(this, null, function*() {
1238
+ const { executor } = yield this.taskExecutor.action(taskPrompt);
1239
+ this.appendExecutionDump(executor.dump());
1240
+ this.writeOutActionDumps();
1241
+ if (executor.isInErrorState()) {
1242
+ const errorTask = executor.latestErrorTask();
1243
+ throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1244
+ ${errorTask == null ? void 0 : errorTask.errorStack}`);
1245
+ }
1246
+ });
1247
+ }
1248
+ aiQuery(demand) {
1249
+ return __async(this, null, function*() {
1250
+ const { output, executor } = yield this.taskExecutor.query(demand);
1251
+ this.appendExecutionDump(executor.dump());
1252
+ this.writeOutActionDumps();
1253
+ if (executor.isInErrorState()) {
1254
+ const errorTask = executor.latestErrorTask();
1255
+ throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1256
+ ${errorTask == null ? void 0 : errorTask.errorStack}`);
1257
+ }
1258
+ return output;
1259
+ });
1260
+ }
1261
+ aiAssert(assertion, msg, opt) {
1262
+ return __async(this, null, function*() {
1263
+ var _a;
1264
+ const { output, executor } = yield this.taskExecutor.assert(assertion);
1265
+ this.appendExecutionDump(executor.dump());
1266
+ this.writeOutActionDumps();
1267
+ if (output && (opt == null ? void 0 : opt.keepRawResponse)) {
1268
+ return output;
1269
+ }
1270
+ if (!(output == null ? void 0 : output.pass)) {
1271
+ const errMsg = msg || `Assertion failed: ${assertion}`;
1272
+ const reasonMsg = `Reason: ${(output == null ? void 0 : output.thought) || ((_a = executor.latestErrorTask()) == null ? void 0 : _a.error) || "(no_reason)"}`;
1273
+ throw new Error(`${errMsg}
1274
+ ${reasonMsg}`);
1275
+ }
1276
+ });
1277
+ }
1278
+ aiWaitFor(assertion, opt) {
1279
+ return __async(this, null, function*() {
1280
+ const { executor } = yield this.taskExecutor.waitFor(assertion, {
1281
+ timeoutMs: (opt == null ? void 0 : opt.timeoutMs) || 15 * 1e3,
1282
+ checkIntervalMs: (opt == null ? void 0 : opt.checkIntervalMs) || 3 * 1e3,
1283
+ assertion
1284
+ });
1285
+ this.appendExecutionDump(executor.dump());
1286
+ this.writeOutActionDumps();
1287
+ if (executor.isInErrorState()) {
1288
+ const errorTask = executor.latestErrorTask();
1289
+ throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1290
+ ${errorTask == null ? void 0 : errorTask.errorStack}`);
1291
+ }
1292
+ });
1293
+ }
1294
+ ai(taskPrompt, type = "action") {
1295
+ return __async(this, null, function*() {
1296
+ if (type === "action") {
1297
+ return this.aiAction(taskPrompt);
1298
+ }
1299
+ if (type === "query") {
1300
+ return this.aiQuery(taskPrompt);
1301
+ }
1302
+ if (type === "assert") {
1303
+ return this.aiAssert(taskPrompt);
1304
+ }
1305
+ throw new Error(`Unknown type: ${type}, only support 'action', 'query', 'assert'`);
1306
+ });
1307
+ }
1308
+ destroy() {
1309
+ return __async(this, null, function*() {
1310
+ yield this.page.destroy();
1311
+ });
1312
+ }
1313
+ constructor(page, opts){
1314
+ /**
1315
+ * If true, the agent will not perform any actions
1316
+ */ this.dryMode = false;
1317
+ this.page = page;
1318
+ this.opts = Object.assign({
1319
+ generateReport: true,
1320
+ autoPrintReportMsg: true,
1321
+ groupName: "Midscene Report",
1322
+ groupDescription: ""
1323
+ }, opts || {});
1324
+ this.insight = new _core.Insight(()=>__async(this, null, function*() {
1325
+ return this.getUIContext();
1326
+ }), {
1327
+ generateElement: ({ content, rect })=>new WebElementInfo({
1328
+ content: content || "",
1329
+ rect,
1330
+ page,
1331
+ id: "",
1332
+ attributes: {
1333
+ nodeType: _constants.NodeType.CONTAINER
1334
+ },
1335
+ indexId: 0
1336
+ })
1337
+ });
1338
+ this.taskExecutor = new PageTaskExecutor(this.page, this.insight, {
1339
+ cacheId: opts == null ? void 0 : opts.cacheId
1340
+ });
1341
+ this.dump = this.resetDump();
1342
+ this.reportFileName = reportFileName((opts == null ? void 0 : opts.testId) || "web");
1343
+ }
1344
+ };
1345
+ var groupAndCaseForTest = (testInfo)=>{
1346
+ let taskFile;
1347
+ let taskTitle;
1348
+ const titlePath = [
1349
+ ...testInfo.titlePath
1350
+ ];
1351
+ if (titlePath.length > 1) {
1352
+ taskTitle = titlePath.pop() || "unnamed";
1353
+ taskFile = `${titlePath.join(" > ")}`;
1354
+ } else if (titlePath.length === 1) {
1355
+ taskTitle = titlePath[0];
1356
+ taskFile = `${taskTitle}`;
908
1357
  } else {
909
- planResult = await plan(param.userPrompt, {
910
- context: pageContext
911
- });
1358
+ taskTitle = "unnamed";
1359
+ taskFile = "unnamed";
912
1360
  }
913
- assert2(planResult.plans.length > 0, "No plans found");
914
- plans = planResult.plans;
915
- cacheGroup.saveCache({
916
- type: "plan",
917
- pageContext: {
918
- url: pageContext.url,
919
- size: pageContext.size
920
- },
921
- prompt: userPrompt,
922
- response: planResult
923
- });
924
1361
  return {
925
- output: planResult,
926
- cache: {
927
- hit: Boolean(planCache)
928
- }
1362
+ taskFile,
1363
+ taskTitle
929
1364
  };
930
- }
931
1365
  };
932
- await taskExecutor.append(this.wrapExecutorWithScreenshot(planningTask));
933
- let output = await taskExecutor.flush();
934
- if (taskExecutor.isInErrorState()) {
935
- return {
936
- output,
937
- executor: taskExecutor
938
- };
939
- }
940
- const executables = await this.convertPlanToExecutable(plans, cacheGroup);
941
- await taskExecutor.append(executables);
942
- output = await taskExecutor.flush();
943
- return {
944
- output,
945
- executor: taskExecutor
946
- };
947
- }
948
- async query(demand) {
949
- const description = typeof demand === "string" ? demand : JSON.stringify(demand);
950
- const taskExecutor = new Executor(description);
951
- const queryTask = {
952
- type: "Insight",
953
- subType: "Query",
954
- param: {
955
- dataDemand: demand
956
- },
957
- executor: async (param) => {
958
- let insightDump;
959
- const dumpCollector = (dump) => {
960
- insightDump = dump;
1366
+ var midsceneAgentKeyId = "_midsceneAgentId";
1367
+ var midsceneDumpAnnotationId = "MIDSCENE_DUMP_ANNOTATION";
1368
+ var PlaywrightAiFixture = ()=>{
1369
+ const pageAgentMap = {};
1370
+ const agentForPage = (page, testInfo)=>{
1371
+ let idForPage = page[midsceneAgentKeyId];
1372
+ if (!idForPage) {
1373
+ idForPage = (0, _crypto.randomUUID)();
1374
+ page[midsceneAgentKeyId] = idForPage;
1375
+ const { testId } = testInfo;
1376
+ const { taskFile, taskTitle } = groupAndCaseForTest(testInfo);
1377
+ pageAgentMap[idForPage] = new PageAgent(new WebPage(page), {
1378
+ testId: `playwright-${testId}-${idForPage}`,
1379
+ cacheId: taskFile,
1380
+ groupName: taskTitle,
1381
+ groupDescription: taskFile,
1382
+ generateReport: false
1383
+ });
1384
+ }
1385
+ return pageAgentMap[idForPage];
961
1386
  };
962
- this.insight.onceDumpUpdatedFn = dumpCollector;
963
- const data = await this.insight.extract(param.dataDemand);
964
- return {
965
- output: data,
966
- log: { dump: insightDump }
1387
+ const updateDumpAnnotation = (test2, dump)=>{
1388
+ const currentAnnotation = test2.annotations.find((item)=>{
1389
+ return item.type === midsceneDumpAnnotationId;
1390
+ });
1391
+ if (currentAnnotation) {
1392
+ currentAnnotation.description = dump;
1393
+ } else {
1394
+ test2.annotations.push({
1395
+ type: midsceneDumpAnnotationId,
1396
+ description: dump
1397
+ });
1398
+ }
967
1399
  };
968
- }
969
- };
970
- await taskExecutor.append(this.wrapExecutorWithScreenshot(queryTask));
971
- const output = await taskExecutor.flush();
972
- return {
973
- output,
974
- executor: taskExecutor
975
- };
976
- }
977
- async assert(assertion) {
978
- const description = `assert: ${assertion}`;
979
- const taskExecutor = new Executor(description);
980
- const assertionPlan = {
981
- type: "Assert",
982
- param: {
983
- assertion
984
- }
985
- };
986
- const assertTask = await this.convertPlanToExecutable([assertionPlan]);
987
- await taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
988
- const output = await taskExecutor.flush();
989
- return {
990
- output,
991
- executor: taskExecutor
992
- };
993
- }
994
- async waitFor(assertion, opt) {
995
- const description = `waitFor: ${assertion}`;
996
- const taskExecutor = new Executor(description);
997
- const { timeoutMs, checkIntervalMs } = opt;
998
- assert2(assertion, "No assertion for waitFor");
999
- assert2(timeoutMs, "No timeoutMs for waitFor");
1000
- assert2(checkIntervalMs, "No checkIntervalMs for waitFor");
1001
- const overallStartTime = Date.now();
1002
- let startTime = Date.now();
1003
- let errorThought = "";
1004
- while (Date.now() - overallStartTime < timeoutMs) {
1005
- startTime = Date.now();
1006
- const assertPlan = {
1007
- type: "AssertWithoutThrow",
1008
- param: {
1009
- assertion
1010
- }
1011
- };
1012
- const assertTask = await this.convertPlanToExecutable([assertPlan]);
1013
- await taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
1014
- const output = await taskExecutor.flush();
1015
- if (output == null ? void 0 : output.pass) {
1016
1400
  return {
1017
- output: void 0,
1018
- executor: taskExecutor
1019
- };
1020
- }
1021
- errorThought = (output == null ? void 0 : output.thought) || "unknown error";
1022
- const now = Date.now();
1023
- if (now - startTime < checkIntervalMs) {
1024
- const timeRemaining = checkIntervalMs - (now - startTime);
1025
- const sleepPlan = {
1026
- type: "Sleep",
1027
- param: {
1028
- timeMs: timeRemaining
1029
- }
1401
+ ai: (_0, _1, _2)=>__async(void 0, [
1402
+ _0,
1403
+ _1,
1404
+ _2
1405
+ ], function*({ page }, use, testInfo) {
1406
+ const agent = agentForPage(page, testInfo);
1407
+ yield use((taskPrompt, opts)=>__async(void 0, null, function*() {
1408
+ return new Promise((resolve, reject)=>{
1409
+ _test.test.step(`ai - ${taskPrompt}`, ()=>__async(void 0, null, function*() {
1410
+ yield waitForNetworkIdle(page);
1411
+ const actionType = (opts == null ? void 0 : opts.type) || "action";
1412
+ try {
1413
+ const result = yield agent.ai(taskPrompt, actionType);
1414
+ resolve(result);
1415
+ } catch (error) {
1416
+ reject(error);
1417
+ }
1418
+ }));
1419
+ });
1420
+ }));
1421
+ updateDumpAnnotation(testInfo, agent.dumpDataString());
1422
+ }),
1423
+ aiAction: (_0, _1, _2)=>__async(void 0, [
1424
+ _0,
1425
+ _1,
1426
+ _2
1427
+ ], function*({ page }, use, testInfo) {
1428
+ const agent = agentForPage(page, testInfo);
1429
+ yield use((taskPrompt)=>__async(void 0, null, function*() {
1430
+ return new Promise((resolve, reject)=>{
1431
+ _test.test.step(`aiAction - ${taskPrompt}`, ()=>__async(void 0, null, function*() {
1432
+ yield waitForNetworkIdle(page);
1433
+ try {
1434
+ const result = yield agent.aiAction(taskPrompt);
1435
+ resolve(result);
1436
+ } catch (error) {
1437
+ reject(error);
1438
+ }
1439
+ }));
1440
+ });
1441
+ }));
1442
+ updateDumpAnnotation(testInfo, agent.dumpDataString());
1443
+ }),
1444
+ aiQuery: (_0, _1, _2)=>__async(void 0, [
1445
+ _0,
1446
+ _1,
1447
+ _2
1448
+ ], function*({ page }, use, testInfo) {
1449
+ const agent = agentForPage(page, testInfo);
1450
+ yield use((demand)=>__async(void 0, null, function*() {
1451
+ return new Promise((resolve, reject)=>{
1452
+ _test.test.step(`aiQuery - ${JSON.stringify(demand)}`, ()=>__async(void 0, null, function*() {
1453
+ yield waitForNetworkIdle(page);
1454
+ try {
1455
+ const result = yield agent.aiQuery(demand);
1456
+ resolve(result);
1457
+ } catch (error) {
1458
+ reject(error);
1459
+ }
1460
+ }));
1461
+ });
1462
+ }));
1463
+ updateDumpAnnotation(testInfo, agent.dumpDataString());
1464
+ }),
1465
+ aiAssert: (_0, _1, _2)=>__async(void 0, [
1466
+ _0,
1467
+ _1,
1468
+ _2
1469
+ ], function*({ page }, use, testInfo) {
1470
+ const agent = agentForPage(page, testInfo);
1471
+ yield use((assertion, errorMsg)=>__async(void 0, null, function*() {
1472
+ return new Promise((resolve, reject)=>{
1473
+ _test.test.step(`aiAssert - ${assertion}`, ()=>__async(void 0, null, function*() {
1474
+ yield waitForNetworkIdle(page);
1475
+ try {
1476
+ yield agent.aiAssert(assertion, errorMsg);
1477
+ resolve(null);
1478
+ } catch (error) {
1479
+ reject(error);
1480
+ }
1481
+ }));
1482
+ });
1483
+ }));
1484
+ updateDumpAnnotation(testInfo, agent.dumpDataString());
1485
+ }),
1486
+ aiWaitFor: (_0, _1, _2)=>__async(void 0, [
1487
+ _0,
1488
+ _1,
1489
+ _2
1490
+ ], function*({ page }, use, testInfo) {
1491
+ const agent = agentForPage(page, testInfo);
1492
+ yield use((assertion, opt)=>__async(void 0, null, function*() {
1493
+ return new Promise((resolve, reject)=>{
1494
+ _test.test.step(`aiWaitFor - ${assertion}`, ()=>__async(void 0, null, function*() {
1495
+ yield waitForNetworkIdle(page);
1496
+ try {
1497
+ yield agent.aiWaitFor(assertion, opt);
1498
+ resolve(null);
1499
+ } catch (error) {
1500
+ reject(error);
1501
+ }
1502
+ }));
1503
+ });
1504
+ }));
1505
+ updateDumpAnnotation(testInfo, agent.dumpDataString());
1506
+ })
1030
1507
  };
1031
- const sleepTask = await this.convertPlanToExecutable([sleepPlan]);
1032
- await taskExecutor.append(
1033
- this.wrapExecutorWithScreenshot(sleepTask[0])
1034
- );
1035
- await taskExecutor.flush();
1036
- }
1037
- }
1038
- const errorPlan = {
1039
- type: "Error",
1040
- param: {
1041
- thought: `waitFor timeout: ${errorThought}`
1042
- }
1043
- };
1044
- const errorTask = await this.convertPlanToExecutable([errorPlan]);
1045
- await taskExecutor.append(errorTask[0]);
1046
- await taskExecutor.flush();
1047
- return {
1048
- output: void 0,
1049
- executor: taskExecutor
1050
- };
1051
- }
1052
- };
1053
-
1054
- // src/common/agent.ts
1055
- var PageAgent = class {
1056
- constructor(page, opts) {
1057
- this.page = page;
1058
- this.opts = Object.assign(
1059
- {
1060
- generateReport: true,
1061
- autoPrintReportMsg: true,
1062
- groupName: "Midscene Report",
1063
- groupDescription: ""
1064
- },
1065
- opts || {}
1066
- );
1067
- this.dump = {
1068
- groupName: this.opts.groupName,
1069
- groupDescription: this.opts.groupDescription,
1070
- executions: []
1071
1508
  };
1072
- this.taskExecutor = new PageTaskExecutor(this.page, {
1073
- cacheId: opts == null ? void 0 : opts.cacheId
1074
- });
1075
- this.reportFileName = reportFileName((opts == null ? void 0 : opts.testId) || "web");
1076
- }
1077
- appendExecutionDump(execution) {
1078
- const currentDump = this.dump;
1079
- currentDump.executions.push(execution);
1080
- }
1081
- dumpDataString() {
1082
- this.dump.groupName = this.opts.groupName;
1083
- this.dump.groupDescription = this.opts.groupDescription;
1084
- return stringifyDumpData2(this.dump);
1085
- }
1086
- writeOutActionDumps() {
1087
- const { generateReport, autoPrintReportMsg } = this.opts;
1088
- this.reportFile = writeLogFile2({
1089
- fileName: this.reportFileName,
1090
- fileExt: groupedActionDumpFileExt,
1091
- fileContent: this.dumpDataString(),
1092
- type: "dump",
1093
- generateReport
1094
- });
1095
- if (generateReport && autoPrintReportMsg) {
1096
- printReportMsg(this.reportFile);
1097
- }
1098
- }
1099
- async aiAction(taskPrompt) {
1100
- const { executor } = await this.taskExecutor.action(taskPrompt);
1101
- this.appendExecutionDump(executor.dump());
1102
- this.writeOutActionDumps();
1103
- if (executor.isInErrorState()) {
1104
- const errorTask = executor.latestErrorTask();
1105
- throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1106
- ${errorTask == null ? void 0 : errorTask.errorStack}`);
1107
- }
1108
- }
1109
- async aiQuery(demand) {
1110
- const { output, executor } = await this.taskExecutor.query(demand);
1111
- this.appendExecutionDump(executor.dump());
1112
- this.writeOutActionDumps();
1113
- if (executor.isInErrorState()) {
1114
- const errorTask = executor.latestErrorTask();
1115
- throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1116
- ${errorTask == null ? void 0 : errorTask.errorStack}`);
1117
- }
1118
- return output;
1119
- }
1120
- async aiAssert(assertion, msg, opt) {
1121
- const { output, executor } = await this.taskExecutor.assert(assertion);
1122
- this.appendExecutionDump(executor.dump());
1123
- this.writeOutActionDumps();
1124
- if (opt == null ? void 0 : opt.keepRawResponse) {
1125
- return output;
1126
- }
1127
- if (!(output == null ? void 0 : output.pass)) {
1128
- const errMsg = msg || `Assertion failed: ${assertion}`;
1129
- const reasonMsg = `Reason: ${(output == null ? void 0 : output.thought) || "(no_reason)"}`;
1130
- throw new Error(`${errMsg}
1131
- ${reasonMsg}`);
1132
- }
1133
- }
1134
- async aiWaitFor(assertion, opt) {
1135
- const { executor } = await this.taskExecutor.waitFor(assertion, {
1136
- timeoutMs: (opt == null ? void 0 : opt.timeoutMs) || 15 * 1e3,
1137
- checkIntervalMs: (opt == null ? void 0 : opt.checkIntervalMs) || 3 * 1e3,
1138
- assertion
1139
- });
1140
- this.appendExecutionDump(executor.dump());
1141
- this.writeOutActionDumps();
1142
- if (executor.isInErrorState()) {
1143
- const errorTask = executor.latestErrorTask();
1144
- throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1145
- ${errorTask == null ? void 0 : errorTask.errorStack}`);
1146
- }
1147
- }
1148
- async ai(taskPrompt, type = "action") {
1149
- if (type === "action") {
1150
- return this.aiAction(taskPrompt);
1151
- }
1152
- if (type === "query") {
1153
- return this.aiQuery(taskPrompt);
1154
- }
1155
- if (type === "assert") {
1156
- return this.aiAssert(taskPrompt);
1157
- }
1158
- throw new Error(
1159
- `Unknown type: ${type}, only support 'action', 'query', 'assert'`
1160
- );
1161
- }
1162
- };
1163
-
1164
- // src/playwright/ai-fixture.ts
1165
- import { test } from "@playwright/test";
1166
- var groupAndCaseForTest = (testInfo) => {
1167
- let taskFile;
1168
- let taskTitle;
1169
- const titlePath = [...testInfo.titlePath];
1170
- if (titlePath.length > 1) {
1171
- taskTitle = titlePath.pop() || "unnamed";
1172
- taskFile = `${titlePath.join(" > ")}`;
1173
- } else if (titlePath.length === 1) {
1174
- taskTitle = titlePath[0];
1175
- taskFile = `${taskTitle}`;
1176
- } else {
1177
- taskTitle = "unnamed";
1178
- taskFile = "unnamed";
1179
- }
1180
- return { taskFile, taskTitle };
1181
- };
1182
- var midsceneAgentKeyId = "_midsceneAgentId";
1183
- var midsceneDumpAnnotationId = "MIDSCENE_DUMP_ANNOTATION";
1184
- var PlaywrightAiFixture = () => {
1185
- const pageAgentMap = {};
1186
- const agentForPage = (page, testInfo) => {
1187
- let idForPage = page[midsceneAgentKeyId];
1188
- if (!idForPage) {
1189
- idForPage = randomUUID2();
1190
- page[midsceneAgentKeyId] = idForPage;
1191
- const { testId } = testInfo;
1192
- const { taskFile, taskTitle } = groupAndCaseForTest(testInfo);
1193
- pageAgentMap[idForPage] = new PageAgent(new WebPage(page), {
1194
- testId: `playwright-${testId}-${idForPage}`,
1195
- cacheId: taskFile,
1196
- groupName: taskTitle,
1197
- groupDescription: taskFile,
1198
- generateReport: false
1199
- // we will generate it in the reporter
1200
- });
1509
+ function waitForNetworkIdle(page) {
1510
+ const timeout = 20 * 1e3;
1511
+ return Promise.race([
1512
+ page.waitForLoadState("networkidle"),
1513
+ new Promise((resolve)=>setTimeout(resolve, timeout))
1514
+ ]);
1201
1515
  }
1202
- return pageAgentMap[idForPage];
1203
- };
1204
- const updateDumpAnnotation = (test2, dump) => {
1205
- const currentAnnotation = test2.annotations.find((item) => {
1206
- return item.type === midsceneDumpAnnotationId;
1207
- });
1208
- if (currentAnnotation) {
1209
- currentAnnotation.description = dump;
1210
- } else {
1211
- test2.annotations.push({
1212
- type: midsceneDumpAnnotationId,
1213
- description: dump
1214
- });
1215
- }
1216
- };
1217
- return {
1218
- ai: async ({ page }, use, testInfo) => {
1219
- const agent = agentForPage(page, testInfo);
1220
- await use(
1221
- async (taskPrompt, opts) => {
1222
- return new Promise((resolve, reject) => {
1223
- test.step(`ai - ${taskPrompt}`, async () => {
1224
- await waitForNetworkIdle(page);
1225
- const actionType = (opts == null ? void 0 : opts.type) || "action";
1226
- try {
1227
- const result = await agent.ai(taskPrompt, actionType);
1228
- resolve(result);
1229
- } catch (error) {
1230
- reject(error);
1231
- }
1516
+ var Page = class {
1517
+ evaluate(pageFunction, arg) {
1518
+ if (this.pageType === "puppeteer") {
1519
+ return this.underlyingPage.evaluate(pageFunction, arg);
1520
+ }
1521
+ return this.underlyingPage.evaluate(pageFunction, arg);
1522
+ }
1523
+ getElementInfos() {
1524
+ return __async(this, null, function*() {
1525
+ const scripts = yield getExtraReturnLogic();
1526
+ const captureElementSnapshot = yield this.evaluate(scripts);
1527
+ return captureElementSnapshot;
1232
1528
  });
1233
- });
1234
1529
  }
1235
- );
1236
- updateDumpAnnotation(testInfo, agent.dumpDataString());
1237
- },
1238
- aiAction: async ({ page }, use, testInfo) => {
1239
- const agent = agentForPage(page, testInfo);
1240
- await use(async (taskPrompt) => {
1241
- return new Promise((resolve, reject) => {
1242
- test.step(`aiAction - ${taskPrompt}`, async () => {
1243
- await waitForNetworkIdle(page);
1244
- try {
1245
- const result = await agent.aiAction(taskPrompt);
1246
- resolve(result);
1247
- } catch (error) {
1248
- reject(error);
1249
- }
1250
- });
1251
- });
1252
- });
1253
- updateDumpAnnotation(testInfo, agent.dumpDataString());
1254
- },
1255
- aiQuery: async ({ page }, use, testInfo) => {
1256
- const agent = agentForPage(page, testInfo);
1257
- await use(async (demand) => {
1258
- return new Promise((resolve, reject) => {
1259
- test.step(`aiQuery - ${JSON.stringify(demand)}`, async () => {
1260
- await waitForNetworkIdle(page);
1261
- try {
1262
- const result = await agent.aiQuery(demand);
1263
- resolve(result);
1264
- } catch (error) {
1265
- reject(error);
1266
- }
1267
- });
1268
- });
1269
- });
1270
- updateDumpAnnotation(testInfo, agent.dumpDataString());
1271
- },
1272
- aiAssert: async ({ page }, use, testInfo) => {
1273
- const agent = agentForPage(page, testInfo);
1274
- await use(async (assertion, errorMsg) => {
1275
- return new Promise((resolve, reject) => {
1276
- test.step(`aiAssert - ${assertion}`, async () => {
1277
- await waitForNetworkIdle(page);
1278
- try {
1279
- await agent.aiAssert(assertion, errorMsg);
1280
- resolve(null);
1281
- } catch (error) {
1282
- reject(error);
1283
- }
1284
- });
1285
- });
1286
- });
1287
- updateDumpAnnotation(testInfo, agent.dumpDataString());
1288
- },
1289
- aiWaitFor: async ({ page }, use, testInfo) => {
1290
- const agent = agentForPage(page, testInfo);
1291
- await use(async (assertion, opt) => {
1292
- return new Promise((resolve, reject) => {
1293
- test.step(`aiWaitFor - ${assertion}`, async () => {
1294
- await waitForNetworkIdle(page);
1295
- try {
1296
- await agent.aiWaitFor(assertion, opt);
1297
- resolve(null);
1298
- } catch (error) {
1299
- reject(error);
1300
- }
1301
- });
1302
- });
1303
- });
1304
- updateDumpAnnotation(testInfo, agent.dumpDataString());
1305
- }
1306
- };
1307
- };
1308
- function waitForNetworkIdle(page) {
1309
- const timeout = 20 * 1e3;
1310
- return Promise.race([
1311
- page.waitForLoadState("networkidle"),
1312
- new Promise((resolve) => setTimeout(resolve, timeout))
1313
- ]);
1314
- }
1315
-
1316
- // src/puppeteer/base-page.ts
1317
- import { readFileSync as readFileSync3, writeFileSync } from "fs";
1318
- import { getTmpFile } from "@midscene/core/utils";
1319
- import { resizeImg } from "@midscene/shared/img";
1320
- var Page = class {
1321
- evaluate(pageFunction, arg) {
1322
- if (this.pageType === "puppeteer") {
1323
- return this.page.evaluate(pageFunction, arg);
1324
- }
1325
- return this.page.evaluate(pageFunction, arg);
1326
- }
1327
- constructor(page, pageType) {
1328
- this.page = page;
1329
- this.pageType = pageType;
1330
- }
1331
- async getElementInfos() {
1332
- const scripts = await getExtraReturnLogic();
1333
- const captureElementSnapshot = await this.evaluate(scripts);
1334
- return captureElementSnapshot;
1335
- }
1336
- async screenshot() {
1337
- const viewportSize = await this.evaluate(() => {
1338
- return {
1339
- width: document.documentElement.clientWidth,
1340
- height: document.documentElement.clientHeight,
1341
- deviceScaleFactor: window.devicePixelRatio
1342
- };
1343
- });
1344
- const path2 = getTmpFile("png");
1345
- await this.page.screenshot({
1346
- path: path2,
1347
- type: "png"
1348
- });
1349
- let buf;
1350
- if (viewportSize.deviceScaleFactor > 1) {
1351
- buf = await resizeImg(readFileSync3(path2), {
1352
- width: viewportSize.width,
1353
- height: viewportSize.height
1354
- });
1355
- writeFileSync(path2, buf);
1356
- }
1357
- return path2;
1358
- }
1359
- url() {
1360
- return this.page.url();
1361
- }
1362
- get mouse() {
1363
- return {
1364
- click: async (x, y, options) => this.page.mouse.click(x, y, { button: (options == null ? void 0 : options.button) || "left" }),
1365
- wheel: async (deltaX, deltaY) => {
1366
- if (this.pageType === "puppeteer") {
1367
- await this.page.mouse.wheel({ deltaX, deltaY });
1368
- } else if (this.pageType === "playwright") {
1369
- await this.page.mouse.wheel(deltaX, deltaY);
1530
+ size() {
1531
+ return __async(this, null, function*() {
1532
+ if (this.viewportSize) return this.viewportSize;
1533
+ const sizeInfo = yield this.evaluate(()=>{
1534
+ return {
1535
+ width: document.documentElement.clientWidth,
1536
+ height: document.documentElement.clientHeight,
1537
+ dpr: window.devicePixelRatio
1538
+ };
1539
+ });
1540
+ this.viewportSize = sizeInfo;
1541
+ return sizeInfo;
1542
+ });
1543
+ }
1544
+ screenshotBase64() {
1545
+ return __async(this, null, function*() {
1546
+ const viewportSize = yield this.size();
1547
+ const path2 = (0, _utils.getTmpFile)("png");
1548
+ yield this.underlyingPage.screenshot({
1549
+ path: path2,
1550
+ type: "png"
1551
+ });
1552
+ let buf;
1553
+ if (viewportSize.dpr > 1) {
1554
+ buf = yield (0, _img.resizeImg)((0, _fs.readFileSync)(path2), {
1555
+ width: viewportSize.width,
1556
+ height: viewportSize.height
1557
+ });
1558
+ (0, _fs.writeFileSync)(path2, buf);
1559
+ }
1560
+ return (0, _img.base64Encoded)(path2, true);
1561
+ });
1562
+ }
1563
+ url() {
1564
+ return __async(this, null, function*() {
1565
+ return this.underlyingPage.url();
1566
+ });
1567
+ }
1568
+ get mouse() {
1569
+ return {
1570
+ click: (x, y, options)=>__async(this, null, function*() {
1571
+ return this.underlyingPage.mouse.click(x, y, {
1572
+ button: (options == null ? void 0 : options.button) || "left"
1573
+ });
1574
+ }),
1575
+ wheel: (deltaX, deltaY)=>__async(this, null, function*() {
1576
+ if (this.pageType === "puppeteer") {
1577
+ yield this.underlyingPage.mouse.wheel({
1578
+ deltaX,
1579
+ deltaY
1580
+ });
1581
+ } else if (this.pageType === "playwright") {
1582
+ yield this.underlyingPage.mouse.wheel(deltaX, deltaY);
1583
+ }
1584
+ }),
1585
+ move: (x, y)=>__async(this, null, function*() {
1586
+ return this.underlyingPage.mouse.move(x, y);
1587
+ })
1588
+ };
1589
+ }
1590
+ get keyboard() {
1591
+ return {
1592
+ type: (text)=>__async(this, null, function*() {
1593
+ return this.underlyingPage.keyboard.type(text);
1594
+ }),
1595
+ press: (key)=>__async(this, null, function*() {
1596
+ return this.underlyingPage.keyboard.press(key);
1597
+ }),
1598
+ down: (key)=>__async(this, null, function*() {
1599
+ return this.underlyingPage.keyboard.down(key);
1600
+ }),
1601
+ up: (key)=>__async(this, null, function*() {
1602
+ return this.underlyingPage.keyboard.up(key);
1603
+ })
1604
+ };
1605
+ }
1606
+ clearInput(element) {
1607
+ return __async(this, null, function*() {
1608
+ if (!element) {
1609
+ console.warn("No element to clear input");
1610
+ return;
1611
+ }
1612
+ yield this.mouse.click(element.center[0], element.center[1]);
1613
+ const isMac = process.platform === "darwin";
1614
+ if (isMac) {
1615
+ yield this.underlyingPage.keyboard.down("Meta");
1616
+ yield this.underlyingPage.keyboard.press("a");
1617
+ yield this.underlyingPage.keyboard.up("Meta");
1618
+ } else {
1619
+ yield this.underlyingPage.keyboard.down("Control");
1620
+ yield this.underlyingPage.keyboard.press("a");
1621
+ yield this.underlyingPage.keyboard.up("Control");
1622
+ }
1623
+ yield this.keyboard.press("Backspace");
1624
+ });
1625
+ }
1626
+ scrollUntilTop() {
1627
+ return this.mouse.wheel(0, -9999999);
1628
+ }
1629
+ scrollUntilBottom() {
1630
+ return this.mouse.wheel(0, 9999999);
1631
+ }
1632
+ scrollUpOneScreen() {
1633
+ return __async(this, null, function*() {
1634
+ const innerHeight = yield this.evaluate(()=>window.innerHeight);
1635
+ const distance = innerHeight * 0.7;
1636
+ yield this.mouse.wheel(0, -distance);
1637
+ });
1638
+ }
1639
+ scrollDownOneScreen() {
1640
+ return __async(this, null, function*() {
1641
+ const innerHeight = yield this.evaluate(()=>window.innerHeight);
1642
+ const distance = innerHeight * 0.7;
1643
+ yield this.mouse.wheel(0, distance);
1644
+ });
1645
+ }
1646
+ destroy() {
1647
+ return __async(this, null, function*() {});
1648
+ }
1649
+ constructor(underlyingPage, pageType){
1650
+ this.underlyingPage = underlyingPage;
1651
+ this.pageType = pageType;
1370
1652
  }
1371
- },
1372
- move: async (x, y) => this.page.mouse.move(x, y)
1373
1653
  };
1374
- }
1375
- get keyboard() {
1376
- return {
1377
- type: async (text) => this.page.keyboard.type(text),
1378
- press: async (key) => this.page.keyboard.press(key),
1379
- down: async (key) => this.page.keyboard.down(key),
1380
- up: async (key) => this.page.keyboard.up(key)
1654
+ // src/playwright/page.ts
1655
+ var WebPage = class extends Page {
1656
+ constructor(page){
1657
+ super(page, "playwright");
1658
+ }
1381
1659
  };
1382
- }
1383
- async clearInput(element) {
1384
- if (!element) {
1385
- return;
1386
- }
1387
- await this.mouse.click(element.center[0], element.center[1]);
1388
- const isMac = process.platform === "darwin";
1389
- if (isMac) {
1390
- await this.page.keyboard.down("Meta");
1391
- await this.page.keyboard.press("a");
1392
- await this.page.keyboard.up("Meta");
1393
- } else {
1394
- await this.page.keyboard.down("Control");
1395
- await this.page.keyboard.press("a");
1396
- await this.page.keyboard.up("Control");
1397
- }
1398
- await this.keyboard.press("Backspace");
1399
- }
1400
- scrollUntilTop() {
1401
- return this.mouse.wheel(0, -9999999);
1402
- }
1403
- scrollUntilBottom() {
1404
- return this.mouse.wheel(0, 9999999);
1405
- }
1406
- async scrollUpOneScreen() {
1407
- const innerHeight = await this.evaluate(() => window.innerHeight);
1408
- const distance = innerHeight * 0.7;
1409
- await this.mouse.wheel(0, -distance);
1410
- }
1411
- async scrollDownOneScreen() {
1412
- const innerHeight = await this.evaluate(() => window.innerHeight);
1413
- const distance = innerHeight * 0.7;
1414
- await this.mouse.wheel(0, distance);
1415
- }
1416
- };
1417
-
1418
- // src/playwright/page.ts
1419
- var WebPage = class extends Page {
1420
- constructor(page) {
1421
- super(page, "playwright");
1422
- }
1423
- };
1424
- export {
1425
- PageAgent as PlaywrightAgent,
1426
- PlaywrightAiFixture,
1427
- WebPage as PlaywrightWebPage
1428
- };
1660
+ });